// Shapes example, C# version using System; abstract class shape { protected int x, y; public virtual double distance(shape other) { int dx = x-other.x, dy = y-other.y; return Math.Sqrt(dx*dx + dy*dy); } public abstract double area(); //abstract methods are already "virtual" public abstract double circumference(); }//shape class circle : shape {// inheritance is public by default double radius; // this is private by default. public circle(int a, int b, int r) {x=a;y=b;radius=r;} public override double area() {return Math.PI*radius*radius;} public override double circumference() {return Math.PI*radius*2;} public double get_radius() { return radius; } }//circle class rectangle : shape { double width, height; public rectangle(int a, int b, double w, double h) { x=a; y=b; width=w; height=h; } public override double area() { return width*height; } public override double circumference() { return width*2 + height*2; } }//rectangle // ... triangle, etc public class shapes { public static void Main() { shape[] S = new shape[4]; S[0] = new circle(3,4,5); S[1] = new circle(50,60,10); S[2] = new rectangle(3,4,5,6); S[3] = new rectangle(30,40,50,60); double totalarea = 0; foreach(var c in S) totalarea+=c.area(); //dynamic dispatch Console.WriteLine("total area is "+totalarea); // Now for a weakness of OOP, in any langauge: COMPROMISE // ON STATIC TYPE SAFETY. shape s = new circle(3,4,5); //valid, a circle "is a" shape double r = ((circle)s).get_radius(); // type casting is required because the compiler only knows that // s is a shape, not a circle. But if this cast is allowed, then.. s = new rectangle(5,6,7,8); //s can point to a rectangle too r = ((circle)s).get_radius(); // THIS ALSO COMPILES. // It compiled for the same reason that the previous cast compiled. // In C# (and Java), this results in a runtime type casting error. // This kind of type casting is not just a compile-time notion, it // results in type-checking at runtime, with dynamic type information. // In C++, this kind of type casting is equivalent to // dynamic_cast(s). }//main }