2016-01-20 48 views
0

我有以下問題:快速遺傳和多態性

A類超級類。

A類協議:

具有方法 - >

func test(params: GeneralParams, completionBlock: GeneralCompletionBlock) 

GeneralParams是超類,並具有以下子類2:BParams,CParams。

現在我有2級以上的類:

B類:A,A協議

C類:A,A協議

我想類B,C爲使用測試功能,但具有不同類爲他們的B類參數我想要使用BParams和不同的完成塊,併爲C同樣的事情。我想要爲兩者使用不同的參數和實現都具有相同的方法。

什麼是這種情況的最佳解決方案?

+0

如果你有不同的參數,你有不同的方法。與Objective-C不同,Swift允許覆蓋。 – nhgrif

+1

你的問題可能會從一個爲什麼你需要類似的東西的例子用例中受益匪淺。 – nhgrif

+0

我希望它爲了有兩個類更簡潔的代碼和相同的接口。我將很快有第三課,我希望能夠爲所有3使用不同的參數和不同的completionHandler使用相同的類名稱。 –

回答

0

由於Swift允許方法重載,因此這裏的最佳做法是重載一個方法以滿足您在新類中的需求。 例如:

class B: A{ 
    func test(params: BParams, completionBlock: GeneralCompletionBlock){ 
     ... 
     } 
    } 


class C: A{ 
    func test(params: CParams, completionBlock: GeneralCompletionBlock){ 
     ... 
     } 
    } 
+0

這就是我所做的,但由於某些原因,我不得不保留GeneralParams類,並在之後施放它,重寫並沒有讓我在基金簽名中使用BParams。 –

+0

@ gal.orlanczyk這是我的壞,不包括單詞「覆蓋」,只是重載/重寫相同的方法與不同的參數 –

+0

@ gal.orlanczyk我編輯答案 –

0

我想B類,C使用測試功能,但不同類的PARAMS

子類中最重要的規則是substitutability。如果B是一個樣的,然後到處的A可以使用,它必須是合法使用B.那麼A的每個子類必須支持此方法:

func test(params: GeneralParams, completionBlock: GeneralCompletionBlock) 

它不能限制這種方法其他類型(甚至不包括這些的子類型)。如果是的話,那麼會有地方我可以使用A,但不能使用B.

B可以自由地擴展A並添加新的方法。因此,正如@tmac_balla所示,您可以添加一個爲子類型選擇的重載。例如:

class AParam {} 
class BParam: AParam {} 

class A { 
    func f(param: AParam) {print("A")} 
} 

class B: A { 
    func f(param: BParam) {print("B")} 
} 

B().f(AParam()) // "A" 
B().f(BParam()) // "B" 

但是B仍然必須支持傳遞超類。

大部分時間在Swift中,這是關於事情的錯誤方式。子類化引入了許多你通常不想要的複雜性。相反,您通常需要Swift中的協議和泛型。例如,而不是A,B和C,你只需要一個通用的A和一個協議。

protocol Param { 
    var name: String { get } 
} 
struct AParam: Param { 
    let name = "A" 
} 
struct BParam: Param { 
    let name = "B" 
} 

struct S<P: Param> { 
    func f(param: P) {print(param.name)} 
} 

let a = S<AParam>() 
a.f(AParam()) // "A" 
// a.f(BParam()) // error; we've restricted the type it can take 

let b = S<BParam>() 
b.f(BParam()) // "B"