为什么我们不能在子类B中声明一个实例方法,它与父类A中的静态方法共享相同的签名?
如果我尝试这样做,会抛出编译时错误。
我的问题是,由于父类的静态方法仅限于父类,为什么子类的实例方法不能编译。
让我们看看代码:
`
public class A{
static void testStatic(){}
}
public class B extends A{
void testStatic (){}
}
public class Test{
public static void main (String[] args){
A a = new B()
a.testStatic();
}
`
在上面的代码中,由于A没有该名称的实例方法,并且由于Java允许对象访问静态方法,因此指向'B'的类型'A'的对象a可以调用静态方法它(A类)。但编译器抛出错误“实例方法不能覆盖静态方法”为什么?
注意:我可以理解一个类是否允许两个方法使用相同的方法名,即使一个是实例而另一个是静态的。但我不明白为什么它不允许子类具有相同名称的实例。特别是考虑到静态方法不能被覆盖的事实。然而,Java允许子类与父类静态方法具有相同的名称,这种方法称为信息隐藏,但不会覆盖。
答案 0 :(得分:3)
编译器抛出错误,因为这些是语言的规则。来自Java Language Specification §8.4.8.2:
如果C类声明或继承
static
方法m
,则m
被称为隐藏任何方法m'
,其中m
的签名是m'
签名的子签名(§8.4.2),在C的超类和超接口中,否则C中的代码可以访问。如果静态方法隐藏了实例方法,则为编译时错误。
(重点在原文中)。语言是密集的(如JLS中的大多数地方),但它与您描述的情况相匹配。 JLS没有提供我在一读时能找到的这条规则的理由。但是对于如何试图使这个规则变得不必要的一点思考可以说明它为什么存在。
答案 1 :(得分:1)
Java中的非法。在实例上对静态方法的调用也是允许的,因此在某些情况下无法区分调用哪种方法:
A a = new A ();
B b = new B ();
A.testStatic (); // ok
B.testStatic (); // ok
a.testStatic (); // ok calling static
b.testStatic (); // undefined. What to call? Based on what?
最后通话是不允许的原因。
答案 2 :(得分:1)
对static
方法的调用在编译时自行解决。所以,他们不能被覆盖。通过使用与静态方法相同的签名定义另一个方法,编译器会抱怨。
答案 3 :(得分:1)
静态方法与类绑定,而实例方法与对象绑定。 静态属于类区域,实例属于堆区域。
答案 4 :(得分:1)
I am not hundred percent sure but I guess answer as below.
静态方法意味着它可以在没有定义它的类的实例的情况下使用。静态方法也只能访问类的静态变量。现在,如果我们覆盖非静态方法并使用超类的引用创建子类的实例,编译器将混淆静态方法的上述两个基本功能。请讨论是否有任何错误。
答案 5 :(得分:0)
4行显示错误。这样做 公共等级B扩展A