Zum Inhalt springen
C# Anfรคnger 30 min

Klassen & Objekte

Klassen definieren, Objekte erzeugen, Konstruktoren, Properties und Methoden. Das Fundament der Objektorientierung in C#.

Aktualisiert:
Inhaltsverzeichnis

Klassen & Objekte

Klassen sind Bauplรคne fuer Objekte. Ein Objekt ist eine konkrete Instanz einer Klasse - mit eigenen Daten und Verhalten.

Eine einfache Klasse

public class Person
{
    public string Name;
    public int Alter;

    public void Vorstellen()
    {
        Console.WriteLine($"Hallo, ich bin {Name} und {Alter} Jahre alt.");
    }
}
  • public macht die Klasse oeffentlich sichtbar
  • Name und Alter sind Felder (Daten)
  • Vorstellen ist eine Methode (Verhalten)

Ein Objekt erzeugen

var anna = new Person();
anna.Name = "Anna";
anna.Alter = 28;
anna.Vorstellen(); // "Hallo, ich bin Anna und 28 Jahre alt."

Mit Object Initializer (kuerzer):

var anna = new Person { Name = "Anna", Alter = 28 };

Properties statt Felder

Oeffentliche Felder sind unsicher - jeder kann sie beliebig aendern. Properties erlauben Kontrolle:

public class Person
{
    public string Name { get; set; }
    public int Alter { get; set; }
}

Das sind Auto-Properties - der Compiler generiert Getter und Setter fuer dich.

Nutzen wie Felder

anna.Name = "Anna"; // Setter wird aufgerufen
var n = anna.Name;  // Getter wird aufgerufen

Read-Only Properties

public string Name { get; }           // nur im Konstruktor setzbar
public string Name { get; init; }     // nur bei Initialisierung setzbar (modern)
public string Name { get; private set; } // intern setzbar, aussen read-only

init ist besonders nuetzlich:

public class Person
{
    public string Name { get; init; }
    public int Alter { get; init; }
}

var p = new Person { Name = "Anna", Alter = 28 };
// p.Name = "Max"; // FEHLER - init erlaubt es nur bei Initialisierung

Properties mit Validierung

public class Person
{
    private int _alter;

    public int Alter
    {
        get => _alter;
        set
        {
            if (value < 0)
                throw new ArgumentException("Alter kann nicht negativ sein");
            _alter = value;
        }
    }
}

value ist der uebergebene Wert im Setter.

Konstruktoren

Der Konstruktor wird beim Erstellen aufgerufen:

public class Person
{
    public string Name { get; init; }
    public int Alter { get; init; }

    public Person(string name, int alter)
    {
        Name = name;
        Alter = alter;
    }
}

var anna = new Person("Anna", 28);

Du kannst mehrere Konstruktoren haben (Overloading):

public Person() { Name = "Unbekannt"; }
public Person(string name) { Name = name; }
public Person(string name, int alter) { Name = name; Alter = alter; }

Und sie koennen sich gegenseitig aufrufen mit : this(...):

public Person() : this("Unbekannt", 0) { }
public Person(string name) : this(name, 0) { }
public Person(string name, int alter)
{
    Name = name;
    Alter = alter;
}

Private Felder und Methoden

private (Default) ist nur innerhalb der Klasse sichtbar. Nutze Konvention _feldname:

public class BankKonto
{
    private decimal _saldo;

    public decimal Saldo => _saldo; // read-only Property

    public void Einzahlen(decimal betrag)
    {
        if (betrag <= 0) throw new ArgumentException("Betrag muss positiv sein");
        _saldo += betrag;
    }

    public bool Auszahlen(decimal betrag)
    {
        if (betrag <= 0 || betrag > _saldo) return false;
        _saldo -= betrag;
        return true;
    }
}

Zugriffsmodifizierer

ModifierSichtbar
publicUeberall
privateNur in der Klasse (Default)
protectedIn Klasse + Subklassen
internalIn der gleichen Assembly
protected internalSubklassen oder gleiche Assembly
private protectedSubklassen in der gleichen Assembly

90% der Zeit reicht public und private.

this

this ist die aktuelle Instanz. Wird gebraucht, wenn Parameternamen Felder verdecken:

public class Person
{
    private string name;

    public Person(string name)
    {
        this.name = name; // this-Feld vs. Parameter
    }
}

static Members

static gehoert zur Klasse, nicht zu einem Objekt:

public class Person
{
    public static int Anzahl { get; private set; } = 0;

    public string Name { get; }

    public Person(string name)
    {
        Name = name;
        Anzahl++;
    }
}

var a = new Person("Anna");
var b = new Person("Max");
Console.WriteLine(Person.Anzahl); // 2

Aufruf ueber den Klassennamen, nicht das Objekt.

Records - kurze Datenklassen

Fuer reine Daten-Container gibt es record:

public record Person(string Name, int Alter);

Das ist ein kompletter, unveraenderlicher Datentyp mit:

  • Konstruktor
  • init-Properties
  • Einem sinnvollen ToString
  • Wertbasierter Gleichheit (a == b vergleicht Werte, nicht Referenzen)
  • with-Expression fuer Kopien mit Aenderungen
var anna = new Person("Anna", 28);
var anna29 = anna with { Alter = 29 }; // Kopie mit Aenderung
Console.WriteLine(anna);               // Person { Name = Anna, Alter = 28 }
Console.WriteLine(anna == anna29);     // False

Records sind perfekt fuer DTOs und Value Objects.

Methoden mit eigenem Status

public class Zaehler
{
    private int _count = 0;

    public void Hoch() => _count++;
    public void Runter() => _count--;
    public int Wert => _count;
}

var z = new Zaehler();
z.Hoch();
z.Hoch();
z.Runter();
Console.WriteLine(z.Wert); // 1

Zusammenfassung

  • Klassen beschreiben Daten (Felder/Properties) und Verhalten (Methoden)
  • new erzeugt Instanzen
  • Auto-Properties: public string Name { get; set; }
  • init fuer unveraenderliche Objekte
  • Konstruktoren initialisieren Objekte
  • static fuer Klassen-weite Daten und Methoden
  • record ist die kurze Form fuer Daten-Container

Im naechsten Kapitel: Vererbung und Interfaces.

Zurรผck zum C# Kurs