2015-01-15 43 views
1

我試圖在類型之間實現一個不平凡的(至少對於我的級別)關係。定義一個符合多個協議/協議+超類的變量

類A和B是一類MySuperClass的子類,和我讓他們實現協議「MyProtocol」

class MySuperclass {...} 

protocol MyProtocol { 
    func myProtocolMethod() 
} 

class A:MySuperclass, MyProtocol {...} 

class B:MySuperclass, MyProtocol {...} 

我的類「容器」具有可變的x,它可以是一個實例的A或B

class Container {... var x:???? ....} 

也許可以想象得到嗎?我的問題是,我希望我可以使用x作爲MyProtocol和MySuperclass。

就在今天,我解決了一個非常類似的問題this thread,我想我可以在這裏應用,但我沒有成功。

這個想法是聲明變量的類型,使其滿足約束<T where T:MySuperclass, T:MyProtocol>,但我在哪裏放?我到目前爲止所嘗試過的一切都沒有真正意義上的失敗。

我試過,例如:

class Container<T where T:MySuperclass, T:MyProtocol> 

class Container {... var x:T ...} 

但我實例化和Container分配T,和我這樣做時,我得到一個編譯錯誤:

class Container {... self.x = A() ....} 

「A類是不可自由兌換到'T'「

但實際上它應該,因爲A滿足類型約束。

編輯:感謝arshajii's anwer我明白爲什麼這是不可能的。但我仍然需要知道如何解決我最初的問題。

我不知道泛型實際上是否是正確的方法。我想我並不需要一個類型變量,我需要的是類似於聚合類型的東西...

編輯2-我知道我可以通過實現一個子類來實現此目的。只是想知道是否還有其他方法。但再考慮一個子類似乎是最好的方法。

在此先感謝。

回答

3

T可以是另一種類型(例如FooImpl2)完全無關FooImpl

 
      Foo 
     / \ 
    FooImpl FooImpl2 

Foo實例不能被分配給FooImpl2類型的(潛在)可變,因此錯誤。

+0

謝謝! (+1)現在我得到了那部分。但我仍然不知道如何解決我原來的問題:/也許我應該刪除Java標記,因爲該標記的解決方案需要Swift專業知識。 – Ixx

0

這只是解決這類問題的策略之一。

// declare Protocol of MySuperClass type 
protocol MySuperClassType { 
    func mySuperClassMethod() 
} 

// Make the superclass conforms to it. 
class MySuperclass: MySuperClassType { 
//     ^^^^^^^^^^^^^^^^ 
    func mySuperClassMethod() {} 
} 

protocol MyProtocol { 
    func myProtocolMethod() 
} 

class A: MySuperclass, MyProtocol { 
    func myProtocolMethod() { } 
} 

class B: MySuperclass, MyProtocol { 
    func myProtocolMethod() { } 
} 

class Container { 

    // use "Protocol Composition" to declare the property. 
    var x: protocol<MySuperClassType, MyProtocol> 

    // ... 
} 
+0

在我的情況下,這個問題是我希望變量可以被現有的apis用作MySuperClass的一個實例。一個例子:如果MySuperClass是一個UIView,即使我創建一個擴展使x符合一個協議「MySuperClassType」與UIView方法,我不能做view.addSubview(x)。 – Ixx

+0

然後你應該採取另一種策略,像這樣:http://stackoverflow.com/questions/26474061/whats-the-swift-equivalent-of-declaring-typedef-someclasssomeprotocol-mytype/26475054#26475054 – rintaro

0
class Container {... var x: protocol<MySuperclassProtocol, MyProtocol> ....} 

確保MySuperclass符合MySuperclassProtocol

+0

這個問題,在我的情況下,我希望變量可以被現有的apis用作MySuperClass的一個實例。一個例子:如果MySuperClass是一個UIView,即使我創建一個擴展使x符合一個協議「MySuperClassType」與UIView方法,我不能做view.addSubview(x)。 – Ixx

+0

'view.addSubview(unsafeBitCast(x,UIView.self))' –

+0

如果我想演員,我不會首先提出這個問題...... – Ixx