有关继承和抽象类的说明

时间:2015-07-18 09:50:45

标签: java

abstract class A1
{
    public abstract void m1();
    public void m2() 
    {
        System.out.println("Green");    
    }

}

abstract class A2 extends A1
{
    public void m1() 
    {
        System.out.println("Cyan"); 
    }
    public void m2() 
    {
        System.out.println("Blue"); 
    }
    public abstract void m3();
}

public class A3 extends A2{
    public void m1() 
    {
        System.out.println("Yellow");   
    }
    public void m2() 
    {
        System.out.println("Pink"); 
    }
    public void m3() 
    {
        System.out.println("Red");  
    }
    public static void main(String[] args)
    {
        System.out.println(" inside main ");
        A2 tp = new A3();
        tp.m1();
        tp.m2();
        tp.m3();
    }

}

输出上述代码:

inside main 
Yellow
Pink
Red

有人可以解释为什么它会打印黄色,粉红色和红色而不是青色绿色红色? 为什么代码不能用于代码执行的抽象类?

4 个答案:

答案 0 :(得分:1)

这是因为你没有扩展方法而是Override方法,如果你想要调用parent-methods,你需要在{{1}方法中自己调用它们}}

答案 1 :(得分:1)

因为与C ++不同,在Java中,所有实例方法都是虚拟的。

答案 2 :(得分:0)

这就是我解释它的方式。

编译器将首先检查方法调用是否为 legal 。为此,它检查调用该方法的引用变量的声明类型 (无论它所指的实际对象的类型如何)。 如果方法是在引用变量的声明类型(包括继承方法)中定义的,则方法调用将是合法的。 在您的示例中,引用变量tp的声明类型为A2 。方法m1,m2和m3在A2中定义。所以 tp.m1(); tp.m2() tp.m3(); 是编译器的合法方法调用,无论 tp实际上是指A3对象

然后在运行时, JVM将检查引用变量引用的实际对象并应用实际对象中的方法实现(如果有)。如果jvm在实际对象中没有找到该方法的任何实现,它将应用在引用变量的声明类型中找到的方法实现(包括继承的方法)。 在你的例子中,tp(甚至声明为A2类型),实际上指的是A3类型的对象(由于A3扩展了A2,这是合法的)。因此,当调用方法m1,m2和时,jvm将执行类A3中的实现。立方米。 如果你没有在A3类中重新定义(覆盖)方法m2,那么输出将是:

inside main
Yellow
Blue
Red

答案 3 :(得分:0)

这就是Override的含义。 A2中的A3 OVERRIDES m1方法中的m1方法。 如果从A3中删除m1方法,您将在输出中获得Cayan,而不是黄色。

同样,如果你从A3和A2中删除m2,你将在输出中获得绿色,而不是粉红色。