V类协议中的继承

时间:2017-09-04 11:24:40

标签: swift

我有点搞砸了,其理念如下:

代码1:

a /home/store//.vas_logon_server 1K

代码2:

a /home/store//.vas_disauthcc_611400381 1K
  1. a /home/store//.bash_history 7Ka /home/store//test/ 0K之间有什么区别,因为它们都有相同的用途?

  2. a /home/store//test/1.txt 1K中,a /home/store//test/migrate-perf3.txt 3958K是来自新协议的a /home/store//test.txt 1K还是只有a /home/store//exclude.txt 1K的协议?

  3. 任何解释都将受到高度赞赏!

4 个答案:

答案 0 :(得分:7)

代码1和代码2基本上不一样

  

Code 1和Code 2有什么区别,因为它们都有相同的用途?

不,他们没有。第一个定义了一个类层次结构,第二个定义了一个协议(一个API,如果你愿意)和一个符合它的类型。

  

在代码2中,classNew是从新协议继承还是仅仅符合协议?

符合协议。没有继承(如果你是迂腐的话)。

代码1定义了一个基类和一个继承它的类。子类重写函数abc()的基类,它的行为与您给定的类层次结构一样,即

let x: New = ClassNew()
let y: ClassNew = ClassNew()

print(x.abc()) // prints "derived class"
print(y.abc()) // prints "derived class"

两个print语句都调用派生类的abc()

代码2 中,您定义了一个没有方法的协议,以及一个带有扩展方法的协议扩展。请注意,这是“默认方法”,协议中没有任何内容可以默认使用。然后,您定义一个符合协议的类,并添加一个恰好与扩展方法同名的新方法。区别(来自纯类层次结构)很重要,因为调用的abc()版本在编译时是静态确定的

protocol New2{}

extension New2{
    func abc(){
        print("new protocol")
    }
}

class ClassNew2: New2 {
    func abc() {
        print("derived protocol")
    }
}

let y2: ClassNew2 = ClassNew2()
let x2: New2 = y2

print(x2.abc()) // prints "new protocol"
print(y2.abc()) // prints "derived protocol"

即使x2和y2 是同一个对象,也会调用不同版本的函数。这是因为除了可以从协议中推断的内容之外,不允许编译器假设x2的任何内容。所以它不知道对象有自己的abc()所以它必须调用扩展函数。

如果你已经定义了这样的协议:

protocol New3{
    func abc()
}

extension New3{
    func abc(){
        print("new protocol")
    }
}

class ClassNew3: New3 {
    func abc() {
        print("derived protocol")
    }
}

let y3: ClassNew3 = ClassNew3()
let x3: New3 = y3

print(x3.abc())  // prints "derived protocol"
print(y3.abc())  // prints "derived protocol"

这次编译器知道对象应该有一个函数abc(),如果没有,则只使用扩展函数。然后适用于类的正常继承规则。

答案 1 :(得分:1)

classNew只是符合第二个代码中的协议。对于Swift中的每个协议都是如此,因为带有协议的目前不支持

这也回答了你的第一个问题:这个用例中的两个代码之间没有显着差异,但是,一般来说,协议对于其他类型的东西而不是子类化。

答案 2 :(得分:1)

Code 1Code 2完全相同,只是概念上不同。

如果我们用简单的话说,Class定义对象本身,Protocol定义对象的行为。

如果与Java相比,protocolInterfaces类似。

Checkout the Protocol Documentation

答案 3 :(得分:1)

代码2 protocol extensions的一个示例。不同之处在于,您无法在代码2 中调用super.abc() - 您必须提供不在任何super上下文中的方法实现。

只是我的意见 - 不要使用协议默认实现,因为如果你忘记提供"覆盖"编译器不会保存你。当你真的需要一个。