C# OOP

Erstelle eine Vector Klasse, mit der du Vektorrechnungen durchführen kannst.

Lerne anhand dieses Beispiels die Grundlagen von OOP in C#.

Despicable Me: Vector

  1. Erstelle ein neues C#-Konsolen-Programm. Nenne es z.B. MathVector

  2. Erstelle darin eine neue Klasse Vector in einem neuen File (pro Klasse ein .cs File). Klicke dazu im Projektmappen-Explorer mit rechts auf den Namen der Solution → Hinzufügen → Klasse

  3. Erstelle einen Konstruktor in der Vector-Klasse. Shortcut: ctor + TAB.

  4. Ein Vector soll dann in Program.cs mithilfe eines Double-Arrays definiert werden können: Vector v = new Vector(new double[] { 1, 2, 3 });

  5. Ein Vektor hat Eigenschaften wie seine Dimension (Anzahl Zahlen, aus dem er besteht) oder seine Länge/Magnitude. Ist v ein Vektor, so soll z.B. über v.Magnitude auf diese Eigenschaft zugegriffen werden. Informiere dich darüber, was Eigenschaften und Felder, sowie getter und setter in C# sind. Schaue dir dazu z.B. folgende Quellen an:
  6. Programmiere nun den Konstruktor aus: Speichere die dem Konstruktor übergebenen Werte in einem privaten Feld components, ein Double-Array, welches die Komponenten des Vektors beinhaltet. Regle über eine Eigenschaft (get/set) Components den Zugriff auf components. Sinn könnte machen:
    1. Die Komponenten sind unveränderbar.
    2. Die Komponenten sind nur veränderbar, wenn sie die gleiche Dimension haben (benötigt Dim von unten).

  7. Füge nun deiner Vector-Klasse die Eigenschaften Dim (für Dimension) und Magnitude. Diese sollen über eine Eigenschaft (get) abgerufen werden. Natürlich sollen sie nicht von aussen über einen setter verändert werden können!

  8. Informiere dich nun über statische und nicht-statische Methoden, z.B. hier; Methoden in Klassen

  9. Füge deiner Klasse folgende (nicht-statische) public Methoden hinzu: IsZeroVector() und IsUnitVector(). Diese geben den Bool true oder false zurück, je nachdem ob es sich beim Vektor um einen Nullvektor oder einen Einheitsvektor (unit vector) handelt.
    Achtung: Da wir mit doubles Arbeiten, können schnell Rundungsfehler entstehen. Es kann deshalb sein, dass die Länge des Vektors eigentlich $0$ wäre, der Code aber eine ganz kleine Zahl berechnet. Deshalb sollte man der Klasse eine Eigenschaft accuracy geben: Ist der Betrag des Werts kleiner dieser Genauigkeit, so wird der Wert als $0$betrachtet.

  10. Nun wollen wir mit den Vektoren Rechnen können. Dazu fügen wir drei statische Methoden mit den Namen Add, Sub und ScalarProd für die Vektoraddition, Vektorsubtraktion und das Skalarprodukt hinzu. Über Vector.Add(v1,v2); soll man dann die Vektorsumme zweier Vektoren berechnen können.

  11. Die beiden Rechenmethoden vom letzten Punkt sollen können nur Funktionieren, wenn beide Vektoren, die als Argument übergeben werden, die gleiche Dimension haben. Überprüfe dies und gib gegebenenfalls einen Fehler aus: throw new System.Exception("...");

  12. Nun wollen wir aber nicht immer Vector.Sub(v1,v2); schreiben müssen, um zwei Vektoren zu Subtrahieren. Stattdessen soll das mit dem Operator -, also v1-v2, gehen. Dies geht ganz einfach mit einem Operator Overloading, siehe z.B. hier: C# - Operator Overloading. Füge nun jeweils ein Operator Overloading für die Operatoren + (Vektoraddition), - (Vektorsubtraktion) und * (Skalarprodukt) hinzu.

  13. Aktuell gibt der Befehl System.Console.WriteLine(v); für einen Vektor v nur „Vector“ aus. Schön wäre aber, wenn man direkt die Komponenten erhalten würde: Jede Klasse in C# erbt automatisch von der Basisklasse object, und object definiert die Methode ToString(). Wenn man also Console.WriteLine(anyObject) aufrufst, wird intern anyObject.ToString() verwendet, ganz egal was anyObject für ein Objekt ist. Mit public override string ToString() können wir nun diese standardmässige Methode überschreiben.

  14. Über eine Eigenschaft soll von einem Vektor der zugehörige Einheitsvektor ausgegeben werden: v.UnitVector. Dieser Einheitsvektor soll selbst wieder vom Typ Vector sein! Um von einem Vektor den zugehörigen Einheitsvektor zu erhalten, dividiert man jede Komponente des Vektors durch die Länge des gesamten Vektors. Tipp: Überlege dir gut, wo genau der Einheitsvektor berechnet werden soll!

  15. Es ist etwas umständlich, für neue Vektoren immer zuerst ein double-Array erstellen zu müssen. Stattdessen wollen wir die gängigsten Vektoren (sagen wir 1-4D) auch durch Vector v = new Vector(3.2,0,4) erzeugen. Dafür müssen wir den Konstruktor überladen, in dem wir 'weitere Konstruktoren' wie public Vector(double x, double y, double z) hinzufügen.

  16. Erweitere nun deine Klasse beliebig. Hier einige Vorschläge:
    1. Weiter Operationen:
      1. DotProduct
      2. ScalarMultiplication (überladen, damit ScalarMultiplication(3,v) und ScalarMultiplication(v,3) funktionieren.
      3. VectorProduct (nur für 3D Vektoren)
    2. Winkel zwischen zwei Vektoren: AngleInRad , AngleInRad
    3. Zwei Vektoren vergleichen: ArePerpendicular,AreParallel,AreAntiParallel,HaveSameMagnitude

  17. Operatoren überladen: Mit v1 + v2 soll man zwei Vektoren addieren können. Der Operator + muss dazu überladen werden: Wird + auf zwei Vektoren angewendet, soll die Add-Methode aufgerufen werden. Gleiches für v1 * v2 (dot product) und s * v resp. v * s (scalar multiplication).

  18. Optional: Falls du sehr motiviert bist, könntest du eine Klasse Matrix definieren, mit der man Matrizen-Rechnungen durchführen kann. Matrizen können als Verallgemeinerungen von Vektoren betrachtet werden.
  • talit/csharp_oop.txt
  • Zuletzt geändert: 2025-05-18 13:30
  • von sca