開源技術教學網 [Groovy] 程式設計教學:介面 (Interface) 和特質 (Trait)

最後修改日期為 APR 11, 2019

前言

介面 (interface) 和特質 (trait) 都是受限制的多重繼承,是 Groovy 中為了補償單一繼承的不足所實作的語法特性。兩者的差別在於前者沒有實作而後者有。

介面 (Interface)

介面 (interface) 是只有方法 (method) 宣告但沒有 method 實作的類別,主要目的是在滿足子類別 (subtying) 的前提下避開多重繼承的問題。介面的虛擬碼如下:

interface Interface {
    // Declare some methods with no implementations.
}

class Child extends Parent implements Interface {
    // Implicitly inherit some fields from Parents.
    // Declare some fields.
    
    public Child(param_a, param_b, param_c) {
        // Init fields.
    }
    
    // Implicitly inherit some methods from Parent.
    
    // Child has to implement the methods in Interface.
    
    // Other methods in Child.
}

extendsimplements 都是繼承,但兩者的行為大不相同。extends 會繼承父類別 (parent class) 實際的屬性和行為,但只能繼承單一的父類別;implements 僅繼承介面的 methods 宣告,要自行實作介面的內容。和 extends 不同的點在於 implements 可同時繼承多個介面。在同一個類別中,可以同時使用兩種繼承的方式,因為 implements 本來就是一種受限制的多重繼承。

以下例子實做三個滿足同一個介面的類別:

interface Speak {
    public String speak()
}

class Dog implements Speak {
    public String speak() {
        return "Wow wow"
    }
}

class Duck implements Speak {
    public String speak() {
        return "Pack pack"
    }
}

class Tiger implements Speak {
    public String speak() {
        return "Halum halum"
    }
}

def animals = [new Dog(), new Duck(), new Tiger()]

animals.each { println it.speak() }

在本例中,由於三個物件繼承自同一個介面,可視為相同型別,故可以放在同一個陣列中。

Groovy 同時具有 interfacetrait 兩種相似的語法機制,算是有點冗餘的設計。如果沒有要實作程式碼的話,最好還是使用 interface,比較不會搞混。

特質 (Trait)

特質 (trait) 和介面 (interface) 算是有點重疊的特性,兩者都是做為受限制的多重繼承的語法特性,主要的差別在於 traits 可以加入實作。參考下例:

trait Greetable {
    abstract String getName()
    
    String greeting() {
        "Hello ${name}"
    }
}

class Person implements Greetable {
    private String _name
    
    public Person(String name) {
        _name = name
    }
    
    public String getName() {
        return _name
    }
}

def p = new Person("Michelle")
assert p.greeting() == "Hello Michelle"

由於 trait 可以加入自己的屬性和方法,已經相當接近多重繼承,在撰寫 trait 要妥善安排程式碼的架構,以免寫出難以維護的程式碼。

分享本文
Facebook Twitter LinkedIn LINE Skype EverNote GMail Yahoo Yahoo
追蹤本站
Facebook Facebook Twitter