2009-06-29 128 views

回答

2

List<apple>List<fruit>是无关的。这两个类可能有完全不同的实现,并且没有办法将一个转换为另一个。例如,List<>模板可能会以某种方式专门用于apple,它与一般的List<T>模板具有完全不同的结构。

而且即使实现了兼容,它仍然是一个坏主意,治疗List<apple>作为List<fruit>从此人们就开始把各种水果到刚应该包含苹果该列表。另见本entry in the C++ FAQ Lite,大约苹果和香蕉的会谈......

1

的问题是有点迷惑,但我的第一个答案将是没有,至少在一个普通的编程语言。 一个子类b并不暗示的一个任何变化也是b相同变异的子类。

5

不! Mutable容器就是不以这种方式工作 - 实际上是OOP的一个迷人的方面。

进入List<fruit>你可以插入一个香蕉 - 到List<apple>,你不能;所以Liskov的原则被违反了,证明你没有继承。

不可变容器确实按预期工作(协方差是艺术术语)。

有趣的是,我从来没有见过这个引人入胜的法则(类似于可变的对象的事实,你不能说一个方形的IS-A矩形......但在世界上不可改变对象,你可以!) - 我只是通过自己的经验和观察来想出它。我很喜欢学术上的参考,如果任何人都可以把它拉起来,BTW ;-)

+0

+1指出“协方差”作为技术术语...... – 2009-06-29 05:53:30

+0

根据上下文,协方差和逆变将被允许在.NET 4.0中(http://msdn.microsoft.com/en-us/library/dd465120(VS.100) ).aspx) – 2009-06-29 05:56:10

0

在Java中,不,List<Apple>不是List<Fruit>的子类。他们都是List类型。

这里有一些Java代码展示了这个事实。

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()); 
    } 

} 

输出:

class java.lang.Object 
class Fruit 
class java.util.AbstractSequentialList 
class java.util.AbstractSequentialList 
0

取决于语言 - 在C#4.0,你将能够投IList<something>IList<object>,但你不能做它在C#3.0