採用類似於您的問題另一個例子,
class Animal
{
void set()
{
System.out.println("i am in animal");
}
}
class Dog extends Animal
{
void set()
{
System.out.println("i am in dog");
}
void bark(){
System.out.println("woof woof");
}
public static void main(String args[])
{
Animal instance=new Dog(); //line
instance.set(); //this would call set() in B.
Dog in=new Animal(); //But this line gives error
}
}
繼承遵循is-a
關係,現在我們可以說,狗伸出動物和狗,一個動物。這就說得通了。但動物是 - 狗沒有意義。
當您編寫Animal instance=new Dog();
時,您正在將Dog對象分配給Animal引用,這聽起來很直觀,LHS(Animal實例)也是引用變量,引用變量的作用是決定調用哪些函數對象(那些存在於動物中的對象,例如set()),因爲它是動物類的類型,所以您不能使用實例調用bark()
方法,因爲它是Animal類型的對象,但是您可以調用set()
。現在有兩個版本的set()
其中一個出現在Animal類和Dog類中,現在要調用哪一個取決於RHS(新Dog();),因爲RHS是一個實例並且類型爲Dog()
,Dog中的版本爲set()
叫做。總而言之,請參閱以下代碼並在註釋中輸出: -
Animal a1=new Animal();
a.set();// output- i am in animal
Dog d1=new Dog();
d.set(); //output- i am in dog
d.bark; //valid and output- woof woof
Animal a2=new Dog();
a2.set();//output- i am in dog
a2.bark();// compilation error, you cannot refer to this method since it is not present in Animal class.
Dog d2=new Animal(); // compilation error
靜態方法不是多態的。在你的代碼中,'instance.set();'會在類'A'中調用'set()'。通過實例變量調用靜態方法是不好的做法。你應該調用'A.set()'或'B.set()'。當然,我猜你實際上並不需要靜態方法。 – GriffeyDog
用'動物'和B用'蝙蝠'弱智地代替'A'。這應該讓你更清楚爲什麼當你試圖在'Bats'變量中放入一個'Animal'時,java會感到不安;你可以調用'.fly()'方法(其中'Bat'只有'Animal'沒有),並且所有的地獄都會崩潰。 [我假設你在這裏使用靜態是偶然的,如果不是這裏有更多的錯誤] –
[在java中,我們可以將超類Object傳遞給子類引用嗎?](http://stackoverflow.com/問題/ 24384547/in-java-can-we-pass-superclass-object-to-subclass-reference) – awksp