如何使不同的类符合具有不同功能的相同协议?

时间:2016-12-04 20:18:13

标签: ios swift swift3 swift-protocols

如果标题不清楚,我会事先道歉,但我想先了解一些代码片段是如何实现的:

ClassOne:

@objc protocol FetchProtocol
{
    var someVar: Bool
    {
        get set
    }

    var someUIView: FetchProtocol
    {
        get set
    }

    func someFuncOne()
}

class ClassOne: UIViewController, FetchProtocol
{
    ...

    @IBOutlet var someUIView: FetchProtocol!

    ....

}

ClassTwo:

@objc protocol FetchProtocol
{
    var someVar: Bool
    {
        get set
    }

    var someTableView: FetchProtocol
    {
        get set
    }

    var someUIView: FetchProtocol
    {
        get set
    }

    func someFuncOne()
    func someFuncTwo()
}

class ClassTwo: UIViewController, FetchProtocol
{
    ...

    @IBOutlet var someTableView: FetchProtocol!
    @IBOutlet var someUIView: FetchProtocol!

    ....

}

ClassOneClassTwo都符合相同的FetchProtocol,并且这两个类使用相同的someVarsomeFuncOne,但是ClassTwo还仅使用someTableViewsomeFuncTwo唯一ClassTwo

如何在两个类之间使用相同的协议,但另一个类具有“附加”不同的骨架实现?

例如,如下所示:

if let vc = currentVC as? FetchProtocol
{
    if vc.someVar == true
    {
        // Check if vc is of class type ClassOne, call someFuncOne

        // Otherwise if vc is of class type ClassTwo, call someFuncOne and someFuncTwo

    }
}

如上所述是否可能使用协议,如果是,如何正确实现它,还是有另一种选择?

2 个答案:

答案 0 :(得分:1)

您的代码无法编译,我认为您过度复杂,并且使用协议是为了使用它们。。如果你想要做的就是这样,根本不需要使用任何协议:

if let vc = currentVC as? FetchProtocol
{
    if vc.someVar == true
    {
        // Check if vc is of class type ClassOne, call someFuncOne

        // Otherwise if vc is of class type ClassTwo, call someFuncOne and someFuncTwo

    }
}

为什么不删除所有协议,只需执行:

if currentVC.someVar {
    if let class1 = currentVC as? ClassOne {
        class1.someFuncOne()
    } else if let class2 = currentVC as? ClassTwo {
        class2.someFuncOne()
        class2.someFuncTwo()
    }
}

这里你真的不需要协议,因为无论协议是否存在,你仍然需要检查currentVCClassOne还是ClassTwo

协议就像“黑匣子”。考虑这种方法:

func foo(fetchObj: FetchProtocol) {
    fetchObj.someFuncOne()
}

foo并不关心fetchObj 究竟是什么。它只是说“我不在乎你是什么,只做someFuncOne!”

你在这里尝试做的完全相反:“我关心你是什么。如果你是ClassOne,那就去做吧。如果你是{{ 1}},做那个。“

答案 1 :(得分:1)

你的问题非常抽象,很难遵循,但这就是你所要求的。话虽如此,我怀疑你根本不需要在这里使用协议。

protocol P1 {
    var someVar1: String { get }

    func func1();
}

protocol P2: P1 {
    var someVar2: String { get }
    func func2();
}


class C1: P1 {
    var someVar1 = "String 1 in C1"

    func func1() {
        print(someVar1)
    }
}

class C2: P2 {
    var someVar1 = "String 1 in C2"
    var someVar2 = "String 2 in C2"

    func func1() {
        print(someVar1)
    }

    func func2() {
        print(someVar2)
    }
}


func foo(with object: P1) {
    object.func1()

    if let object = object as? P2 {
        object.func2()
    }
}

print("Test case 1:")
foo(with: C1())
print("Test case 1:\n")
foo(with: C2())