Почему вы расширяете класс, а не просто добавляете новый метод в исходный класс?


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

Author: TheBestJohn, 2012-09-27

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()
  {
  }
}
 4
Author: JvdBerg, 2012-09-26 20:26:34

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

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

Например (синтаксис 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(). Это не сработало бы, если бы вы просто добавили метод к фигуре класс.

 2
Author: user1701374, 2012-09-26 20:38:18

Это будет упрощением, но приведу вам пример из реальной жизни:

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

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

Однако, что, если бы вы разрешили команду входа в систему, независимо от того, где пользователь в данный момент находится на вашем веб-сайте? т. Е. Это была бы команда, разделяемая всеми модулями.

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

// 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();

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

 2
Author: bblue, 2012-09-27 16:52:13