为什么我不能在我的实现中创建一个静态的抽象方法?

时间:2012-11-15 15:18:36

标签: java compiler-construction

让我们假设Java中的以下场景

public interface Foo {
    Object bar();
}

public class Baz implements Foo {
    public Object bar() {
        //My implementation
    }
}

为什么我不能使Baz.bar()静态?

这样做会导致编译器错误This static method cannot hide the instance method from Foo@Override添加Baz.bar()注释会将编译器错误更改为The method bar() of type Baz must override or implement a supertype method

在我看来,从使用接口Foo的任何人的角度来看,实现类Baz仍然可以满足接口要求,同时使任何具有静态实现的方法可用于任何人显式使用Baz类而不实例化。

为什么编译器不允许这种情况?

修改

也许我不够清楚,但我实际上问的是 为什么 这是不允许的,因为从我的观点来看,我是不降低接口定义方法的可见性。

是的,我知道我在标题中使用了抽象这个词,而不是在问题中,但这是因为abstract关键字隐含在界面中。

编辑2

我将添加一个更贴近现实的例子,以明确我为什么要问这个:

public interface DatabaseMapper<T extends DatabaseType> {
    Entry<T> convert(Entry);
}

public interface SQL extends DatabaseType {}

public class SQLEntry implements Entry<SQL> {}

public class SQLMapper implements DatabaseMapper<SQL> {
    public SQLEntry convert(Entry e) {
        //Convert some generic entry to the SQLEntry type
    }
}

在这种情况下,我想强制所有Mapper实现实现convert方法,但同时,此方法可能不会以任何方式依赖于{{{}的内部状态1}} object,并且可能希望能够将通用SQLMapper转换为Entry而无需经过可能包含数据库连接字符串之类的实例化进程。

这是我面临的情景,为什么我想看看是否有人知道为什么用同样的方法无法实现这一点 - 例如不必求助于被覆盖的方法将其实现委托给的SQLEntry

我再次理解,由于编译器的工作原理,这在Java中是不可能的 - 我只是想了解为什么

4 个答案:

答案 0 :(得分:3)

真正的答案是Java并没有以这种方式定义。在其他语言中,这是可能的。

例如,在Scala中没有静态方法,但您可以定义静态object,它们是单例并且允许这样做。在像Smalltalk或Ruby这样的动态语言中,类就像对象一样,这也是可能的。

但在Java中,静态方法与全局方法类似。静态方法中没有selfsuper的概念,因为它没有绑定到对象。因此,继承/覆盖并不真正适用。

它展现出如果没有继承的概念,那么谈论abstract也是没有意义的。

答案 1 :(得分:1)

抽象方法应该由子类方法覆盖(定义)。您不能覆盖静态方法,因为它们不属于实例,而是属于它们所定义的特定类。

例如,使用非静态方法:

Foo b = new Baz();
Object result = b.bar();

static就是这样使用的:

Object result = Baz.bar2();

如果你真的想要bar是静态的,并且在实例级别也要覆盖它:

public interface Foo {
    Object bar();
}

public class Baz implements Foo {
    @Override
    public Object bar() {
          return Baz.bar2();
    }
    public static Object bar2() {
     //your implementation
    }

}

答案 2 :(得分:1)

public class Baz implements Foo {
    public Object bar() {
        //My implementation
    }
 public static  Object bar() {
        //My implementation
    }
}

因为,您的方法签名相同,bar()不会重载。因为你在抽象类中声明了一个非静态bar(),所以你不得不在这个类中实现该方法。

答案 3 :(得分:1)

int a = 2表示在后台内存中为&#34; a&#34;分配并作为int类型并由2初始化 每当我需要一个值时,我只需使用&#34; a&#34;。类似地,静态变量和方法在加载类时被初始化,这样在任何类中我都不需要提到使用new运算符的静态变量的内存分配,因为已经有内存为它们分配,因此它与对象无关,而抽象意味着它需要实现对象,因此两者都是矛盾的