快速遗传和多态性

快速遗传和多态性

问题描述:

我有以下问题:快速遗传和多态性

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使用相同的类名称。 –

由于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我编辑答案 –

我想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"