【问题标题】:Swift 4 generic, referencing selfSwift 4 泛型,引用自我
【发布时间】:2018-02-28 23:34:57
【问题描述】:

我正在考虑使用 Swift 4 的以下结构:

class BaseClass {

    // abstract function
    func doSomething<T: BaseClass>(with object: T) {}

}

class SubClass: BaseClass {

    var title: String = "hello world"

    // implementation
    override func doSomething<T: BaseClass>(with object: T) {
        // do something with object
        // can I access object.title here?
    }

}

在上面的 sn-p 中,object.title 属性不可访问,因为显然object 属性的类型是BaseClass,而不是SubClass

我假设函数参数类型应该设置为Self,如:

func doSomething(with object: Self) {}

但编译时出现以下错误。

'Self' is only available in a protocol or as the result of a method in a class; did you mean 'BaseClass'?

有没有办法在覆盖基类的函数时引用 self 的类型?

编辑

所以我的问题是我们是否可以在覆盖超类函数的函数中访问SubClass 的属性(因为object.title 属性在SubClass 实现中)。我正在考虑很多继承基类的类,所以我认为让函数在调用时与具有相同类型的另一个实例交互可能很有用。

【问题讨论】:

  • 我认为你不能访问基类对象的子类属性,你可以像这样访问title self.title inside doSomething
  • 你不能有像函数参数那样的协方差。考虑是否可能; BaseClass 会说你可以传入一个继承自 BaseClass 或者是 BaseClass 的类型的实例。然后SubClass 会说您实际上可以 传入一个继承自SubClass 或者是SubClass 的类型的实例。这明显违反了 Liskov 替换原则,您可以将 SubClass 向上转换为 BaseClass,然后将 BaseClass 参数传递给期望实例符合 SubClass 的方法。

标签: swift generics inheritance subclass self


【解决方案1】:

您不能创建函数 kike func doSomething(with object: Self) {},因为它在这些类中意味着不同的东西(因此,不会在语义上相互覆盖)

考虑使用BaseClass 对象调用子类,这不是Subclass,如果您有一个带有Self 的方法,就像您在sn-p 中显示的那样,它将由超类实现,但是子类将不再实现它。

但是,你可以在子类中这样转换:

override func doSomething<T: BaseClass>(with object: T) {
    guard let subClass = object as? SubClass else { return }
    print("\(title): \(subClass.title)")
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多