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:
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?¶
-
Typisierung:
-
C#: Statisch typisiert (z. B.
int,string). -
Python: Dynamisch typisiert.
-
Syntax:
-
C#: Streng strukturiert mit mehr Boilerplate (z. B.
public string Name { get; set; }). -
Python: Einfacher und kompakter.
-
Methoden:
-
C#: Rückgabetyp und Schlüsselwörter wie
virtual/override. -
Python: Keine Typangaben, Methoden sind automatisch überschreibbar.
-
Konstruktoren:
-
C#: Definiert mit dem Klassennamen.
-
Python: Verwendet
__init__. -
Entry Point:
-
C#:
static void Main(string[] args). -
Python:
if __name__ == "__main__":. -
Namespaces:
-
C#: Mit
using System;. -
Python: Mit
import. -
Ausführung:
-
C#: Muss kompiliert werden.
- Python: Wird direkt interpretiert.
C# ist strenger und typisierter, Python flexibler und kompakter.
Welche Konzepte der OOP werden verwendet?¶
- Klassen und Objekte: Klassen wie
TierundHunddienen als Baupläne, Objekte wiemeinTierundmeinHundwerden daraus erstellt. - Konstruktoren: Initialisieren Objekte mit Werten.
- Vererbung:
Hunderbt vonTierund übernimmt dessen Eigenschaften und Methoden. - Polymorphismus: Die Methode
MachGeräuschwird inHundüberschrieben und zeigt je nach Objekt unterschiedliches Verhalten. - Kapselung: Eigenschaften wie
NameundAlterwerden durch Auto-Properties kontrolliert. - 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:
-
static: -
Die Methode gehört zur Klasse (
Program) und nicht zu einem Objekt. Daher kann sie direkt aufgerufen werden, ohne dass ein Objekt vonProgramerstellt werden muss. -
Dies ist notwendig, da die Anwendung starten muss, bevor Instanzen existieren.
-
void: -
Gibt an, dass die Methode keinen Rückgabewert liefert.
-
Main: -
Der Name der Methode ist festgelegt und wird von der .NET-Laufzeit beim Start der Anwendung gesucht.
-
string[] args: -
Ermöglicht den Zugriff auf Befehlszeilenargumente, die der Anwendung beim Start mitgegeben werden.
- Beispiel: Beim Start mit
dotnet run --name=testenthältargsden 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 (mitget) oder zu setzen (mitset).- 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.





