// Exercise 1: virtual dispatch vs method hiding // // Implement the Shape hierarchy so that: // - Shape.Describe() is NOT overridden anywhere, but calling it through // any subtype must report the CORRECT overridden Area() (polymorphism). // - Square.Area() properly overrides Shape.Area() using `virtual`/`override`. // - Triangle.Area() uses `new` to HIDE Shape.Area() instead of overriding it // (this is deliberately here to demonstrate the difference in the self-check). using System; class Shape { public virtual double Area() => 0; public string Describe() => $"Area = {Area()}"; } class Square : Shape { public double Side { get; init; } // TODO: override Area() to return Side * Side } class Triangle : Shape { public double Base { get; init; } public double Height { get; init; } // TODO: use `new` (member hiding, NOT override) to define Area() as // 0.5 * Base * Height. This intentionally breaks polymorphism — // the self-check demonstrates why. } class Program { static void Main() { int pass = 0, total = 0; Shape sq = new Square { Side = 4 }; total++; if (sq.Describe() == "Area = 16") { Console.WriteLine("PASS: Square overrides correctly"); pass++; } else Console.WriteLine("FAIL: Square overrides correctly, got " + sq.Describe()); // Triangle.Area() hides rather than overrides, so calling through // a Shape-typed reference should still hit Shape.Area() (= 0), // even though Triangle "has its own" Area(). Shape tri = new Triangle { Base = 6, Height = 2 }; total++; if (tri.Describe() == "Area = 0") { Console.WriteLine("PASS: Triangle's `new` hides, base reference sees Shape.Area()"); pass++; } else Console.WriteLine("FAIL: Triangle's `new` hides, base reference sees Shape.Area(), got " + tri.Describe()); // But calling Area() through the CONCRETE Triangle type should see // Triangle's own hidden method. var triConcrete = new Triangle { Base = 6, Height = 2 }; total++; if (triConcrete.Area() == 6) { Console.WriteLine("PASS: concrete Triangle reference sees Triangle.Area()"); pass++; } else Console.WriteLine("FAIL: concrete Triangle reference sees Triangle.Area(), got " + triConcrete.Area()); Console.WriteLine($"--- {pass}/{total} checks passed ---"); } }