2014-09-19 4 views
0

Я просматривал свой ООП, и у меня есть небольшой вопрос об объектах. Ну, у меня есть класс супер Ship, который также является абстрактным классом. Корабль имеет некоторые подклассы, а именно: Submarine, Destroyer и так далее.Создание объекта для абстрактного класса

Я знаю, что я не могу создать объект класса Ship, потому что он абстрактный. Но почему все еще работают?

Ship s1 = new Submarine("ship 1"); 
+1

Просто потому, что вы не можете создать экземпляр абстрактного класс, не означает, что вы не можете иметь объект такого типа. Вы также можете иметь объекты определенного интерфейса, например 'List stringings = new ArrayList <>();' – Davio

+2

Потому что в этой строке вы создаете объект типа 'Submarine', а затем набрасываете его на тип' Ship'. 'Submarine' IS-A' Ship' – SimY4

+2

Прочтите этот: http://stackoverflow.com/questions/4321386/create-object-of-abstract-class-and-interface –

ответ

1

Чтобы быть простым, абстрактный класс означает, что вы не можете создать новый экземпляр этого класса.
Тем не менее, по-прежнему можно объявить объект как Ship (типа во время компиляции против выполнения типа), чтобы использовать полиморфизм, позволяет сделать некоторые смешные вещи, как массив Ship, который содержит как Submarine и Destroyer (и многие другие).

Ship[] army = new Ship[2]; 
army[0] = new Submarine("0"); 
army[1] = new Destroyer("1"); 

for(Ship s : army) { 
    s.fire(); 
} 

В этом примере, мы можем вызвать fire() на два объекта, поскольку fire() является метод Ship. Поскольку атака корабля зависит от типа корабля (подводная лодка не срабатывает, как эсминца), вы устанавливаете метод fire() в Ship и реализуете его в Submarine и Destroyer.

Эти трюки необходимы в ООП и позволяют реализовать мощные шаблоны проектирования. Если вы новичок, смотрит на strategy pattern и template method pattern, они изменили свое видение ООП несколько лет назад)

Надежда этот маленький пример поможет вам :)

2

Линия: Ship s1 = new Submarine("ship 1");

Вы не создаете объект абстрактного класса Ship, его просто ссылка, которая указывает на объект класса детского Submarine. То, что вы делаете, - это создание объекта дочернего класса.

1

Это связано с полиморфизмом.

Ссылка на родительский класс может содержать объект дочернего класса. Но используя эту ссылку, вы можете вызвать методы, которые правильно переопределены в дочернем классе.

1

Вы должны различать тип времени выполнения и тип времени компиляции.

Допустим, у вас есть следующее заявление:

Ship s1 = new Submarine("ship 1"); 
  • времени компиляции типа из s1 является типом на левой стороне даного назначения, например, тип времени компиляции - Ship. Вы можете назначить s1 любому типу, который наследует Ship.

  • Тип выполнения из s1 является правая часть оператора присваивания, например, тип исполнения s1 - это бетон исполнение Ship (в вашем случае - Submarine).

Подробнее:

+0

+1, чтобы выделить разницу между типом времени компиляции и типом времени выполнения :) – NiziL

0

Просто потому, что вы не можете создать экземпляр абстрактного класса, не означает, что вы не можете иметь объект этого типа. Вы также можете иметь объекты определенного интерфейса, например List<String> strings = new ArrayList<>()

Вы объявляете абстрактную форму метода, поскольку реализация по умолчанию не имеет смысла.

Рассмотрите класс под названием shape с подклассами circle и square. A shape указанная площадь, но circle вся дистанция рассчитывается отдельно от square.

Вы можете создать абстрактный метод, называемый getArea в абстрактном классе shape и пусть circle и square обеспечить их реализацию.

0

s1 - это корабль, и вы можете использовать все методы, определенные в вашем абстрактном классе, но только те. Если у вас есть дополнительные методы в вашем классе Submarine (например, dive, periscopeUp, ...), они не могут быть вызваны, потому что они не определены в вашем абстрактном классе Ship.

Использование этого в основном удобно для коллекций, например, теперь вы можете хранить различные типы кораблей в списке.

List<Ship> ships = new ArrayList<Ship>(); 
ships.add(new Submarine("sub 1")); 
ships.add(new Destroyer("des 1")); 

Если вы определили бы «List<Submarine> subs» вы можете хранить только подводные классы в этом списке.

Смежные вопросы