Страницы

Поиск по вопросам

пятница, 7 декабря 2018 г.

Вопрос про абстракцию и полиморфизм в java

Загвоздка такова: по отдельности я более-менее понимаю, о чем эти 2 парадигмы:
Абстрактный класс с методами - своего рода шаблон,который наследуют другие классы. Объект такого класса нет смысла создавать, т.к. он абстрактен, но наследники могут использовать его методы и переопределять их. Полиморфизм - это возможность использовать метод с одним именем в разных классах, но по-разному его реализовывать, переопределяя. Также понимаю,что в принципе одну систему можно построить как на базе абстрактного класса,так и используя полиморфизм.
Но что использовать лучше и чем они отличаются - я не понимаю, не хватает совсем немного,чтобы додумать. Поясните, пожалуйста, что и как, если можно на примерах. Заранее большое спасибо.


Ответ

Это тесносвязанные базовые понятия ООП, они дополняют друг друга. Поэтому нельзя говорить "что использовать лучше". Как вы написали,
абстрактный класс с методами своего рода шаблон,который наследуют другие классы
Так вот, вы задаете определенный шаблон для дальнейшей реализации полиморфизма. Когда от этого абстрактного класса у вас будут 2 или более наследника, реализующие абстрактные методы. Это и будет полиморфизм. Также, часто помогает осознать что это сама расшифровка слова. "поли" - означает много, "морфа" - форма. Полиморфизм - много форм. Есть одна абстракция, и есть много реальных форм этой абстракции. Ещё стоит помнить, что полиморфизм в ООП не ограничивается этим, перегрузка методов - также является полиморфизмом: много форм у одного метода.
Ещё раз, не разделяйте понятия ООП и не пытайтесь выбрать "что лучше" - все базовые принципы ООП - костяк, и только используя все кости сразу вы добьетесь красивого результата (конечно, меру знать нужно, так что злоупотреблять не стоит).
UPD. касательно вашего комментария:
если мы имеем супер-класс,но не абстрактный и наследуем от него другие классы,использующие его метод. можно ведь при этом делать супер-класс не абстрактным. например класс "фигура" и классы-наследники "квадрат", "круг".все будут иметь метод "рисовать".
abstract public class Shape { int Color; Coordinates StartPoint; abstract public void Draw(); }
class Point extends Shape { public void draw() { // Здесь рисуется точка } }
class Circle extends Shape { public void draw() { // Здесь рисуется круг } }
class Square extends Shape { public void draw() { // Здесь рисуется квадрат } }
Если суперкласс будет неабстрактным в данной ситуации, то либо придется писать реализацию draw() для класса Shape, которую не особо понятно как делать, либо же вообще Shape не будет ничего знать про метод draw() и тогда не получится сделать то, что описано ниже.
Зачем все это вообще нужно? Потому что когда-нибудь у вас будет много разных фигур, например, в массиве:
List shapes = shapes(); // Получим откуда-то его. shapes.forEach(Shape::draw);
И всё, мы отрисовали все квадраты, круги, точки. И для каждой фигуры вызвался свой метод draw.
Это так же ответ на вопрос:
а зачем нам выделять из нескольких классов общие черты и плодить еще один дополнительный класс?

Комментариев нет:

Отправить комментарий