Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to init my subclass with an instance of its superclass?

In my app I read calendar events of type EKEvent, and I've made an extension with a lot of computed vars so I can easily get the duration, number of man-hours etc. for each event in the calendar. But in large scale, the performance is bad - so I want to use lazy vars instead, to cache all my extra data.

Therefore, I want to make a subclass of EKEvent - called CustomEvent, which adds the lazy vars, but my problem is that the EKEventStore always returns EKEvents, and I need to convert that to instances of my CustomEvent subclass, in order to be able to access the lazy vars etc.

A simple typecast is not enough, and I've tried in a playground, to see what could work, but got nothing useful. I need a special constructor for CustomRectangle, which can initialize a CustomRectangle from a NativeRectangle. An alternative solution is to make a wrapper class that holds the original object as a property, but that wouldn't be my favorite solution, since I'd then have to map all methods and properties

class NativeRectangle: NSObject {
    var width: Int
    var height: Int

    init(width: Int, height: Int) {
        self.width = width
        self.height = height
        super.init()
    }
}

class CustomRectangle: NativeRectangle {
    var area: Int { return width * height}
}

let rect = NativeRectangle(width: 100, height: 20)

let customRect = CustomRectangle(rect) // This fails, i need a constructor

print(customRect.area)
like image 915
Esben von Buchwald Avatar asked Aug 26 '17 10:08

Esben von Buchwald


People also ask

Can a superclass be an instance of a subclass?

It is possible to reference a subclass as an instance of one of its superclasses. For instance, using the class definitions from the example in the previous section it is possible to reference an instance of the Car class as an instance of the Vehicle class.

How do you define a subclass from a superclass?

Definition: A subclass is a class that derives from another class. A subclass inherits state and behavior from all of its ancestors. The term superclass refers to a class's direct ancestor as well as all of its ascendant classes.

How do you call superclass in subclass?

Subclass methods can call superclass methods if both methods have the same name. From the subclass, reference the method name and superclass name with the @ symbol.

Can you create a superclass object in a subclass?

No. It makes zero sense to allow that. The reason is because subclasses generally define additional behavior. If you could assign a superclass object to a subclass reference, you would run into problems at runtime when you try to access class members that don't actually exist.


1 Answers

There is no way in Swift (and in general in most Object Oriented languages) to use an existing instance of a base class object when creating a child class instance.

From a general programming stand-point you have the two options in this situation:

  1. Use composition: Make the CustomRectangle contain a NativeRectangle and forward all methods to it that you need.

  2. Use a map to link NativeRectangles to additional information. In Objective C and Swift you can you objc_AssociationPolicy to have such an internal map most easily. See https://stackoverflow.com/a/43056053/278842

Btw. There is no way that you will see any speed-up from "caching" a simple computation as width * height.

like image 180
Christopher Oezbek Avatar answered Oct 22 '22 17:10

Christopher Oezbek