2014-02-20 54 views
0

所以這是非常基本的,但我無法得到它。讓我們假設我們有2類A,B(繼承A):Java覆蓋參考

class A { 
     public void m() {System.out.println("AAA");} 
    } 
    class B extends A { 
     public void m() {System.out.println("BBB"); } 
    } 

我們的主類:

class Test{ 
    public static void main(String [] args){ 
     A a=new A(); B b=new B(); A x; 
     x=a; x.m(); // "AAA" 
     x=b; x.m(); // "BBB" 

     a=b; a.m(); // "BBB" 
     b=a; b.m(); // ERROR 
    }} 

我的理解是 'X' 是A型的空引用,因爲沒有任何對象被創建。當我鍵入x = a;對null的引用現在指向A的實例。如果我調用x.m(),它會打印出與AAA =相同的x = b; x.n(); 「BBB」;

但是如果我創建了一個實例A,其中'a'是引用並且說b = a;它說錯誤。找到一個必需的B.

那麼我認爲'b'的引用被引用'a'覆蓋,如果我現在調用b.m();它給了我「AAA」,因爲它現在指向A的實例。雖然a = b;用a.m()打印「BBB」

爲什麼?

+0

實例的超類的不一定是子類的實例... –

回答

4

首先我只是加入一些字符類的名字:

class Animal { 
     public void m() {System.out.println("AAA");} 
    } 
    class Bee extends Animal { 
     public void m() {System.out.println("BBB"); } 
    } 

class Test{ 
public static void main(String [] args){ 
    Animal a=new Animal(); 
    Bee b=new Bee(); 
    Animal x; 

    x=a; x.m(); // "AAA" a is an animal 
    x=b; x.m(); // "BBB" b is a Bee, so it's an Animal 

    a=b; a.m(); // "BBB" A Bee is an Animal 
    b=a; b.m(); // ERROR An Animal is a Bee? What if it's a Cat? 
}} 

在情況尚不清楚,讓我們創建類:

class Cat extends Animal{ 
    public void m() {System.out.println("CAT"); } 
    public void foo() {System.out.println("FOO"); } 
}; 

你可以在前面的代碼Animal a=new Animal();改變通過Animal a= new Cat();,然後你會看到b=a是不正確的,因爲蜜蜂不是貓。

更新:我添加了兩個方法到類貓。讓我們看看它是如何工作的:

// This is the obvious part: 
Cat c= new Cat(); 
c.m(); // "CAT" 
c.foo(); // "FOO" 

// Not so obvious 
Animal a2= new Cat(); // a Cat is an animal 
a2.m(); // "CAT" 
a2.foo(); //Won't compile: ERROR 

這裏會發生什麼?貓是一種動物,這確保它具有方法m。該方法的行爲由實例本身定義。 a2是一個指向Cat實例的變量,但我們只能調用Animal定義的方法,因爲a2也可以是任何其他動物,我們不知道它可能具有哪些方法。是的,這種情況下,我們知道這是一隻貓,但讓我們說我們有這個方法:

public Animal createAnAnimal() { 
    if (Random.nextBoolean()) { 
     return new Cat(); 
    } else { 
     return new Bee(); 
    } 
} 

無論如何,你應該閱讀有關繼承和接口,其中鐵道部ecomplexity添加到這個東西。

+0

確定我以爲我聽錯,但我不知道 - 如果我創建一個動物A2 =新蜂();並說a2.m();現在究竟發生了什麼? (A2是動物類型,並指出蜂他是否覆蓋AAA與BBB?) – dustinboettcher

+0

@Duboe我想你應該只是你的榜樣測試,但無論如何,我已經添加了一些解釋 –

+0

你是最棒的 - 我失蹤了鏈接,但它現在更清晰 - 謝謝:) – dustinboettcher

0

假設你有另一個類C:

class C extends A { 
    public void m() {System.out.println("CCC"); } 
} 

那麼你的代碼可以修改:

A c = new C(); 
B b = c; 

這顯然是不正確的,因此錯誤。

2

我認爲你的問題是,你有一個錯誤的觀點。

您認爲,如果您設置爲a = b,那麼a將是B類型!但它是而不是a仍然是A類型,並且對類B的實例有參考。

所以,這就是爲什麼你不能將類A的值設置爲B類型的變量!

A a = new A(); 
B b = new B(); 
A x; 

x = a; // x is of type A and has now a reference to an instance of type A 
x = b; // x is of type A and has now a reference to an instance of type B 

a = b; // a is of type A and has now a reference to an instance of type B 
b = a; // b is of type B and you can't set a reference to a variable of type A 
+0

Thx這是相當有用的:) – dustinboettcher