Polymorphism means "many shapes" — the same method call behaves differently depending on the actual type of the object.
public class Shape
{
public virtual double Area() => 0;
public override string ToString() => $"{GetType().Name}: area={Area():F2}";
}
public class Rectangle : Shape
{
public Rectangle(double w, double h) { Width = w; Height = h; }
public double Width { get; }
public double Height { get; }
public override double Area() => Width * Height;
}
public class Circle : Shape
{
public Circle(double r) => Radius = r;
public double Radius { get; }
public override double Area() => Math.PI * Radius * Radius;
}
Shape[] shapes = { new Rectangle(5, 3), new Circle(4) };
foreach (var s in shapes)
Console.WriteLine(s); // calls the correct Area()
// Rectangle: area=15.00
// Circle: area=50.27
Shape s = new Circle(3);
if (s is Circle c)
Console.WriteLine($"Radius: {c.Radius}"); // pattern matching
var r = s as Rectangle;
Console.WriteLine(r is null ? "Not a Rectangle" : r.Width.ToString());
public class Base { public string Name => "Base"; }
public class Child : Base { public new string Name => "Child"; }
Base obj = new Child();
Console.WriteLine(obj.Name); // "Base" — hiding, not overriding!