Является ли Шаблон производного объекта подклассом шаблона базового типа - PullRequest
1 голос
/ 29 июня 2009

Если 'apple' является подклассом 'fruit', то List<apple> является подклассом List<fruit>, это правильно?

Ответы [ 5 ]

5 голосов
/ 29 июня 2009

Нет! Изменяемые контейнеры просто не работают таким образом - на самом деле, захватывающий аспект ООП.

В List<fruit> вы можете вставить банан - в List<apple> вы не можете; таким образом, нарушается принцип Лискова, который доказывает, что у вас нет подклассов.

Неизменяемые контейнеры действительно работают как положено (ковариантность - это термин искусства).

Достаточно забавно, я никогда не видел этот захватывающий закон в печати (сродни тому факту, что в мире изменяемых объектов вы не можете сказать Прямоугольник IS-A квадрата ... но в мир неизменных объектов, вы можете !) - я только придумал это сам благодаря опыту и наблюдению. Я хотел бы, чтобы в этом контексте использовалась научная ссылка, если кто-нибудь может это сделать, кстати; -)

2 голосов
/ 29 июня 2009

Нет. List<apple> и List<fruit> не связаны. Оба этих класса могут иметь совершенно разные реализации, и нет способа конвертировать один в другой. Например, шаблон List<> может быть в некотором роде специализирован для apple s, структура которого полностью отличается от общего шаблона List<T>.

И даже если бы реализации были совместимы, все равно было бы плохой идеей рассматривать List<apple> как List<fruit>, так как тогда люди начали бы помещать в этот список всевозможные фрукты, которые должны были содержать яблоки. , Смотрите также эту запись в C ++ FAQ Lite , в которой говорится о яблоках и бананах ...

1 голос
/ 29 июня 2009

Вопрос немного запутанный, но мой первый ответ будет нет , по крайней мере, на обычном языке программирования. Подклассы a b не означают, что любое изменение a также является подклассом этого же варианта b .

0 голосов
/ 29 июня 2009

Зависит от языка - в C # 4.0 вы сможете приводить IList<something> к IList<object>, но вы не можете сделать это в C # 3.0

0 голосов
/ 29 июня 2009

В 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...