2013-08-23 1 views
0

Я учусь Java и было интересно, в какой ситуации вы хотели бы расширить класс, как здесь предлагается:В какой ситуации мне нужно расширить класс?

http://5upcodes.blogspot.fi/2013/08/java-inheritance.html

Спасибо!

+3

Я бы не назвал это учебником. На самом деле, я бы даже не сказал, что это большой пример ... – KidTempo

+2

Прочтите [FAQ]. И отвечать: обычно на тихом рабочем месте, с коллегами, ничего необычного. – ppeterka

+0

Я знаю, что этот вопрос по теме ... Но я чувствую, что вы можете получить более интересные ответы либо в [Programmers] (http://programmers.stackexchange.com), либо в [Computer Science] (http: //cs.stackexchange. ком). Оба являются сестринскими сайтами Stack Overflow. – Renan

ответ

-1

Практически никогда. Лучше всего только расширить классы, которые были активно разработаны для него. Большинство разработчиков классов не думают о том, что произойдет, если люди расширят свои классы. Есть всевозможные проблемы.

Композиция - ваш лучший друг.

Уязвимость включает

  • вы больше не можете правильно реализовать Equals() или хэш-код() в подклассах
  • вы нарушаете инкапсуляцию, и теперь полагается на внутренностях другого класса
  • вы уязвимы к изменениям в родительском классе
  • вы обязаны принимать любые новые методы, которые добавляются в родительский класс
  • вы должны беспокоиться о замене Лискова Pri nciple, что может привести к тонким ошибкам

Джош Блох в своей замечательной книге Эффективное Java, второе издание, говорит об этом в нескольких местах, в том числе пункты 8, 16 и 17.

+1

Это звучит так же, как «Мне не нравятся гаечные ключи allen, поэтому давайте клянемся, чтобы никогда не использовать гаечные ключи». – Renan

+3

Плохой ответ. Наследование существует не просто так. – Mehrdad

+0

Это радикальный ответ, но у меня есть точка: избегайте наследования, если интерфейс решит ваши проблемы. Наследование повышает сложность и может быстро запутаться. – Fernando

4

Когда вы хотите создайте класс, который обычно похож на суперкласс (расширяемый класс), вы расширяете его и настраиваете его. Переписывание некоторых из его функций и/или добавление функций.

2

Это сценарий «есть-a», один из трех столпов ООП (наследование, инкапсуляция, полиморфизм). Если у вас есть класс Animal, вам может понадобиться расширить класс Dog от Animal. Собака - это животное, но не наоборот. У всех животных есть клетки, но у собак есть другие особенности. Это было бы довольно простой идеей.

1

Расширение класса является одним из основополагающих принципов ООП, а также интерфейсов. Допустим, у вас есть общий класс под названием Building. У этого есть члены, такие как район, город, где здание (или координаты) и т. Д.

Теперь, с расширением, вы можете указать дом «Коттедж», «SkyScraper» и т. Д. Они будут иметь функциональность parent + something more (например, количество уровней для SkyScaraper).

-1

Существует три основных недостатка с наследованием. Несмотря на то, что отношения являются отношениями «есть», рассмотрите эти три, решив наследовать класс.

  1. Частичное наследование невозможно. Вы не можете распространяться частично.
  2. Статически связан. Наследование является статическим. Вы не можете изменить эти отношения во время выполнения.
  3. Вы не можете ограничить поведение путем наследования. (Это возможно в C++ через личное наследование. Но не в java)
+0

Думаю, при рассмотрении причины наследования придется учитывать и свои недостатки. – Prem

+0

Да, но вопрос был * why *, и вы ответили *, вы будете страдать, если будете использовать это *. Вряд ли ответ вообще. – Renan

+0

@ Renan. Значит, вы хотите сказать, что нет необходимости рассматривать вопрос о том, есть ли какие-либо проблемы, если он решит продлить один класс? Я сильно чувствую, что если я напишу класс Properties и не буду расширять класс Properties из Hashtable, если бы я подумал о том, «кто будет страдать, если я продлю свойства из Hashtable» – Prem

0

При продлении класса у вас есть отношение родитель-потомок между исходным и новым, расширяющимся.

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

Вы расширяете класс, когда хотите, чтобы новый класс имел все те же функции оригинала и что-то еще. Тогда дочерний класс может либо добавить новые функции, либо переопределить некоторые функциональные возможности родительского класса.

Вы также можете использовать расширение, если хотите иметь набор классов, которые связаны друг с другом и имеют общие функции, но с другой реализацией, когда дело доходит до деталей. Например, обычно для графических интерфейсов вы имеете класс Control, который имеет функции, связанные с рендерингом и позиционированием. Затем у вас есть дети по имени Button, Textbox, Combo и т. Д. Все они имеют общую реализацию, но каждая из них различна в своих деталях.

Обязательно изучите интерфейсы. Иногда вам нужно много связанных классов, чтобы они имели общий набор участников, но не имели общих функций. В подобных случаях лучше реализовать интерфейс, чем расширять общий класс. Интерфейс подобен классу, но без реализации в нем (он служит только для того, чтобы сообщить вам, какие члены должны иметь его разработчики).

0

Обычно расширение класса - это то, что вы создаете класс на основе чего-то. Например, чтобы создать действие, вы должны продлить действие. Если ваш класс должен настроить IntentService, то вы должны расширить свой класс для использования IntentService.

public class AClassNameHere extends Activity implements OnClickListener { 

public class ClassName extends IntentService{ 
0

Вы можете продлить суперкласс Переопределить метод суперкласса быть специфическими для подклассов Например:

В случае, если ваш суперкласс общий класс с общим поведением, например, класс животных может быть общий класс как

class Animal{ 
private String name; 
public String getVoice(){ 
return "Animal"; 
} 

}

Теперь вам нужно создать сказать класс Cat, который имеет тип животных, но с разной В.О. лед, то вы просто расширить суперкласса животное и просто переопределить метод getVoice() как

class Cat extends Animal{ 

public String getVoice(){ 
return "mew"; 
} 
} 

Теперь, если у вас есть такой код: животных кошки = новый Cat(); cat.getVoice(); // он вернет «mew»

Практически это можно использовать в ряде ситуаций, таких как 1. Расширение существующего класса фреймов в вашем пользовательском классе. 2. Если вы разрабатываете какую-либо фреймворк, вы можете открыть некоторые классы, которые вы хотите настроить пользователем.

Но переопределение представляет отношения IS-A.

1

Хорошая практика ООП заключается в program towards interfaces. Но в некоторых случаях вы можете воспользоваться использованием наследования: например, когда ваш верхний класс имеет четко определенное поведение (я имею в виду конкретный код), который наследует все дочерние классы - это уменьшает код, сложность и улучшает обслуживание сценарий.

С другой стороны, если ваша модель слишком абстрактна (основное поведение не очень ясное), вы должны подумать об использовании интерфейсов.

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

1

Основной причиной использования наследования является расширение поведения базового класса.

Например, если вы делаете видеоигру, у вас может быть класс Character, содержащий весь код, необходимый для того, чтобы персонаж мог перемещаться по миру и делать все, что он делает.

Вы могли бы расширить Character с Player и NPC, так что Player (представляющий характер игрока) содержит логику, которая позволяет человеку играть в игру, чтобы контролировать свой характер, и NPC (представляющий Неигрока-Character) содержит логика, позволяющая компьютеру управлять другими символами. Таким образом, все логическое ядро ​​для каждого символа инкапсулируется в класс Character, а подклассы имеют только логику, необходимую для расширения определенного поведения.

Например, класс Character может иметь способ передвижения.

protected void MoveToLocation(x, y) 
{ 
//movement logic goes here 
} 

И тогда Player класс может содержать MouseListener, чтобы переместить игрока туда, где нажата.

public void mouseClicked (MouseEvent mouseEvent) 
{ 
    MoveToLocation(mouseEvent.getX(), mouseEvent.getY()); 
} 

И NPC будет понять это само по себе как-то

protected void decideWhereToGo() 
{ 
    int destinationX, destinationY; 
    //logic for determining destination 
    MoveToLocation(destinationX, destinationY); 
} 

Поскольку оба они наследуют от Character они оба знают, как MoveToLocation, и если вы хотите изменить, как это будет сделано, вы только необходимо изменить код в одном месте и каждые Character (независимо от того, являются ли они Player или NPC, они все еще являются Character путем наследования) будут иметь обновленное поведение.

3

Моим любимым примером наследования является пример фигур. Все квадраты - это формы, но не все формы - квадраты.

Предположим, у вас есть класс под названием «форма». Все формы имеют периметр, область и т. Д. Это будут члены данных вашего класса фигур.

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

Класс круга будет называться «наследовать» из класса формы, поскольку он имеет все особенности фигуры, а также новые функции, характерные только для класса круга.

2

По простой причине мы продляем один класс два другого, и фонд называется НАСЛЕДОВАНИЕМ.

Скажите, если вы хотите создать программу, в которой есть два класса автомобилей i.e.- Car and Boat, которые имеют схожие свойства, кроме некоторых.

public class Vehicle 
{ 
    void engine() 
} 

protected class Car extends Vehicle 
{ 
void tyres() 
} 

protected class Boat extends Vehicle 
{ 
void propeller() 
} 

Вы видите, как транспортное средство имеет двигатель, но имеет различные режимы, как один движется с помощью шин, а другой с пропеллером.

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