Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why doesn't inheritance work the way I think it should work?

I'm having some inheritance issues as I've got a group of inter-related abstract classes that need to all be overridden together to create a client implementation. Ideally I would like to do something like the following:

abstract class Animal
{
  public Leg GetLeg() {...}
}

abstract class Leg { }

class Dog : Animal
{
  public override DogLeg Leg() {...}
}

class DogLeg : Leg { }

This would allow anyone using the Dog class to automatically get DogLegs and anyone using the Animal class to get Legs. The problem is that the overridden function has to have the same type as the base class so this will not compile. I don't see why it shouldn't though, since DogLeg is implicitly castable to Leg. I know there are plenty of ways around this, but I'm more curious why this isn't possible/implemented in C#.

EDIT: I modified this somewhat, since I'm actually using properties instead of functions in my code.

EDIT: I changed it back to functions, because the answer only applies to that situation (covariance on the value parameter of a property's set function shouldn't work). Sorry for the fluctuations! I realize it makes a lot of the answers seem irrelevant.

like image 210
Luke Avatar asked Sep 05 '08 21:09

Luke


2 Answers

The short answer is that GetLeg is invariant in its return type. The long answer can be found here: Covariance and contravariance

I'd like to add that while inheritance is usually the first abstraction tool that most developers pull out of their toolbox, it is almost always possible to use composition instead. Composition is slightly more work for the API developer, but makes the API more useful for its consumers.

like image 130
Apocalisp Avatar answered Sep 22 '22 04:09

Apocalisp


Clearly, you'll need a cast if you're operating on a broken DogLeg.

like image 45
vextasy Avatar answered Sep 23 '22 04:09

vextasy