← SEARCHABLE ARCHIVE
C# · 2026-07-25

C# von den Grundlagen bis zum Profi — Folge 4

Aufteilung der Rollen in Vererbung, Schnittstellen und Generika

INTERACTIVE READING MODE →

Die in diesem Blog verfassten Artikel wurden mit dem Ziel erstellt, zu unterrichten. Außerdem können die Informationen im Artikel falsch sein, also seien Sie bitte vorsichtig.

Vererbung und Schnittstellen können verwendet werden, wenn mehrere Klassen dasselbe Verhalten bereitstellen müssen. Welche Art von Vertrag nach außen präsentiert wird, ist wichtiger als die Gemeinsamkeit.

Rollen durch Schnittstellen ausdrücken

public interface IDamageable
{
    bool IsAlive { get; }
    void TakeDamage(int amount);
}

public sealed class Monster : IDamageable
{
    public int Health { get; private set; } = 100;
    public bool IsAlive => Health > 0;

    public void TakeDamage(int amount)
    {
        Health = Math.Max(0, Health - amount);
    }
}

Für den Angriffscode müssen Sie nur IDamageable kennen, nicht das gesamte Monster. Sie können denselben Code später verwenden, um Trainingsvogelscheuchen oder zerstörbare Kisten hinzuzufügen.

Vererbung wird in is-a-Beziehungen verwendet

public abstract class Skill
{
    public string Name { get; }

    protected Skill(string name) => Name = name;
    public abstract void Execute(IDamageable target);
}

public sealed class FireSkill : Skill
{
    public FireSkill() : base("Fire") { }

    public override void Execute(IDamageable target)
    {
        target.TakeDamage(30);
    }
}

Durch die Vererbung werden auch der Status und die Regeln der Basisklasse geerbt. Wenn Sie eine tiefe Vererbungsstruktur erstellen, nur um einige Codezeilen wiederzuverwenden, wirken sich Änderungen am übergeordneten Element auf alle untergeordneten Elemente aus.

Aufrechterhaltung der Typensicherheit bei Generika

public sealed class Registry<T> where T : class
{
    private readonly Dictionary<int, T> values = new();

    public void Add(int id, T value) => values.Add(id, value);

    public T? Find(int id)
    {
        return values.TryGetValue(id, out T? value) ? value : null;
    }
}

Registry<Monster> und Registry<Skill> verwenden dieselben Speicherregeln, ihre Werte können jedoch nicht gemischt werden. Die Einschränkung where teilt dem Compiler mit, welche Eigenschaften T bereitstellen muss.

Schnittstellen drücken Rollen aus, Vererbung drückt eine gemeinsame Basis aus und Generika drücken dieselben Regeln für verschiedene Typen aus. Anstatt viele der drei Funktionen gleichzeitig zu verwenden, ist es sicherer, zuerst den kleinsten Vertrag zu erstellen und ihn bei Bedarf zu erweitern.