不能使用具体的子类在Swift中实现协议中的属性

时间:2014-08-21 06:25:10

标签: swift

我在JAVA中执行类似于Bridge Pattern的操作,DriverType是协议,需要名为vehicle的属性为Drivable对象,Drivable也是一个协议,并被班级' Car'

采用
protocol Drivable {
    var speed: Double { get }
}

protocol DriverType {
    var vehicle: Drivable { get }
}

class Car: Drivable {
    var speed = 80.0;
    var brand = "BMW"
}

class Driver: DriverType {

    var vehicle: Car = Car() //Error: Type 'Driver' does not conform to protocol 'DriverType'

    // This one works, but I have to downcast the property to 'Car' everytime I use it.
    var vehicle: Drivable = Car() //Type 'Driver' does not conform to protocol 'DriverType'
}

当我实施Driver课程时,将vehicle属性声明为Car非常自然。但后来我遇到了编译器认为Driver不符合DriverType的问题,即使Car完全符合Drivable

更新:

@Antonio的回答很可靠,但这是我目前所解决的问题,它并不涉及到该类的泛型。

protocol Drivable {
    var speed: Double { get }
    init()
}

protocol DriverType {
    func vehicle() -> Drivable
}

class Car: Drivable {
    var speed = 80.0;
    var brand = "BMW"
    required init() {}
}

class Driver: DriverType {
    private var m_vehicle: Car = Car()
    func vehicle() -> Drivable {
        return m_vehicle
    }

    // Inside Driver class I use the m_vehicle property directly
}

1 个答案:

答案 0 :(得分:1)

我认为编译错误具有误导性。 DriverType声明任何采用它的类都必须使用vehicle类型公开Drivable属性,而不是使用Drivable类型的类类型的属性。

我会通过使用泛型定义DriverType协议和Car类来解决此问题:

protocol Drivable {
    var speed: Double { get }
    init()
}

protocol DriverType {
    typealias T: Drivable
    var vehicle: T { get }
}

class Car: Drivable {
    var speed = 80.0;
    var brand = "BMW"
    required init() {}
}

class Driver<T: Drivable>: DriverType {   
    var vehicle: T = T() 
}

这明确指出采用DriverType的类必须公开vehicle属性,其类型是采用Drivable协议的任何类。