如果我subclass一个class,我可以指定某个subclass一个实例变量应该是什么吗?

If I subclass a class, can I specify a certain subclass an instance variable should be?

我有一个 NSObject 子class,BaseClass。 BaseClass 是一对子 class 的占位符 class,SubClassASubClassB。我在两个 subclasses 上都有一个实例变量。它们是同名的,并且都是另一个对象的相应子class。它们通常以非常相似的方式使用,因此我想将一些功能从我的 SubClassA 和 SubClassB 转移到 BaseClass。但是,我需要访问该变量。

如果我将变量移动到 BaseClass,我无法在 SubClassASubClassB 中指定它的正确子 class,说我可以'不要覆盖它。如果我在 BaseClass 中使用此实例变量的公共父级 class,我将失去一些对 SubClassA 之间公共的东西的访问权限] 和 SubClassB 工作。

这是一个更原始的示例,但它是我正在尝试做的事情的基础。这个例子显然行不通。我唯一的选择是必须在 SubClassASubClassB 中定义通用功能,还是有适当的方法来实现我的目标?

class BaseClass: NSObject {
    var myObject: MyObject
}

class SubClassA: BaseClass {
    override var myObject: MyObjectA
}

class SubClassB: BaseClass {
    override var myObject: MyObjectB
}

class MyObject: NSObject { }

class MyObjectA: MyObject { }

class MyObjectB: MyObject { }

这给了我错误:

Property 'myObject' with type 'MyObjectA' cannot override a property with type 'MyObject'

使用泛型怎么样?为简单起见,我删除了 NSObject

class MyObject {

}

class MyObjectA: MyObject {

}

class MyObjectB: MyObject {

}

class BaseClass<T> where T : MyObject {
    var myObject: T?
}

class SubClassA: BaseClass<MyObjectA> {
}

class SubClassB: BaseClass<MyObjectB> {
}

与其将 myObject 相关代码放入 BaseClass,不如将其放入协议扩展。考虑一下:

class BaseClass {
}

class SubClassA: BaseClass, HasMyObject {
    var myObject: MyObjectA
}

class SubClassB: BaseClass {
    var myObject: MyObjectB
}

class MyObject { }

class MyObjectA: MyObject { }

class MyObjectB: MyObject { }

protocol HasMyObject {
    associatedtype MyObjectClass

    var myObject: MyObjectClass { get set }
}

这在概念上与使用泛型非常相似,但会将您的 myObject 相关代码与 class 中的其余代码分开。这是否真的优于泛型取决于您的编码风格和特定用例。

您可以在 BaseClass 中创建一个 class 函数,returns 一个 class 继承自 BaseObject (myObject) 并覆盖它class 您需要的任何一个。

class BaseClassObject: NSObject {

}

class BaseClass: NSObject {
    func generateClass() -> NSObject {
        return BaseClassObject()
    }
}

class BranchedObject: BaseClassObject {

}

class SubClassA: BaseClass {

    var myObject: NSObject?

    override func generateClass() -> NSObject {
        return BranchedObject()
    }

    override init() {
        super.init()
        self.myObject = self.generateClass()
    }

}