Swift从泛型类型继承

时间:2014-12-16 15:40:19

标签: generics swift

我试图从泛型类型继承,以便我可以将类型插入层次结构中:

class Foo < T:AnyObject > : T {}

但我收到错误

inheritance from non-protocol, non-class type 'T'

但是我确保T是一个类(即使我将AnyObject更改为其他类)。这是不可能的吗?

2 个答案:

答案 0 :(得分:0)

如果由于多种原因你不知道它是什么,你就不能继承。

  • 首先,编译器需要知道如何在内存中布置类的实例。要做到这一点,它需要知道它具有哪些实例变量(存储属性):类指定的那些和从超类继承的那些。

  • 编译器还需要了解超类的属性和初始值设定项,以确保正确初始化类的实例。如果超类的属性是未知的,那么在初始化程序结束之前,无法知道您是否已初始化了应该进行的所有状态(并且没有一个你不应该这样做)。如果超类的初始化程序未知,则编译器无法强制您从自己的程序中调用超类“指定的初始化程序。”

  • 如果您不知道超类是什么,您将如何编写引用超类属性和方法的方法实现?如果您编写引用self.view的代码,那么以某种方式实例化您的类的一个版本,该版本不会从具有该属性的类继承,该代码将会中断。

可能还有其他几个原因,但这些原因应该足够了。 :)

虽然有一些地方需要你进行子类化,但Cocoa(无论是在Swift还是ObjC中)通常都支持composition而不是继承来进行自定义。

如果您要向各种视图控制器添加一堆功能,并通过将其分解到自己的类中来重用代码,那么简单的解决方案就是让您的视图控制器类全部拥有该类的实例,而不是尝试 该类。如果您想要强制某些视图控制器类必须拥有Foo,您可以定义表达该要求的协议。

如果您尝试向现有类添加功能,则可以使用扩展名。您可能无法使用扩展来添加存储的属性,但您当然可以伪造它。例如,您可以使用计算属性,并在其实现中定义您自己的存储。一种方法可能是使用ObjC运行时的associated objects feature(仍然可以从Swift访问AFAIK)。

答案 1 :(得分:0)

不是CR的(Curiously recurring template pattern)与OP不同吗?

在Swift(&lt; = 3.0)中设计该模式是完全没问题的,但它目前存在漏洞,并且会在运行时锁定初始化而没有任何错误。

class Template<T> { ... }

class RealThing : Template<RealThing> { ... }

我最近在桥接的UIKit API中发现了这种模式。您可以在我的短文here中阅读。

我还将wiki中的示例翻译成了Swift 3.0:

protocol Constructor {
    init()
}

protocol Shape {
    func cloned() -> Shape
}

typealias ShapeProtocols = Constructor & Shape

class Shape_CRTP<T> : ShapeProtocols {

    required init() {}

    func  cloned() -> Shape {
        let new = Shape_CRTP<T>()
        // copy everything to `new` from `self`
        return new
    }
}

extension Shape_CRTP where T : ShapeProtocols {

    func cloned() -> Shape {
        let new = T()
        // copy everything to `new` from `self`
        return new
    }
}

// First non-crtp proof of concept
class Square : ShapeProtocols {

    required init() {}
    func cloned() -> Shape {
        return Square()
    }
}

let clone = Shape_CRTP<Square>().cloned() // creates a new `Shape`
type(of: clone) // Square.Type

// now CRTP but this is bugged: http://blog.devandartist.com/posts/swift-crtp
class Circle : Shape_CRTP<Circle> {}

Circle().cloned()

print("this will never print because of the described bug")