May 2009

C# kann keine Kovarianz

Wenn man objekt-orientiert programmiert, dann ist Vererbung ein gutes Mittel um ein Objekt wie eines der Oberklasse erscheinen zu lassen und dabei aber trotzdem noch zusaetliche Funktionalitaet einzubauen.

In diesem simplen Beispiel gibt es Vehikel und ein ganz besonderer Vehikel ist z.B. ein Auto. Wenn eine Fabrik nun Autos produziert, so ist natuerlich logisch, dass diese Fabrik damit implizit auch Vehikel produziert. Auf OOP angewendet heisst das, dass man bei einer ueberschriebenen Methode den Typ noch genauer spezifieren kann als in der gleichen Methode der Oberklasse. Das bringt keinerlei Probleme mit sich und kann im Zweifelsfall einen Typ-Cast vermeiden.

In C# sehe das Beispiel so aus:

class Vehicle {    }
class Car : Vehicle { }
 
class VehicleFactory {
    public virtual Vehicle Produce() {
        return new Vehicle();
    }
}
 
class CarFactory : VehicleFactory {
    public override Car Produce() {
        return new Car();
    }
}
 
class Program {
    static void Main(string[] args) {
        VehicleFactory vf = new CarFactory();
        Vehicle vehicle = vf.Produce();
        // do something with the vehicle
        CarFactory cf = new CarFactory();
        Car car = cf.Produce();
        // do something with the car
    }
}

Leider hat die aktuelle Version von C# keine Unterstueztung fuer diese Art der Kovarianz und somit kompiliert dieser Code nicht. Gluecklicherweise ist es in C# 4.0 geplant

In Java wiederum sehe das Beispiel so aus:

public class Program {
 
    class Vehicle {  }
    class Car extends Vehicle {}
 
    class VehicleFactory {
        public Vehicle produce() {
            return new Vehicle();
        }
    }
 
    class CarFactory extends VehicleFactory {
        public Car produce() {
            return new Car();
        }
    }
 
    public Program() {
        VehicleFactory vf = new CarFactory();
        Vehicle vehicle = vf.produce();
        // do something with the vehicle
        CarFactory cf = new CarFactory();
        Car car = cf.produce();
        // do something with the car
    }
 
    public static void main(String[] args) {
        new Program();
    }
}

...und laesst sich problemlos kompilieren und ausführen!

(originally posted 2009-05-27)