ProgramGuru

Inheritance, overrides and safe casting

Inheritance, overrides and safe casting

A school has a general person description and a specialized teacher description. Class inheritance can express a specialization, and an override replaces an inherited implementation. It should model a genuine substitutable relationship rather than merely avoid copying a few lines.

What you’ll learn

  • Trace an override through a superclass reference.
  • Handle a conditional cast without assuming it must succeed.

Inheritance, overrides and safe casting in the example

  1. Superclass reference

    A school has a general person description and a specialized teacher description.

    Superclass reference
  2. Subclass instance

    A subclass can inherit members from one superclass.

    Subclass instance
  3. Overridden behaviour

    The reference is declared as Person but points at a Teacher instance, so the override returns Teacher.

    Overridden behaviour
The reference is declared as Person but points at a Teacher instance, so the override returns Teacher. The is check is true, and the conditional cast succeeds. The reference declaration does not replace the instance with a new superclass object.

How inheritance, overrides and safe casting works

A subclass can inherit members from one superclass. Calling an overridden method through a superclass reference uses the instance’s implementation. A conditional cast with as? checks whether a reference can be viewed as a particular subtype and returns an optional instead of asserting success.

Work through inheritance, overrides and safe casting

Save this complete program as main.swift and run it with the Swift toolchain. No separate input file is needed.

Swift · complete program

class Person {
  func role() -> String { "Person" }
}
class Teacher: Person {
  override func role() -> String { "Teacher" }
}
let person: Person = Teacher()
print(person.role())
print(person is Teacher)
print((person as? Teacher)?.role() ?? "Other")

Expected output

Teacher
true
Teacher

Follow the execution

The reference is declared as Person but points at a Teacher instance, so the override returns Teacher. The is check is true, and the conditional cast succeeds. The reference declaration does not replace the instance with a new superclass object.

Try this program in the Swift compiler. Paste the complete source above.

Practice: Inheritance, overrides and safe casting

Your task: What does as? Teacher return for an ordinary Person instance?

Swift · complete program

class Person {
  func role() -> String { "Person" }
}
class Teacher: Person {
  override func role() -> String { "Teacher" }
}
let person: Person = Teacher()
print(person.role())
print(person is Teacher)
print((person as? Teacher)?.role() ?? "Other")

Worked answer

It returns nil. Handle that result rather than using a forced cast that can trap when the actual instance does not match.

Check the existing instance before casting

Structs do not use class inheritance. Protocols can express shared capabilities without a superclass and often fit unrelated types better. Mark a class or member final when further overriding is not part of its intended contract.

Check your decision

What does as? Teacher return for an ordinary Person instance?
Choose one answer. You can try again.

Answer and explanation

It returns nil.

It returns nil. Handle that result rather than using a forced cast that can trap when the actual instance does not match.

Check the existing instance before casting

It returns nil. Handle that result rather than using a forced cast that can trap when the actual instance does not match. Structs do not use class inheritance.

Further reading: official Swift language guide.

Reaching the recap and completing the quizzes are separate milestones.

    Next lesson: Protocols: define a capability →