繼承是物件導向程式常見的一項特性,主要有兩個用意,一個是重用程式碼,一個是做為子類別的手段。
繼承使用 extends
保留字,其虛擬碼如下:
class Child extends Parent {
// Declare some fields.
// Implicitly inherit protected and public fields from Parent.
public Child(param_a, param_b, param_c) {
// Init some fields.
}
// Implicitly inherit protected and public methods from Parent.
// Declare some methods.
}
在類別沒有繼承關係時,只會用到 public
和 private
兩種修飾詞,但類別有繼承關係時,則要視需求用 protected
將屬性暴露給子類別。附帶一提,由於 Groovy 本身的缺陷,目前 private
的屬性也可繼承給子類別,但我們不應濫用這項「特性」(詳見這裡)。
在本文範例中,我們用繼承來重用程式碼:
/* Parent class */
class Person {
protected int _age
protected String _name
public Person(String name, int age) {
setName(name)
setAge(age)
}
public getAge() {
return _age
}
public setAge(int age) {
assert age >= 0
_age = age
}
public getName() {
return _name
}
public setName(String name) {
_name = name
}
}
/* Child class */
class Employee extends Person {
private double _salary
public Employee(String name, int age, double salary) {
super(name, age)
setSalary(salary)
}
public getSalary() {
return _salary
}
public setSalary(double salary) {
assert salary >= 0.0
_salary = salary
}
}
一開始,我們建立 Person
類別,做為父類別,該類別有 name
和 age
兩個 property。
接著,我們建立 Employee
類別,該類別是 Person
類別的子類別,除了原有的 name
和 age
以外,又額外多出 salary
這個 property。
使用這兩個類別的外部程式如下:
def e = new Employee("Michelle", 28, 1000.0)
assert e.name == "Michelle"
assert e.age == 28
assert e.salary == 1000.0
我們建立物件 e
,透過存取該物件的 property 可知 Employee
的確有繼承到 Person
的程式碼。
如同 Java 般,Groovy 採單一繼承,這主要是修正 C++ 的多重繼承所採取的策略。為了補償無法使用多重繼承的缺陷,Groovy 使用 interface 和 trait,我們將於後文介紹。