创建从多个协议继承的协议类型的对象时出错

Error of creating an object of a protocol type which is inherited from multiple protocols

在下面的代码中,有3个协议:WheeledVehicleWheeledVehicle(继承自WheeledVehicle

protocol Wheeled {
    var numberOfWheels: Int { get }
}

protocol Vehicle {
    var maker: String { get }
    var owner: String {get set}
    var ownerKid: String { get }
}

protocol WheeledVehicle: Wheeled, Vehicle {
  // simply just combine Wheeled and Vehicle
}

class Bike: Vehicle, Wheeled {
let numberOfWheels: Int = 0
var ownerKid: String = "Junior"

var maker: String {
    return "Ford"
}

var owner: String {
    get {
        return "Bob"
        }
        set {
            ownerKid = "\(newValue) Junior"
        }
    }
}


let bike: Bike = Bike()

let wheeledVehicleBike: WheeledVehicle = bike //error: value of type 'Bike' does not conform to specified type 'WheeledVehicle'

问题:几乎是错误本身,我不明白,为什么类型 Bike 的值不符合指定类型 WheeledVehicle

非常感谢您的宝贵时间和帮助。

编译器不假定 "being wheeled" 和 "being a vehicle" 暗示 "being a wheeled vehicle"。可能是您的 WheeledVehicle 添加了新要求。

目前,编译器不做这种检查。老实说,这不应该,因为这会引入很多含糊不清的隐性行为,而且几乎没有什么好处。

您必须明确地将 Bike 设为 WheeledVehicle

基本上:因为不符合

要让编译器知道 Bike 符合 WheeledVehicle,您必须指定它。编译器 不会 只是假设因为它们都遵循相同的协议,所以它们可以相互赋值。

同样的方法下面不行。

class A { var a : String = "" }
class B { var a : String = "" }

var a : A = A()
var b : B = a // cannot convert value of type 'A' to specified type 'B'

或者更简单

class A {  }
class B {  }

var a : A = A()
var b : B = a // cannot convert value of type 'A' to specified type 'B'

编译器不关心这两种类型是否相似——它们必须相似

如果您的 WheeledVehicle 添加了 func,您的示例会发生什么情况? Bike不符合了吗?

使Bike符合WheeledVehicle唯一方法是显式声明:class Bike : WheeledVehicle!

继承只在一个方向起作用。例如,如果 Cat 继承自 Animal,则 Cat 的实例是 Animal 的实例。但是 Animal 的实例不一定是 Cat

同样,在您的示例中,WheeledVehicle 的实例既是 Wheeled 的实例又是 Vehicle 的实例。但是既是 Wheeled 又是 Vehicle 的实例不一定是 WheeledVehicle.

的实例

另一个注意事项:您可能会发现在代码中使用此表示法很方便:

let wheeledVehicleBike: protocol<Wheeled, Vehicle> = bike

这允许您指定一个类型符合的多个协议,而无需为此目的定义额外的协议。