我们今天在comp sci讲座中讨论了继承问题,并讨论了从其他类中访问方法。我的一个同学询问一个子类如何访问最高的父母班级方法,我的教授也对它很好奇并建议类似:
super.super.toString();
可以工作,但事实并非如此。我很好奇,我试图自己解决这个问题并想出了这个:
public class A {
public static void main(String[] args){
B b = new B();
C c = new C();
System.out.println(b.toString());
System.out.println(c.toString());
}
public String toString(){
return "Class A";
}
}
class B extends A {
public String toString(){
return "Class B";
}
}
class C extends B {
public String toString(){
return A.class.toString();
}
}
现在,在测试各种各样的东西时,我发现了这一点:(这都将在C级完成)
super.toString();
似乎做同样的事情:
B.class.toString();
我的问题是两者之间有什么区别,还是它们完全相同?同样在我上面的代码中,是从子子类调用方法的正确方法吗?
答案 0 :(得分:3)
不,B.class.toString()
会在toString()
课程上调用Class
方法。这甚至不是稍微与调用super.toString()
相同的东西。
无法绕过A
从toString()
调用C
A
的{{1}}实施方式。这基本上会破坏封装。
答案 1 :(得分:3)
super.toString()
拨打C
,则会在toString()
上调用B
,这将返回“B级”。
当您致电A.class.toString()
或B.class.toString()
时,您根本没有调用任何超类方法,而是在toString
上致电Class
。
答案 2 :(得分:3)
class Parent{
public void foo(){
}
}
class Child extends Parent{
@Override
public void foo(){
super.foo(); //will call the parent class foo method
}
}
class ChildOfChild extends Child{
public void bar(){
super.foo(); //this actually is the method of the Parent that is actually called at the end as Child calls super.foo();
}
}
super.toString();
和B.class.toString()
完全不同。在稍后您调用类文字的toString()
方法。
如示例所示,如果子子类调用层次结构中定义的方法,则它取决于实现将调用哪个方法。如果直接父覆盖该方法并且未调用super.method()
,则它(父母的方法)无法被调用。这就是继承的工作方式。
如果直接父级没有覆盖该方法,并且您从子子类调用方法,那么将调用直接父级的父方法。
答案 3 :(得分:1)
如果您尝试访问toString()中的任何状态,并且您没有按照您的想法进行操作,您将很快看到。
SomeClass.class是一个特殊的构造。见http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.8.2 对于确切的定义。
您可能不会使用super.super,因为Java实际上是为了强制您正确使用对象和面向对象的模式。不应该允许您跳过父类的实现,因此不允许这样做。与其他不那么严格的语言相比,这实际上是Java的抱怨之一,但它确实迫使你真正考虑你的类层次结构和你正在做的事情。