swift - Swift 上的协议(protocol)和组合

标签 swift protocols composition

我正在尝试了解有关协议(protocol)的更多信息,但在不了解以下代码片段发生的情况的情况下陷入困境。主要是为好的文章和解释寻求一些启发和方向。

在 Apple 库的一个示例中,协议(protocol)所做的不仅仅是确保类符合它。

它们允许一个类中的对象访问其他类中的方法,而无需使用传统的类继承定义。

Dice 类上的这行代码 let Generator: RandomNumberGenerator 允许 Dice 类型的 var d6 访问函数func random() -> Double 位于 Dice 范围之外、LinearCongruentialGenerator 范围内,并且使用 RandomNumberGenerator build 这座桥。

.ramdom()再次不在Dices范围内时,还允许执行以下调用d6.generator.random()

protocol RandomNumberGenerator {
    func random() -> Double
}

class LinearCongruentialGenerator: RandomNumberGenerator {
    var lastRandom = 42.0
    let m = 139968.0
    let a = 3877.0
    let c = 29573.0

    func random() -> Double {
        lastRandom = ((lastRandom * a + c) % m)
        return lastRandom/m
    }
}

class Dice {
    let sides: Int
    let generator: RandomNumberGenerator

    init(sides: Int, generator: RandomNumberGenerator) {

        println(generator.random())

        self.sides = sides
        self.generator = generator
    }

    func roll() -> Int {
        return Int(generator.random() * Double(sides)) + 1
    }
}

var d6 = Dice(sides: 6, generator: LinearCongruentialGenerator())

更新问题

谢谢各位的解答!通过做一些研究,我想我刚刚接触了构图。因此,我编写了下面的代码来更好地举例说明组合,而不使用协议(protocol)或委托(delegate)。只是纯粹的组合。如果我做对了,请告诉我,因为它可能会帮助其他尝试理解构图的人。

class A {

    var a1: String

    init (valueToA: String){
        self.a1 = valueToA
    }

    func aFunc1() -> A {
        return self
    }
}


class B {

    var b1: A

    init (valueToB: A ) {
        self.b1 = valueToB
    }

    func bFunc1(){
        println("I am bFunc and I am calling aFunc \(b1.aFunc1())")
    }

}

var myA = A(valueToA: "Initiated myA with this string")
//myA.aFunc1()

var myB = B(valueToB: myA)
myB.b1 = A(valueToA: "a value to B")
myB.b1.aFunc1()

The same code but now with protocols

protocol myProtocol {
    func protocolFunc(value: String) -> String
}

class A: myProtocol {

    var a1: String

    init (valueToA: String){
        self.a1 = valueToA
    }

    func aFunc1() -> A {
        return self
    }

    func protocolFunc(value: String) -> String {
        return value
    }

}

class B {

    var b1: A
    var b2: myProtocol

    init (valueToB1: A, valueToB2: myProtocol ) {
        self.b1 = valueToB1
        self.b2 = valueToB2
    }

    func bFunc1(){
        println("I am bFunc and I am calling aFunc \(b1.aFunc1())")
    }

    func callProtocolFuncOnA (value: String) {
        b1.protocolFunc(value)
    }

}

var myA1 = A(valueToA: "my A 1 created")
var myA2 = A(valueToA: "my A 2 created")


var myB = B(valueToB1: myA1, valueToB2: A(valueToA: "my A 3 created"))

myB.callProtocolFuncOnA("calling other function")

最佳答案

正如 @DevAndArtist 在他的评论中所说,当 RandomNumberGenerator 类型在 Dice 类的初始值设定项中传递时,它允许封装(抽象),因此只有该部分您可以看到您的实现。

以我的拙见,如果常量生成器Dice类范围之外不可见,正如您在问题中所说,例如制作他的访问修饰符,可能会更好private,但请记住,在您的示例中,所有内容都在同一个 swift 文件中设置,这意味着 private 访问修饰符与其他编程语言(如 C#、Java)不同等

即使执行private,您也可以在调用中访问d6.generator.random(),因为它存在于同一个 Swift 文件中,这是隐藏属性的唯一方法如果您为 Dice 类创建一个新的 Swift 文件,然后在属性为私有(private)时进行此调用:

var d6 = Dice(sides: 6, generator: LinearCongruentialGenerator())
println(d6.generator.random())

给你以下错误:

'Dice' does not have a member named 'generator'

并且您可以隐藏其范围之外的属性。这只是一个观点。

希望这对您有帮助。

关于swift - Swift 上的协议(protocol)和组合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31797688/

相关文章:

swift - 协议(protocol) associatedType 和 <>

clojure - 跨多个命名空间使用 clojure 协议(protocol)

swift - 我可以在 Swift 中组合类型吗?

Java - 对象中具有相同数据类型的多个字段

swift - swift3中NSNumber怎么写?

ios - 使用另一个 View Controller (带有 TableView )来显示 UISearchController 的结果

cocoa - 数据源和委托(delegate)有什么区别?

java - 组合中的对象?

ios - UIBarButtonItem 在 UIToolBar 中不可点击

ios - UIButton 的出现和消失