0

How do I work with variables in Swift that have the type of a main class but are passed an instance of a subclass?

Here is a piece of example code:

class MainClass {
    var name: String
    
    init(name: String) {
        self.name = name
    }
}

class Num1: MainClass {
    var num: Int = 1
}

class Num2: MainClass {
    var num: Int = 2
}

struct ExampleView: View {
    var subClassInstance: MainClass
    
    var body: some View {
        Text(subClassInstance.name)
        Text(subClassInstance.num) // trying to access this property
    }
}
let example = ExampleView(subClassInstance: Num1(name: "test"))

Specifically, I want to be able to access subclass properties from a variable with the type of a main class. In the context of my example, I want to be able to access the "num" property of the passed subclass instance from the variable in the view with type of MainClass. Is this possible? The motivation for doing this is having one view that works with similar subclasses of a main class--not having to write two views, one with a variable set to the type of each subclass.

2 Answers 2

1

You could have num as a property in MainClass. This means you can access num from MainClass itself or any sub-class.

Example:

class MainClass {
    var name: String
    var num: Int

    init(name: String, num: Int) {
        self.name = name
        self.num = num
    }
}

class Num1: MainClass {
    init(name: String) {
        super.init(name: name, num: 1)
    }
}

class Num2: MainClass {
    init(name: String) {
        super.init(name: name, num: 2)
    }
}

struct ExampleView: View {
    var subClassInstance: MainClass

    var body: some View {
        Text(subClassInstance.name)
        Text(String(subClassInstance.num))
    }
}
let example = ExampleView(subClassInstance: Num1(name: "test"))

See edit history for old answer

Sign up to request clarification or add additional context in comments.

6 Comments

and I presume that this could be extended to work for either num1 or num2...
@JohnSorensen Ideally you should just have num as a property in MainClass.
yeah it looks like the way to go is to have it as a property in the main class but override in the subclasses
the property overriding syntax isn't clear to me yet though haha
@JohnSorensen I re-did the answer. This time using num as a property. In this case I assume you wanted to keep the default num values`, so I did that. Have a look, is that what you are after?
|
0

It is common practice to include properties in the superClass (your MainClass) if the property is used by different subclasses, I'll not replicate other answers here, George explained it pretty well

(This Answer is about what to do if Georges answer is not suitable, such as when you need different properties in the subclasses)

For your own understanding, It should be possible to Type Cast your ExampleView.subClassInstance to Num1 or Num2

2 ways to do this are

let numInstance = subClassInstance as? Num1

let numInstance = subClassInstance as! Num1

as? will try to downcast from MainClass to Num1 and will return nil if this fails for some reason

as! will try to downcast from MainClass to Num1 and throw an error, causing your app to crash if this fails

if all goes successful you should then be able to use

Text(numInstance.num)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.