Философия Java


Неудобство контейнеров: неизвестный тип - часть 2


Сначала создаются классы Cat и Dog:

//: c09:Cat.java

public class Cat { private int catNumber; Cat(int i) { catNumber = i; } void print() { System.out.println("Cat #" + catNumber); } } ///:~

//: c09:Dog.java

public class Dog { private int dogNumber; Dog(int i) { dogNumber = i; } void print() { System.out.println("Dog #" + dogNumber); } } ///:~

Кошки (Cat) и собаки (Dog) помещаются в контейнер, а затем вытягиваются оттуда:

//: c09:CatsAndDogs.java

// Пример простого контейнера.

import java.util.*;

public class CatsAndDogs { public static void main(String[] args) { ArrayList cats = new ArrayList(); for(int i = 0; i < 7; i++) cats.add(new Cat(i)); // Не проблема добавить к кошкам собаку:

cats.add(new Dog(7)); for(int i = 0; i < cats.size(); i++) ((Cat)cats.get(i)).print(); // Собака обнаружится только во время выполнения

} } ///:~

Классы Cat и Dog отличаются — они не имеют ничего общего, за исключением того, что они оба - Object. (Если вы не можете точно сказать от чего унаследован класс, вы автоматически наследуете от Object.) Так как ArrayList содержит Object, вы можете поместить в контейнер не только объекты Cat с помощью метода add( ) контейнера ArrayList, но вы также можете добавить объекты Dog и при этом не получите ошибок времени компиляции, либо времени выполнения. Когда вы достаете то, о чем выдумаете как об объекте Cat с помощью метода get( ) контейнера ArrayList, вы получаете назад ссылку на объект, который вы должны привести к Cat. Затем вам необходимо взять в круглые скобки все выражение, чтобы навязать вычисление приведения до вызова метода print( ) для Cat, в противном случае вы получите синтаксическую ошибку. Затем, во время выполнения, когда вы попробуете привести объект Dog к типу Cat, вы получите исключение.

Это больше, чем просто неприятность. Это то, что может создать трудные в обнаружении ошибки. Если одна часть (или несколько частей) программы вставляют объекты в контейнер, и вы обнаруживаете только в отдельной части программы исключение, говорящее о том, что в контейнер был помещен неправильный объект, то вы должны найти, где производится неправильное вставление. С другой стороны, программирование удобно начать с каких-то стандартных контейнерных классов, несмотря на недостатки и неуклюжесть.




Начало  Назад  Вперед