iT邦幫忙

2017 iT 邦幫忙鐵人賽
DAY 7
0

有沒有看到那到光

基本上前面介紹的就是Julia的type system與multiple dispatch,這兩個可謂Julia設計最優雅的地方,當然我還有很多東西沒有介紹到,可能就要請大家去看官方文件了。

這個標題是Julia的物件導向,但是從前面一點都沒有看到傳統物件導向的影子阿!
別急~~~~
雖然Julia沒有傳統物件導向的樣子,但是仍有物件導向的精神:可讀性與可修改性
基本上可讀性在Julia這個語言當中遍地都是,應該不用我解釋。可修改性也如同前面提到的,想要增加型別的行為只要外加上去就有了,型別也可以自由的重新定義或是成為子類別。

所以基本上Julia是可以適用物件導向的,我們來看看怎麼做吧!

如何初始化

前面在提型別的時候都沒有提到constructor的部份,constructor就是一個型別被實體化的時候會先被執行的函式,他可以幫助型別做初始化的動作。

Inner Constructor

inner constructor,顧名思義就是定義在型別中的constructor,並且只能有一個。
相對也有outer,不過我們這邊沒有介紹。

type OrderedPair
    x::Real
    y::Real

    function OrderedPair(x, y)
        return x < y ? new(x, y) : new(y, x)
    end
end

以上是一個有序的配對的型別,他會幫我們把輸入的xy,小的排前面。
然後再把xy放入new()當中,new()是真正用來建構物件的,他有對應型別中fields的順序了。
以往我們的型別在實體化的時候就要把裡面的fields都安排好,但是有了constructor之後我們就可以在constructor上面做點事情,像是檢查使用者輸入的是不是正確的、做些基本的運算或轉換等等,再放入fields。

op1 = OrderedPair(4, 7)
op2 = OrderedPair(7, 4)

所以以上兩個就會是一樣的喔!

參數化

以上我們是定義出constructor,但是我們可以進一步進行參數化,讓這個型別的是用範圍更廣。

type OrderedPair{T<:Real}
    x::T
    y::T

    function OrderedPair(x, y)
        return x < y ? new(x, y) : new(y, x)
    end
end

如此一來,我們就讓所有Real的子類別都可以適用這個型別,更限定兩個成員變數的型別必須一致。

Julia的物件導向

先來複習一下物件導向程式設計的一些要素:

  • Encapsulation (封裝): 大家應該熟悉這是物件導向的第一步,我們通常會定義fields跟methods,甚至需要定義存取權限
  • Inheritance (繼承): 接著,我們將類別之間的關係組織起來,讓類別的fields跟methods可以讓其他類別可以重用
  • Polymorphism (多型): 最後我們使可以同樣的methods根據不同的類別展現出不同的行為

Julia的哲學

  • Polymorphism: multiple dispatch佔了重要的角色。multiple dispatch可以對於不同的型別提供了不同實作,同時解耦了子類別繼承了不想要的方法的狀況。
  • Inheritance: Julia的型別系統佔了重要的角色。subtype是個描述型別之間關係,而非實作,的好方法。
  • Encapsulation: 若是中介的隱私狀態是不需要的,那封裝也是不需要的。在Julia中是沒有封裝的。

傳統物件導向寫法

type Foo
    bar::Int64
    
    baz::Function
 
    function Foo(x::Int64)  # 在constructor中初始化
        this = new()  # 建立物件
        this.bar = x  # 設定物件的field
 
        function baz(input::AbstractString)  # 在method中實現polymorphism
            println(input)
        end
 
        function baz(input::Int64)
            println(input * 10)
        end
 
        this.baz = baz  # 設定物件的method
 
        return this  # 回傳物件
    end
end
foo = Foo(10)
foo.bar  # 10
foo.baz("Hello world!")  # Hello world!
foo.baz(5)  # 50

Julia風物件導向

典型的介面實作分離:

abstract Animal

immutable Dog <: Animal  # 比較可惜的是有相同fields的部份無法reuse
    color::AbstractString
    species::AbstractString
end

immutable Cat <: Animal
    color::AbstractString
    species::AbstractString
end

型別的行為可以分開定義

function color(a::Animal)
    return a.color
end

function voice(d::Dog)
    return "bark"
end

function voice(c::Cat)
    return "meow"
end
d1 = Dog("yellow", "Labrador")
voice(d1)  # "bark"
c1 = Cat("brown", "?")
voice(c1)  # "meow"

今天就到這邊結束囉!


上一篇
[Day 06] Multiple dispatch
下一篇
[Day 08] 函數式程式設計
系列文
Julia語言—從入門到專案31

尚未有邦友留言

立即登入留言