Java中的继承简单说明

时间:2012-07-04 10:44:23

标签: java inheritance

所以,我有这个:

public class A {

    public int a = 0;
    public void m(){
        System.out.println("A"+a);
    }
}

而且:

public class B extends A {

    public int a = 5 ;
    public void m (){
        System.out.println("B"+a);
    }
    public static void main(String[] args) {
        A oa = new A();
        B ob = new B();
        A oab = ob;
        oa.m();
        ob.m();
        oab.m();

        System.out.println("AA"+oa.a);
        System.out.println("BB"+ob.a);
        System.out.println("AB"+oab.a);
    }
}

输出:

A0
B5
B5
AA0
BB5
AB0

我不明白为什么 oab.m(); 输出 B5 而不是 A0 。谁可以给我解释一下这个?

7 个答案:

答案 0 :(得分:9)

这就是多态性的全部意义。 oab的具体类型为B(因为对象是使用new B()创建的)。所以调用方法B.m()

查看http://en.wikipedia.org/wiki/Polymorphism_%28computer_science%29中的Animal示例,了解它为什么有用。当你有一只动物,而这只动物是一只猫时,你会期待它说“喵!”当你说话时。

答案 1 :(得分:1)

B ob = new B();
A oab = ob;

类似于

A oab=new B();

I don't understand why oab.m(); output is B5 instead of A0

因为你创建B的对象并将其引用到A所以m()被继承,这就是为什么B's versionm()调用的原因。

答案 2 :(得分:0)

A oa = new A();
B ob = new B();
A oab = ob;

从上面的代码中,ob是B类的一个实例。它可以存储在A类的变量中,因为A扩展为B.但是由于存储的Object实例是B,因此它不知道A的m()功能。 因此,输出为B5

答案 3 :(得分:0)

在继承中,实际的方法调用取决于实际对象的类型,而不取决于引用的类型。

 B ob = new B();
 A oab = ob;

此处oabA类型的引用变量,但它指向B类型的对象,即ob,因此在运行时oab.m()将调用覆盖类m()

中的B方法

答案 4 :(得分:0)

在Java中有类似后期绑定(polymorphism)的东西。这意味着方法代码在编译时(早期绑定)时没有链接,而是在运行时。在调用oab.m();时,JVM正在检查aob引用(在您的情况下为B)中的对象的实际类型(类),并基于该信息调用该类中的方法代码。这就是oab.m();返回B5的原因。

您还需要知道后期绑定仅适用于方法,而不适用于字段。对于字段,值将由引用类型确定,因此oab.a将返回0而不是5

答案 5 :(得分:0)

想象一下,你有以下几点:

public class C extends A {

public int a = 7 ;
public void m (){
    System.out.println("C"+a);
}

现在,如果你在Main方法中有这个...

C oc = new C();
A oac = oc;
oac.m();

...你希望最后一次调用输出特定于C类的东西。

关键是 B是A C是A ,但每个都有A包含的更多特定版本的值,以及何时你要求提供这些数据,应该返回它们的具体版本。

现在你可以这样做:

// Get an instance of B or C, but you don't
// care which - could be either:
A someVersionOfA = getAnInstanceOfA(); 

// This works no matter if you've got an instance
// of B or C, but the result should vary accordingly:
someVersionOfA.m();

正如其他人提到的那样,将 A 视为“动物”,将 B 视为“cat”,将 C 视为“狗”。如果 m()表示“发出一些噪音”,那么调用m()会导致“Meow”或“Woof!”取决于实例 getAnInstanceOfA()返回。

答案 6 :(得分:0)

您刚刚将B的内部地址复制为A,然后将其替换。

B继承自A,所以没有编译问题。

最后,对A的引用被破坏,现在它是对B

的引用的副本