当我无法使用基类引用调用派生类方法时,动态多态如何有用

时间:2015-08-28 14:04:46

标签: java inheritance polymorphism

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

5 个答案:

答案 0 :(得分:4)

而不是类AB让我们使用类AnimalBird作为示例。

假设您的Animal班级有方法eatsleep(所有动物都做的事情),而您的班级班级也有fly方法(只有鸟类可以做) )。如果你有一个Animal对象的引用,那么能够在这个变量上调用fly方法是没有意义的,因为你不知道它是什么类型的动物,它可以是SlugWombat

答案 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 ,你不必在那里实现它。这将允许您在基类(它本身将变为抽象)上调用它,同时您不需要在那里实现该方法。