Почему вы расширяете класс, а не просто добавляете новый метод в исходный класс?
Наконец-то у меня был момент Ах-ха, когда дело дошло до занятий по ООП. Я изо всех сил пытался осмыслить эту идею. Теперь, когда я начинаю понимать это, мне стало интересно, какова цель расширения класса. Не было бы проще просто добавить другой метод в класс или я просто упускаю суть?
3 answers
Если вы хотите добавить функциональность в класс, вы добавляете метод. Однако бывают ситуации, когда вы хотите добавить функциональность, но не можете сделать это в базовом классе.
Лучше всего показать на примере. При добавлении метода Radius
в класс имеет смысл только в том случае, если класс является Circle
, Rect
не имеет радиуса. Добавление метода Radius
в базовый класс также не имеет смысла, потому что класс Rect
также получает метод Radius
.
Пример:
abstract class Shape
{
abstract public function Draw();
}
class Rect extends Shape
{
public function Draw()
{
}
}
class Circle extends Shape
{
public function Draw()
{
}
public function Radius()
{
}
}
Иногда исходный класс является частью библиотеки, которую вы не можете изменить.
Иногда вы хотите расширить суперкласс несколькими различными способами.
Например (синтаксис java вместо PHP, но идея та же):
class Shape {
abstract double getArea();
}
class Square extends Shape {
double getArea() {
return size * size;
}
}
class Circle extends Shape {
double getArea() {
return radius * radius * Math.PI;
}
}
Методу, который принимает аргументы типа Shape, вы можете передавать как квадраты, так и круги. Методу не нужно знать, какой из них он получает, но он все равно может вызвать getArea(). Это не сработало бы, если бы вы просто добавили метод к фигуре класс.
Это будет упрощением, но приведу вам пример из реальной жизни:
Учтите, что вы должны были создать систему управления контентом, т.Е. скрипт для отображения различных страниц на вашем веб-сайте на основе пользовательского ввода.
Вероятно, вы хотели бы, чтобы каждая страница (назовем их модулями) имела определенные функции, такие как допустимые команды, которые должны выполняться на этой странице/модуле. Эти разные команды могут быть разными методами в каждом классе модуля.
Однако, что, если бы вы разрешили команду входа в систему, независимо от того, где пользователь в данный момент находится на вашем веб-сайте? т. Е. Это была бы команда, разделяемая всеми модулями.
Ваше решение этой проблемы можно было бы решить, создав класс родительского модуля, в котором будет находиться метод входа, и который будет выполняться всеми модулями.
// Your parent class
abstract class ParentModule
{
protected function login()
{
// Login stuff
}
}
// One of your modules
final class ArticleModule extends ParentModule
{
public function submit_article()
{
// An example function
}
}
// Another one of your modules that the user could still login from
final class AnotherModule extends ParentModule
{
public function another_command()
{
// Magic
}
}
Ваш контроллер может выглядеть примерно так, как показано ниже.
$module = new ArticleModule();
$module->login();
$module->submit_article();
Наконец, когда вы начинаете изучать интерфейсы - мне потребовалась целая вечность, чтобы поймите это - вы снова увидите преимущества абстрактных классов. И действительно, если вы полностью поймете концепцию абстрактных классов, вам будет легче понять интерфейсы.