2012-12-02 100 views
3

我想要圍繞Java中的繼承進行包裝。到目前爲止,我明白如果我以下面的方式聲明一個對象:Superclass object = new Subclass()創建的子對象僅限於父對象的方法。如果我想訪問孩子的其他方法,我將不得不投給孩子。 但爲什麼在子類中方法仍然被覆蓋。Java對於初學者的繼承

這裏是我的榜樣

public class Parent { 

    public Parent() {  

    } 

    public void whoAmI(){  
     System.out.println("I'm a parent"); 
    } 

} 
public class Child extends Parent { 

public Child() {   

} 

public void whoAmI(){  
    System.out.println("I'm a child"); 
} 

public void childMethode() { 
    System.out.println("Foo"); 

} 
} 

public class Test { 

/** 
* @param args 
*/ 
public static void main(String[] args) { 
    // TODO Auto-generated method stub 

    List<Parent> list = new ArrayList<>();  

    Child c = new Child(); 
    Parent p = new Parent(); 
    Parent pc = new Child(); 

    c.whoAmI(); 
    p.whoAmI(); 
    pc.whoAmI(); 

    // Access child methodess 
    ((Child) pc).childMethode(); 

    list.add(c);  
    list.add(p); 
    list.add(pc); 

    System.out.println(list.size()); 

} 

} 

pc.whoAmI()版畫 「我是一個孩子。」爲什麼不打印「我是父母」?

+0

[本文](http://javarevisited.blogspot.com/2011/08/what-is-polymorphism-in-java-example.html)可能是有用的 – Pshemo

+0

從邏輯上講它是有道理的調用實際的對象方法。請參閱我的示例 –

回答

1

爲什麼很難回答這個問題,這是很久以前Java團隊做出的一個設計決定。

他們決定所有的方法都是virtual,除非他們明確標記爲靜態。在某些語言中,這是相反的方法(默認情況下方法是靜態的,除非聲明爲虛方法),它並沒有真正的區別。

重要的是要了解how static and virtual methods work。 (或者因爲它們有時被稱爲Java:實例和類/靜態方法。)

1

您可以想象繼承創建名爲super的隱藏成員。

Java中的每個對象實例都有自己的常量類型。在鑄造時你不會改變它。在投射時,您只需對Java說,您確定此對象屬於子類型。

覆蓋的方法仍然覆蓋,這是Java的意識形態。如果你瞭解C++,你可以說Java中的所有函數都是虛擬的。

4

爲避免混淆,請務必理解您創建的子類對象始終包含所有方法。 Downcasting是一個無操作;你只要把同一個對象當作子類型的一個實例。

推論:決不能通過向下轉換來改變對象的行爲。由此直接得出結論,你總是訪問相同的覆蓋方法,而從來沒有超類方法。

這種行爲可以讓你用相同的聲明超類型替換不同的行爲。它被稱爲多態性並且是Java編程和一般OOP的主力。沒有它,首先就沒有階級層次結構。至少,它會很多,不太有用。

+0

感謝您的解釋。所以通過聲明Parent pc = new Child();電腦將仍然有其他孩子的方法,但我無法訪問它,對吧? whoAmI方法總是被忽略,因爲這就是java創建者想象的那樣。 – user1870482

+0

這比Java創作者想象的要多一點,因爲它是所有OOP的基石,一直回到Smalltalk。是的,所有方法都在那裏,只有編譯器會拒絕編譯調用未在變量類型上聲明的方法的代碼。 –

0
class Person{ 

    public void run(){ 
     //running 

    } 

} 

class OneLeggedPerson extends Person{ 
    @Override 
    public void run(){ 
     //cant run have only one leg 
    } 
} 


Person p = new OneLeggedPerson(); 
p.run(); //cannot as it is actually a one legged person 


Hope that makes sense now.. 
0

讓我們假設你是蘋果公司,而你正在銷售iPod。

在一個工廠與另一個工廠之間或者iPod的第一個版本與上一個版本之間建立iPod的方式可能存在細微的差異,因爲該過程已經改變。

你,蘋果,知道你建設一個什麼樣的iPod:

IPodWithFirstWayOfBuildingIt ipod = new IPodWithFirstWayOfBuildingIt(); 

IPodWithSecondWayOfBuildingIt ipod = new IPodWithSecondWayOfBuildingIt(); 

但最終客戶(即,代碼的其餘部分)並沒有提到iPod的構建方式。對他而言最重要的是,iPod的工作原理和行爲就像iPod(它在廣告,最終用戶手冊或Ipod類的javadoc中的顯示方式)。他並沒有要求商店「給我一個建造iPod的第一種方式」。但事實是,他以第一種方式建造iPod,或者以第二種方式構建iPod。而且他稱之爲「iPod」的事實並不會改變iPod的內置方式,因此:

IPod iPod = new IPodWithFirstWayOfBuildingIt(); 

就是這樣說的。我用第一種方式構建iPod,但我會像使用其他iPod一樣使用它,而不關心它是如何構建的。