Marmelador
Marmelador

Reputation: 1017

Casting a superclass as one of its subclasses

I have a function that takes an instance of type Being. There are two subclasses to Being: Person and Animal. I want the function to recognize which of the two was passed and do something with properties specific to each subclass.

I thought this would work:

func fight(attacker1: Being, attacker2: Being) -> String {
    if attacker1 is Person {
        let name1 = attacker1.name as! Person //Error: Value of type Being has no member name
    } else {
        print("Its not a person")
    }

But it doesn't. What is the smoothest/shortest way to achieve what I am looking for?

Upvotes: 3

Views: 1238

Answers (3)

Yannick
Yannick

Reputation: 3278

While @V.Khambir's code works and probably is the nicer solution, it did not point out the problem of you code. You are trying to cast .name to a Person. .name is not a property of attacker1, that is why you are getting the error. What you wanted to do is cast attacker1 to a Person and then access the name property.

func fight(attacker1: Being, attacker2: Being) -> String {
    if attacker1 is Person {
        let name1 = (attacker1 as! Person).name
    } else {
        print("Its not a person")
    }

Upvotes: 3

Akshay Agrawal
Akshay Agrawal

Reputation: 217

Since Being is a base class so it will not have access to any child class properties. So first of all, you have to check the type of attacker1 and attacker2. for ex: if attacker1 is of type Person then you can type cast it to an instance of type Person and then access the properties of the person object. Note:- Make sure to check the type first and then type cast it else it will crash.

Upvotes: 0

Vlad Khambir
Vlad Khambir

Reputation: 4383

You should create new variable of the needed type and put on your parameter into this variable.

func fight(attacker1: Being, attacker2: Being) -> String {
    if let att1 = attacker1 as? Person {
        let name1 = att1.name
    } else {
        print("Its not a person")
    }

In this way, if attacker1 is Person, you just save this value into att1 constant and later you can use this constant as instance of the Person type.

Upvotes: 6

Related Questions