public class A {
protected int x = 10;
A() {
System.out.println("Constructor A" ) ;
}
public void test() {
System.out.println(" A " );
}
public void Aex() {
System.out.println(" Aex " ) ;
}
public void testg() {
System.out.println("Hello");
}
}
public class B extends A {
B() {
System.out.println("Constructor B" ) ;
}
B(int num){
this.x = num ;
//System.out.println(this.x);
}
public void test() {
System.out.println(" B " );
}
public int getx() {
return this.x;
}
}
public class C {
public static void main( String [] args ) {
A a = new B();
//a.test();
a.Aex();
//a.testg();
B b = new B(5);
a = b;
a.test();
System.out.println( a.getx() ) ;
}
}
类B
继承自类A
,并且都有一个名为test()
的方法。我可以创建一个派生类对象的基类引用,所以我创建了一个引用A a = new B();
。当我致电a.test()
时,test()
的{{1}}方法被调用,我理解,这有助于我防止在我的代码中使用条件语句。但假设B
有另一个名为B
的方法,我想调用该方法,我不能用基类引用来调用它,因为基类没有名为void void getx()
的方法。那么多态如何在这种情况下有用呢?调用getx()
的唯一方法是创建派生类的引用并调用getx
。
答案 0 :(得分:4)
而不是类A
和B
让我们使用类Animal
和Bird
作为示例。
假设您的Animal
班级有方法eat
和sleep
(所有动物都做的事情),而您的班级班级也有fly
方法(只有鸟类可以做) )。如果你有一个Animal
对象的引用,那么能够在这个变量上调用fly
方法是没有意义的,因为你不知道它是什么类型的动物,它可以是Slug
或Wombat
。
答案 1 :(得分:3)
重点是不要意识到getx()
方法的存在,也不要通过引用A
来调用它。
如果您真的需要调用它,可以将其转换为所需的类型:
B b = (B) a;
b.getx();
但在这种情况下,您应该重新考虑您的设计并更改设计以避免投射,或者首先使用B
的引用。
想象一下,你邀请朋友去吃饭。在这个抽象层次上,你只能告诉他们来:
for (Friend friend : friends) {
friend.comeToDinner();
}
你会不告诉他们离开他们的家,坐进车里,开车,停在红色交通灯上,继续开绿灯......停在你家,退出车。你告诉他们要做什么,而不是如何这样做(有些是开车来的,有些是乘公共交通工具等)。
每个Friend
实例都将使用自己的状态和实现来执行comeToDinner
方法。
答案 2 :(得分:1)
您已经说明了它是如何有用的,您可以在对基类的引用上调用方法,这可能实际上具有继承类的值,这使您的代码可以扩展。
我想调用那个方法,我不能用基类调用它 引用,因为基类没有名为void getx()的方法。
这是一个矛盾,你为什么要调用一个不存在的类的方法?
codebox在回答为什么调用未实现的方法没有意义时有一个很好的例子。
答案 3 :(得分:1)
你所谓的缺陷实际上是多态性的关键优点:你可以在不知道任何关于它或它自己的方法的情况下达到子类的重写方法。那就是短语"对接口的编程"是为了捕获。
答案 4 :(得分:1)
似乎你缺少一个重要的OO魔法:方法getx()可以在A中声明为 abstract ,你不必在那里实现它。这将允许您在基类(它本身将变为抽象)上调用它,同时您不需要在那里实现该方法。