階層的建立
階層的建立
這裡有一些方式可以定義適當的建構子函數,以實現 Employee 的階層結構。該如何選擇定義這些的方式,主要取決於你希望你的應用程式能做什麼。
本節展示如何使用非常簡單的(相對來說也比較沒有彈性)定義,以示範繼承是如何運作的。在這些定義中,當你建立物件的時候,你不能指定任何的屬性值。這些新建立的物件會簡單的取得預設值,稍後你就可以修改這些值。圖 8.2 以這些簡單的定義解說了階層結構。
在實際的應用程式中,你可能會定義允許你在建立物件的時候提供屬性值的建構子(參閱 更靈活的建構子 以取得資訊)。現在,這些簡單的定義示範繼承是如何發生的。
圖 8.2: Employee 物件的定義
下面 Java 和 JavaScript 的 Employee
定義很類似。唯一的不同點是,在 Java 中,你需要為每一個屬性指定類型,但 JavaScript 不需要。而且你需要為 Java 類別建立明確的建構子方法。
JavaScript | Java |
---|---|
function Employee () { this.name = ""; this.dept = "general"; } |
public class Employee { public String name; public String dept; public Employee () { this.name = ""; this.dept = "general"; } } |
Manager
和 WorkerBee
的定義顯現出在如何指定高於繼承鏈的下一個物件時的不同點。在 JavaScript 中,你把原型實體作為建構子函數的 prototype
屬性的值加了上去。在你定義了建構子以後的任何時間點上,你都可以這麼做。在 Java 中,你只能在類別定義的內部指定親類別。你不能在類別定義的外部改變親類別。
JavaScript | Java |
---|---|
function Manager () { this.reports = []; } Manager.prototype = new Employee; function WorkerBee () { this.projects = []; } WorkerBee.prototype = new Employee; |
public class Manager extends Employee { public Employee[] reports; public Manager () { this.reports = new Employee[0]; } } public class WorkerBee extends Employee { public String[] projects; public WorkerBee () { this.projects = new String[0]; } } |
Engineer
和 SalesPerson
的定義所建立的物件是傳承自 WorkerBee
以及 Employee
。這些類型的物件具有在鏈上比他高層的所有物件的屬性。此外,定義中還使用指定給這些物件的新值來覆蓋被繼承的 dept
屬性的值。
JavaScript | Java |
---|---|
function SalesPerson () { this.dept = "sales"; this.quota = 100; } SalesPerson.prototype = new WorkerBee; function Engineer () { this.dept = "engineering"; this.machine = ""; } Engineer.prototype = new WorkerBee; |
public class SalesPerson extends WorkerBee { public double quota; public SalesPerson () { this.dept = "sales"; this.quota = 100.0; } } public class Engineer extends WorkerBee { public String machine; public Engineer () { this.dept = "engineering"; this.machine = ""; } } |
使用這些定義,你可以建立這些物件的實體,同時實體也為他們的屬性取得預設值。圖 8.3 解說使用這些 JavaScript 定義來建立新的物件,並顯示新物件的屬性值。
附註: 術語實體(instance)在以類別為基礎的語言中有特定的技術含義。在這些語言中,實體就是類別的獨立成員,而且在根本上就有別於類別。在 JavaScript 中,〝實體〞並沒有這些技術含義,因為 JavaScript 並沒有類別和實體的分別。然而,在談到 JavaScript 的時候,〝實體〞也可以在通俗上用來指,使用實際的建構子函數建立的物件。因此,在這些範例中,你也可以通俗的說 jane
是 Engineer
的實體。類似的,儘管術語 親(parent)、子(child)、祖先(ancestor)、子孫(descendant)在 JavaScript 中並沒有正式的含義;你也可以隨俗的使用這些術語,來談論在原型鏈中較高或較低的某個物件。
圖 8.3: 使用簡單的定義來建立物件