2014-12-03 99 views
0
class Foo { 
    var str = "hi"; 

    func refresh() { 
    println(self.str); 
    } 
} 

class Bar: Foo { 
    // override str in init 
    // create Zed with parent = self 
} 

class Baz: Foo { 
    // override str in init 
    // create Zed with parent = self 
} 


class Zed { 
    var parent: Foo?; // I want it to work for both Bar and Baz 

    // call parent.refresh() in init 
} 

我想讓Zed類擁有一個適用於Bar和Baz類的屬性。這可能嗎?快速繼承問題

+0

所以你想訪問Bar和Baz類的'parent'? – Padarom 2014-12-03 07:56:59

+0

'parent'應該是'Bar'或'Baz'類。 – switz 2014-12-03 07:59:12

+1

那什麼不起作用?這對我來說看起來很好...... – Grimxn 2014-12-03 08:15:23

回答

0

我不明白的問題,因爲這段代碼看起來好像沒什麼問題:

class Foo { 
    var str = "hi"; 

    func refresh() { 
     println(self.str); 
    } 
} 

class Bar: Foo { 
    override init() { 
     super.init() 
     str = "bar" 
     let zed = Zed(parent: self) 
    } 
} 

class Baz: Foo { 
    override init() { 
     super.init() 
     str = "baz" 
     let zed = Zed(parent: self) 
    } 
} 


class Zed { 
    var parent: Foo?; // I want it to work for both Bar and Baz 

    init(parent: Foo) { 
     self.parent = parent 
     self.parent?.refresh() 
    } 
} 

let b = Bar() // prints bar 

let c = Baz() // prints baz 

如果問題是如何確保美孚的沒有其他子類允許爲捷思銳的父母:有沒有辦法來指定斯威夫特的類型約束的「或」約束,但你可以通過在酒吧和巴茲相同的協議,並指定該協議爲parent的類型:

protocol CanRefresh 
{ 
    func refresh() 
} 

extension Bar : CanRefresh 
{ 

} 

extension Baz : CanRefresh 
{ 

} 

class Zed { 
    var parent: CanRefresh?; // I want it to work for both Bar and Baz 

    init(parent: CanRefresh) { 
     self.parent = parent 
     self.parent?.refresh() 
    } 
} 

這樣ÿ您可以明確列出Zed支持的類(但這是一個非常糟糕的API設計;您應該發佈協議,並讓任何願意遵守該協議的人遵守)。

+0

我想我有另一個問題。我清理了代碼,它按預期工作,謝謝! – switz 2014-12-03 08:43:04

0

我能想到的最接近的是對父類使用Protocol

protocol FooProtocol { 
    var str: String { get set } 
    func refresh() 
} 

class Foo { 
    var str = "hi" 

    func refresh() { 
    println(self.str) 
    } 
} 

美孚現在符合FooProtocol,即使它不直接實現它。這樣,每個從Foo繼承的類也符合該協議。現在

class Bar: Foo, FooProtocol { 
    override init() { 
    super.init() 
    self.str = "ho" 
    } 
} 

class Baz: Foo, FooProtocol { 
    override init() { 
    super.init() 
    self.str = "hup" 
    } 
} 

,你應該能夠在捷思銳設定的parent類型FooProtocol。它可能是Bar或Baz的一個實例。

class Zed { 
    var parent: FooProtocol? 
} 
+0

如果你繼承了父類的子類,爲父類創建一個協議是不是很沒用? – 2014-12-03 08:19:41

+1

這不是,如果你不想在每個子類中實現'refresh()'。 – Padarom 2014-12-03 08:23:56

+1

你不必在每個子類中重新實現它! Bar和Baz從foo繼承它,即使沒有協議涉及,並且從Foo繼承是一個充足的類型約束。換句話說,問題中的代碼就足夠了。我懷疑實際的問題是如何防止Foo的其他子類被用作「父」,在這種情況下使用這樣的協議是一種解決方案。 – 2014-12-03 08:28:12