tags:

views:

329

answers:

5

If 'apple' is a subclass of 'fruit' , then List<apple> is a subclass of List<fruit> is this correct ?

+2  A: 

No. List<apple> and List<fruit> are not related. These both classes could have totally different implementations and there is no way to convert one into the other. For example the List<> template could be specialized in some way for apples that has a totally different structure than the general List<T> template.

And even if the implementations were compatible, it would still be a bad idea to treat a List<apple> as a List<fruit> since then people would start to put all kinds of fruits into that list that was just supposed to contain apples. See also this entry in the C++ FAQ Lite, that talks about apples and bananas...

sth
+1  A: 

The question is a bit confuse, but my first answer would be no, at least in a regular programming language. a subclassing b does not imply that any variation of a is also a subclass of that same variation of b.

Felipe Lima
+4  A: 

No! Mutable containers just don't work that way -- a fascinating aspect of OOP, actually.

Into a List<fruit> you can insert a banana -- into a List<apple>, you can't; so Liskov's Principle is violated which proves you don't have subclassing.

Immutable containers do indeed work as expected (covariance is the term of art).

Funny enough, I've never seen this fascinating law in print (akin to the fact that in the world of mutable objects you can't say a Square IS-A Rectangle... but in the world of immutable objects, you can!) -- I just came up with it on my own through experience and observation. I'd love a scholarly reference to use in this context, if anyone can pull it up, BTW;-)

Alex Martelli
+1 for pointing out "covariance" as the technical term...
Nader Shirazie
depending on the context, covariance and contravariance will be allowed in .NET 4.0 (http://msdn.microsoft.com/en-us/library/dd465120(VS.100).aspx)
Nader Shirazie
A: 

In Java, no, List<Apple> is not a subclass of List<Fruit>. They are both of type List.

Here is some Java code demonstrating that fact.

import java.util.LinkedList;
import java.util.List;

class Fruit { }

class Apple extends Fruit { }

public class Main {

    public static void main(String[] args) {
     Fruit fruit = new Fruit();
     Apple apple = new Apple();
     List<Fruit> fruitList = new LinkedList<Fruit>();
     List<Apple> appleList = new LinkedList<Apple>();

     System.out.println(fruit.getClass().getSuperclass());
     System.out.println(apple.getClass().getSuperclass());
     System.out.println(fruitList.getClass().getSuperclass());
     System.out.println(appleList.getClass().getSuperclass());
    }

}

Output:

class java.lang.Object
class Fruit
class java.util.AbstractSequentialList
class java.util.AbstractSequentialList
William Brendel
This is only true in java, which does not have proper support for generics (uses type erasure). This is not true in .NET languages, for example.
Nader Shirazie
A: 

Depends on the language - in C# 4.0 you will be able to cast IList<something> to IList<object>, but you can't do it in C# 3.0

vanja.