我正在尝试了解有关协议(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/