Zum Inhalt

Block 06

Note

18.12.2024 V 1.0 Tim Langenauer

C

"Hello World!" mit C#

Wir haben C# installiert und dann einen neuen Ordner auf unserer Spielwiese hinzugefügt. Dann haben wir diesen in VSC geöffnet und folgenden Code ins Terminal eingegeben:

dotnet new console -o hello_world

bevor man dotnet run ausführen konnte musste man mit cd hello_world in den richtigen Ordner reingehen wenn man das gemacht hat kann man den code ausführen

dotnet run

dann hat sich ein Ordner erstellt mit verschiedenen Dateien, wenn man das das programm ausgeführt hat bekam man folgende Ausgabe:

Hello, World!

Datei Bedeutung
hello_world.deps.json Beschreibt Abhängigkeiten (Dependencies) des Projekts.
hello_world.dll Die eigentliche kompilierte Anwendung (Intermediate).
hello_world.exe Die ausführbare Datei für Windows (zum Starten des Programms).
hello_world.pdb Debug-Informationen (für Fehleranalyse).
hello_world.runtimeconfig.json Konfigurationsdatei für die .NET Runtime zur Ausführung.

das problem war wenn man die .exe datei dann ausführte dann öffnete sich etwas schnell schloss sich aber gleich schnell wieder deshalb muss man bei der Program.cs eine codezeile ergänzen:

Console.ReadLine();

dann natürlich ctrl s und dann konnte man die .exe datei ausführen und man bekam im Terminal die Ausgabe:

Hello World!

Zoo_CS

Note

Zoo V1 Tim Langenauer 18.12.2024 15:30

Aufgabe:

Erstellen Sie ein neues C#-Projekt "Zoo" und führen Sie den Code aus: Screenshot Projektordner und Ausgabe:

Verstehen Sie den Code Zeile für Zeile und kommentieren/dokumentieren Sie entscheidende Codeabschnitte

using System; // Importiert den System-Namespace für die Nutzung von Klassen wie Console.

class Tier
{
    // Eigenschaften der Klasse Tier
    public string Name { get; set; } // Auto-Property für den Namen des Tieres
    public int Alter { get; set; }   // Auto-Property für das Alter des Tieres

    // Konstruktor der Klasse Tier: Er wird aufgerufen, wenn ein Objekt erstellt wird.
    public Tier(string name, int alter)
    {
        Name = name;  // Setzt den Namen des Tieres
        Alter = alter; // Setzt das Alter des Tieres
    }

    // Methode, die ein Geräusch ausgibt. "virtual" bedeutet, dass diese Methode in abgeleiteten Klassen überschrieben werden kann.
    public virtual void MachGeräusch()
    {
        Console.WriteLine("Das Tier macht ein Geräusch.");
    }
}

// Abgeleitete Klasse Hund erbt von der Basisklasse Tier
class Hund : Tier
{
    // Konstruktor der Klasse Hund ruft den Konstruktor der Basisklasse Tier auf
    public Hund(string name, int alter) : base(name, alter) { }

    // Überschreibt die Methode MachGeräusch der Basisklasse Tier
    public override void MachGeräusch()
    {
        // Gibt eine spezifische Nachricht für Hunde aus
        Console.WriteLine($"{Name} bellt: Wuff Wuff!");
    }
}

class Program
{
    // Der Einstiegspunkt der Anwendung
    static void Main(string[] args)
    {
        // Erstelle ein Objekt der Klasse Tier
        Tier meinTier = new Tier("Unbekannt", 3);
        meinTier.MachGeräusch(); // Ruft die Methode MachGeräusch() der Klasse Tier auf

        // Erstelle ein Objekt der Klasse Hund
        Hund meinHund = new Hund("Bello", 5);
        meinHund.MachGeräusch(); // Ruft die überschriebene Methode MachGeräusch() der Klasse Hund auf
    }
}
Schlüsselbegriff Beispiel aus dem Code Bedeutung
Klasse class Tier, class Hund Definiert eine Vorlage für Objekte.
Eigenschaften public string Name { get; set; } Variablen der Klasse, die Werte speichern (Name, Alter).
Konstruktor public Tier(string name, int alter) Methode zur Initialisierung eines Objekts.
Vererbung class Hund : Tier Hund erbt von Tier und übernimmt dessen Eigenschaften.
virtual public virtual void MachGeräusch() Ermöglicht das Überschreiben der Methode in der Kindklasse.
override public override void MachGeräusch() Überschreibt die Basismethode mit neuem Verhalten.
Objekt Tier meinTier = new Tier("Unbekannt", 3); Eine Instanz (Kopie) einer Klasse.
Methode MachGeräusch() Eine Funktion, die in einer Klasse definiert ist.
Polymorphie meinTier.MachGeräusch() / meinHund.MachGeräusch() Verhalten von Methoden hängt von der Klasse ab.

Welche wichtigen Unterschiede zu Python können Sie erkennen?

  1. Typisierung:

  2. C#: Statisch typisiert (z. B. int, string).

  3. Python: Dynamisch typisiert.

  4. Syntax:

  5. C#: Streng strukturiert mit mehr Boilerplate (z. B. public string Name { get; set; }).

  6. Python: Einfacher und kompakter.

  7. Methoden:

  8. C#: Rückgabetyp und Schlüsselwörter wie virtual/override.

  9. Python: Keine Typangaben, Methoden sind automatisch überschreibbar.

  10. Konstruktoren:

  11. C#: Definiert mit dem Klassennamen.

  12. Python: Verwendet __init__.

  13. Entry Point:

  14. C#: static void Main(string[] args).

  15. Python: if __name__ == "__main__":.

  16. Namespaces:

  17. C#: Mit using System;.

  18. Python: Mit import.

  19. Ausführung:

  20. C#: Muss kompiliert werden.

  21. Python: Wird direkt interpretiert.

C# ist strenger und typisierter, Python flexibler und kompakter.

Welche Konzepte der OOP werden verwendet?

  1. Klassen und Objekte: Klassen wie Tier und Hund dienen als Baupläne, Objekte wie meinTier und meinHund werden daraus erstellt.
  2. Konstruktoren: Initialisieren Objekte mit Werten.
  3. Vererbung: Hund erbt von Tier und übernimmt dessen Eigenschaften und Methoden.
  4. Polymorphismus: Die Methode MachGeräusch wird in Hund überschrieben und zeigt je nach Objekt unterschiedliches Verhalten.
  5. Kapselung: Eigenschaften wie Name und Alter werden durch Auto-Properties kontrolliert.
  6. Dynamische Bindung: Zur Laufzeit wird die passende Methode aufgerufen.

Kurz: Der Code zeigt Klassen/Objekte, Konstruktoren, Vererbung, Polymorphismus, Kapselung und dynamische Bindung.

Wozu `static void Main(string[] args)

Die Methode static void Main(string[] args) ist der Einstiegspunkt für jede C#-Anwendung. Hier eine kurze Erklärung ihrer Bestandteile:

  1. static:

  2. Die Methode gehört zur Klasse (Program) und nicht zu einem Objekt. Daher kann sie direkt aufgerufen werden, ohne dass ein Objekt von Program erstellt werden muss.

  3. Dies ist notwendig, da die Anwendung starten muss, bevor Instanzen existieren.

  4. void:

  5. Gibt an, dass die Methode keinen Rückgabewert liefert.

  6. Main:

  7. Der Name der Methode ist festgelegt und wird von der .NET-Laufzeit beim Start der Anwendung gesucht.

  8. string[] args:

  9. Ermöglicht den Zugriff auf Befehlszeilenargumente, die der Anwendung beim Start mitgegeben werden.

  10. Beispiel: Beim Start mit dotnet run --name=test enthält args den Wert ["--name=test"].

Zusammenfassung:
Main ist der Startpunkt der Anwendung. Sie ist static, damit sie ohne Objektaufruf ausgeführt werden kann, und nutzt args, um Befehlszeilenargumente zu empfangen.

Aspekt C# Python
Klassen & Vererbung class Hund : Tier class Hund(Tier):
Konstruktoren public Tier(string name, int alter) def __init__(self, name, alter):
Eigenschaften Auto-Properties: { get; set; } Direkt: self.name = name
Methodenüberschreibung virtual in Basisklasse, override in abgeleiteter Klasse Direktes Überschreiben
Zugriffsmodifikatoren public, private, protected Keine Modifikatoren, Konventionen
Ausgabe Console.WriteLine print()
String-Interpolation $"{Name} bellt" f"{name} bellt"

Note

Zoo V2 Tim Langenauer 18.12.2024 16:00

Zoo V2 Oop

in der program.cs datei ist dieser Code

using System; // Importiert den System-Namespace, um Funktionen wie Console.WriteLine zu verwenden.

class Program
{
    // Der Einstiegspunkt der Anwendung.
    static void Main(string[] args)
    {
        // Erstellt ein Objekt der Basisklasse Tier mit Name "Unbekannt" und Alter 3.
        Tier meinTier = new Tier("Unbekannt", 3);
        meinTier.MachGeräusch(); // Ruft die Methode MachGeräusch der Klasse Tier auf.

        // Erstellt ein Objekt der abgeleiteten Klasse Hund mit Name "Bello" und Alter 5.
        Hund meinHund = new Hund("Bello", 5);
        meinHund.MachGeräusch(); // Ruft die überschreibende Methode MachGeräusch der Klasse Hund auf.

        // Zusätzliche Ausgaben mit Eigenschaften und Methoden der Objekte.
        Console.WriteLine($"Das Tier {meinTier.Name} ist {meinTier.Alter} Jahre alt."); // Zeigt Name und Alter des Tieres.
        Console.WriteLine($"Der Hund {meinHund.Name} ist {meinHund.Alter} Jahre alt und macht folgendes Geräusch:");
        meinHund.MachGeräusch(); // Ruft erneut die spezifische Geräuschmethode des Hundes auf.
    }
}

in hund.cs datei dieser:

using System; // Importiert den System-Namespace, um Funktionen wie Console.WriteLine zu verwenden.

// Die Klasse Hund erbt von der Basisklasse Tier.
class Hund : Tier
{
    // Konstruktor: Initialisiert ein neues Hund-Objekt mit einem Namen und Alter.
    // Der Basiskonstruktor der Klasse Tier wird mit `base(name, alter)` aufgerufen.
    public Hund(string name, int alter) : base(name, alter) { }

    // Überschriebene Methode: Definiert ein spezifisches Geräusch für Hunde.
    // `override` gibt an, dass diese Methode die virtuelle Methode aus der Basisklasse Tier überschreibt.
    public override void MachGeräusch()
    {
        Console.WriteLine($"{Name} bellt: Wuff Wuff!"); // Gibt das Bellen des Hundes aus.
    }
}

in Tier.cs datei dieser:

using System; // Importiert den System-Namespace, um Funktionen wie Console.WriteLine zu verwenden.

class Tier
{
    // Eigenschaften: Die Eigenschaften Name und Alter speichern den Namen und das Alter des Tieres.
    public string Name { get; set; } // Auto-Property für den Namen des Tieres.
    public int Alter { get; set; }   // Auto-Property für das Alter des Tieres.

    // Konstruktor: Initialisiert ein neues Tier-Objekt mit einem Namen und Alter.
    public Tier(string name, int alter)
    {
        Name = name;  // Setzt den Namen des Tieres.
        Alter = alter; // Setzt das Alter des Tieres.
    }

    // Virtuelle Methode: Kann in abgeleiteten Klassen überschrieben werden, um spezifische Geräusche für verschiedene Tiere zu implementieren.
    public virtual void MachGeräusch()
    {
        Console.WriteLine("Das Tier macht ein Geräusch."); // Standardausgabe für ein Tiergeräusch.
    }
}

Zusammenfassung

  • Wenn sich alle Dateien auf der Hauptebene befinden, brauchst du keinen Namespace oder spezielle using-Anweisungen.
  • Die Klassen werden direkt erkannt, da der Compiler alle Dateien in derselben Ebene automatisch einbindet.

Dies funktioniert gut für einfache Projekte. Bei größeren Projekten ist es jedoch ratsam, eine saubere Ordnerstruktur und Namespaces einzuführen.

Ich habe den Code von Ki noch kommentieren lassen, wie man oben sehen kann.

Man muss dann in der Program.cs -Datei das Programm ausführen und dann erhält man im Terminal folgende Ausgabe:

Leitfrage: Wieso werden in Console.WriteLine($"{Name} [..] bellt: Wuff Wuff!"); die Variablennamen gross geschrieben? Erklären und verstehen Sie die Zusammenhänge!

Ergänzen Sie das Programm so, dass folgende Ausgaben entstehen:

Man muss nur bei Hund.cs und Tier.cs etwas anpassen:

neuer Code bei Tier.cs:

using System;

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

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

    public virtual void MachGeräusch()
    {
        Console.WriteLine($"Das Tier heisst Unbekannt, ist {Alter} jahre alt und macht ein Geräusch.");
    }
}

mann musste nur Output anpassen beim Console:WriteLine Befehl.

neuer Code bei Hund.cs :

using System;

class Hund : Tier
{
    public Hund(string name, int alter) : base(name, alter) { }

    public override void MachGeräusch()
    {
        Console.WriteLine($"{Name} ist {Alter} und bellt: Wuff Wuff!");
    }
}

Hier musste ich auch bei Console.WriteLine etwas anpassen, aber einen Teil hatte die KI bereits übernommen als ich es zu Oop umgewandelt habe


In C# wird bei Name und Alter in den geschweiften Klammern (also in der Klasse) groß geschrieben, weil es sich um Eigenschaften handelt.

  • **get** und **set** sind dafür verantwortlich, den Wert der Eigenschaft zu lesen (mit get) oder zu setzen (mit set).
  • Diese Eigenschaften werden in der Klasse definiert, um den Zugriff auf private Felder zu kapseln und den Code sauber und sicher zu halten.

Die Methode **MachGeräusch** gibt dann den Wert der Eigenschaften (z. B. Name und Alter) aus, um das Tier korrekt zu beschreiben. In C# ist es üblich, Eigenschaften mit einem großen Anfangsbuchstaben zu benennen, um sie von lokalen Variablen (die klein anfangen) zu unterscheiden.

PyCharm