【在主畫面加入捷徑】
       
【選擇語系】
繁中 简中

[Groovy] 程式設計教學:介面 (Interface) 和特質 (Trait)

Facebook Twitter LinkedIn LINE Skype EverNote GMail Yahoo Email
【贊助商連結】

    介面 (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("Michael")
    assert p.greeting() == "Hello Michael"

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

    【贊助商連結】
    標籤: GROOVY, JAVA
    【贊助商連結】
    【分類瀏覽】