Search code examples
swiftinstance-variablessubclassing

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


I have an NSObject subclass, BaseClass. BaseClass is a placeholder class for a couple subclasses, SubClassA and SubClassB. There is an instance variable that I have present on both of the subclasses. They're the same name, and are both of a corresponding subclass of another object. They're often used in very similar ways, so I wanted to move some functionality from my SubClassA and SubClassB to the BaseClass. However, I need access to that variable.

If I move the variable into the BaseClass, I am unable to specify the proper subclass of it in SubClassA and SubClassB, saying I can't override it. If I use the common parent class of this instance variable in the BaseClass, I lose some access to things that aren't common between how SubClassA and SubClassB work.

This is a more primitive example, but the basics of what I'm trying to do. This example obviously does not work. Are my only options to choose having to define common functionality within SubClassA and SubClassB or is there a proper way to achieve my goal here?

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 { }

This gives me the error:

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


Solution

  • How about using generic? For simplicity, I removed 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> {
    }