基本上前面介紹的就是Julia的type system與multiple dispatch,這兩個可謂Julia設計最優雅的地方,當然我還有很多東西沒有介紹到,可能就要請大家去看官方文件了。
這個標題是Julia的物件導向,但是從前面一點都沒有看到傳統物件導向的影子阿!
別急~~~~
雖然Julia沒有傳統物件導向的樣子,但是仍有物件導向的精神:可讀性與可修改性
基本上可讀性在Julia這個語言當中遍地都是,應該不用我解釋。可修改性也如同前面提到的,想要增加型別的行為只要外加上去就有了,型別也可以自由的重新定義或是成為子類別。
所以基本上Julia是可以適用物件導向的,我們來看看怎麼做吧!
前面在提型別的時候都沒有提到constructor的部份,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
以上是一個有序的配對的型別,他會幫我們把輸入的x
跟y
,小的排前面。
然後再把x
跟y
放入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
的子類別都可以適用這個型別,更限定兩個成員變數的型別必須一致。
先來複習一下物件導向程式設計的一些要素:
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
典型的介面實作分離:
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"
今天就到這邊結束囉!