如果我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,SubClassA
和 SubClassB
。我在两个 subclasses 上都有一个实例变量。它们是同名的,并且都是另一个对象的相应子class。它们通常以非常相似的方式使用,因此我想将一些功能从我的 SubClassA 和 SubClassB 转移到 BaseClass。但是,我需要访问该变量。
如果我将变量移动到 BaseClass
,我无法在 SubClassA
和 SubClassB
中指定它的正确子 class,说我可以'不要覆盖它。如果我在 BaseClass
中使用此实例变量的公共父级 class,我将失去一些对 不 与 SubClassA
之间公共的东西的访问权限] 和 SubClassB
工作。
这是一个更原始的示例,但它是我正在尝试做的事情的基础。这个例子显然行不通。我唯一的选择是必须在 SubClassA
和 SubClassB
中定义通用功能,还是有适当的方法来实现我的目标?
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()
}
}
我有一个 NSObject 子class,BaseClass
。 BaseClass 是一对子 class 的占位符 class,SubClassA
和 SubClassB
。我在两个 subclasses 上都有一个实例变量。它们是同名的,并且都是另一个对象的相应子class。它们通常以非常相似的方式使用,因此我想将一些功能从我的 SubClassA 和 SubClassB 转移到 BaseClass。但是,我需要访问该变量。
如果我将变量移动到 BaseClass
,我无法在 SubClassA
和 SubClassB
中指定它的正确子 class,说我可以'不要覆盖它。如果我在 BaseClass
中使用此实例变量的公共父级 class,我将失去一些对 不 与 SubClassA
之间公共的东西的访问权限] 和 SubClassB
工作。
这是一个更原始的示例,但它是我正在尝试做的事情的基础。这个例子显然行不通。我唯一的选择是必须在 SubClassA
和 SubClassB
中定义通用功能,还是有适当的方法来实现我的目标?
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()
}
}