让我们假设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中是不可能的 - 我只是想了解为什么。
答案 0 :(得分:3)
真正的答案是Java并没有以这种方式定义。在其他语言中,这是可能的。
例如,在Scala中没有静态方法,但您可以定义静态object
,它们是单例并且允许这样做。在像Smalltalk或Ruby这样的动态语言中,类就像对象一样,这也是可能的。
但在Java中,静态方法与全局方法类似。静态方法中没有self
和super
的概念,因为它没有绑定到对象。因此,继承/覆盖并不真正适用。
它展现出如果没有继承的概念,那么谈论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运算符的静态变量的内存分配,因为已经有内存为它们分配,因此它与对象无关,而抽象意味着它需要实现对象,因此两者都是矛盾的