2

让我们假设 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

在我看来,从使用 interface 的任何人的角度来看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方法,但同时,该方法可能不依赖于SQLMapper对象的内部状态,并且可能希望能够将泛型Entry转换为aSQLEntry无需经过可能包括数据库连接字符串等的实例化过程。

这就是我所面临的情况,以及为什么我想看看是否有人知道为什么用相同的方法无法实现这一点——例如,不必求助于public static SQLEntry convertStatic(Entry e)被覆盖的方法将其实现委托给的 a。

不过,我再次明白,由于编译器的工作方式,这在 Java 中是不可能的——我只是想理解为什么会这样

4

3 回答 3

3

真正的答案是 Java 根本就不是这样定义的。在其他语言中,这是可能的。

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

但是在 Java 中,静态方法类似于全局方法。没有 , 的概念self,也没有super在静态方法中,因为它没有绑定到对象。结果继承/覆盖并不真正适用。

它表明,如果没有继承的概念,那么谈论 . 也是没有意义的abstract

于 2012-11-15T15:27:53.220 回答
1

抽象方法应该被子类方法覆盖(定义)。您不能覆盖静态方法,因为它们与实例无关,而是与它们定义的特定类有关。

例如,使用非静态方法:

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

静态是这样使用的:

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
    }

}
于 2012-11-15T15:20:18.077 回答
1
public class Baz implements Foo {
    public Object bar() {
        //My implementation
    }
 public static  Object bar() {
        //My implementation
    }
}

因为,您的方法签名是相同的, bar () 没有重载。由于您在抽象类中声明了非静态 bar(),因此您被迫在此类中实现该方法。

于 2012-11-15T15:20:52.813 回答