Inheritance & Interfaces
Keywords:, virtual, override, abstract, base, sealed, interface
CategoryObject-oriented programming
In Unityclass Player : MonoBehaviour, IPointerClickHandler

Inheritance & Interfaces

Inheritance lets a class build on another class and reuse its code. Player : MonoBehaviour means "a Player is a MonoBehaviour, plus some extras". Interfaces describe what a class can do, without saying how.

Inheritance is a family tree: a Goblin is an Enemy, which is a MonoBehaviour. The Goblin inherits everything the Enemy has, like eye color from a parent. An interface is a skill certificate, such as a driving licence. A Goblin, a Crate and a Wall aren't related, but each can hold the "can take damage" certificate. Code that needs a driver just asks for the licence, not the family name.

Inheritance basics

using UnityEngine;

// Base class: shared by every enemy
public class Enemy : MonoBehaviour
{
    [SerializeField] protected float health = 50f; // protected: children can use it

    public void TakeDamage(float amount)
    {
        health -= amount;
        if (health <= 0f) Die();
    }

    // virtual: children MAY replace this
    protected virtual void Die()
    {
        Destroy(gameObject);
    }
}

// Child class: everything Enemy has, plus changes
public class ExplodingSlime : Enemy
{
    [SerializeField] private GameObject explosionPrefab;

    // override: replace the parent's version
    protected override void Die()
    {
        Instantiate(explosionPrefab, transform.position, Quaternion.identity);
        base.Die(); // also run the parent's version (Destroy)
    }
}
KeywordMeaning
class B : AB inherits from A. A class can only have one parent class.
virtual"Children are allowed to override this."
override"I'm replacing my parent's virtual/abstract version."
base.Method()Call the parent's version from inside the override.
abstractOn a class: can't be used directly, only inherited. On a method: no body; children must override it.
sealedNobody can inherit from this class (or override this method further).

Abstract classes

public abstract class Weapon : MonoBehaviour
{
    [SerializeField] protected float cooldown = 0.5f;
    private float nextUse;

    public void TryUse()
    {
        if (Time.time < nextUse) return;
        nextUse = Time.time + cooldown;
        Use(); // each weapon decides what "use" means
    }

    protected abstract void Use(); // no body: every weapon MUST write one
}

public class Sword : Weapon
{
    protected override void Use() { Debug.Log("Swing!"); }
}

public class Bow : Weapon
{
    protected override void Use() { Debug.Log("Shoot arrow!"); }
}

// The player doesn't care which weapon it has:
[SerializeField] private Weapon equipped; // drag a Sword OR a Bow here
void Update() { if (Input.GetButtonDown("Fire1")) equipped.TryUse(); }

You can't add an abstract class like Weapon to a GameObject by itself, only its concrete children.

Interfaces

public interface IDamageable
{
    void TakeDamage(float amount);
}

public interface IInteractable
{
    string Prompt { get; }       // interfaces can require properties too
    void Interact(GameObject who);
}

// A class can have ONE parent class but MANY interfaces
public class Barrel : MonoBehaviour, IDamageable, IInteractable
{
    public string Prompt => "Kick barrel";

    public void TakeDamage(float amount) { /* explode */ }
    public void Interact(GameObject who)  { /* roll away */ }
}

// Using them: ask for the ability, not the class
void OnTriggerEnter(Collider other)
{
    if (other.TryGetComponent(out IDamageable d)) d.TakeDamage(10f);
}

Unity uses interfaces itself: implement IPointerClickHandler on a UI object and Unity calls your OnPointerClick method.

Inheritance: "is a"MonoBehaviourEnemyGoblinExplodingSlimeinherits fromInterfaces: "can do"IDamageableBarrelCrateEnemyimplements
A class has exactly one parent, forming a tree. An interface cuts across the tree: unrelated classes can all implement IDamageable, so a sword that asks for IDamageable works on every one of them.

Abstract class or interface?

Abstract classInterface
Shares code?Yes, fields and method bodiesMostly no, just the "contract"
How many per class?OneAs many as you want
Relationship"is a" (a Bow is a Weapon)"can do" (a Barrel can be damaged)
Shows in Inspector fields?Yes ([SerializeField] Weapon w)No, not directly ([SerializeField] IDamageable d won't show)

What happens at runtime

  1. A child object contains all the fields of its parent classes. An ExplodingSlime has health even though it doesn't declare it.
  2. When you call a virtual method, C# checks the object's real type at runtime and runs the most-derived override. enemy.TakeDamage() on a slime calls the slime's Die(), even though TakeDamage is written in Enemy.
  3. Unity's messages (Update, Start) are also inherited. If the parent has a private Update and the child declares its own, only the child's runs (the parent's is hidden, not combined). Make it protected virtual and call base.Update() to run both.

Common Mistakes

See also