Наследование классов
Представьте, что у вас есть класс User . Он нужен вам для каких-то целей и в общем-то полностью вас устраивает — доработки этому классу в не нужны.
А теперь представим себе ситуацию, когда нам понадобился еще и класс Employee . Работник очень похож на юзера, имеет те же свойства и методы, но еще и добавляет свои — свойство salary , а также геттер и сеттер для этого свойства. Вот этот класс:
salary; > // Сеттер зарплаты public function setSalary($salary) < $this->salary = $salary; > public function getName() < return $this->age; > public function setName($name) < $this->name = $name; > public function getAge() < return $this->age; > public function setAge($age) < $this->age = $age; > > ?>?php>
Как мы видим, код классов User и Employee практически полностью совпадает. Было бы намного лучше сделать так, чтобы общая часть была записана только в одном месте.
Для решения проблемы существует такая вещь, как . С помощью наследования мы можем заставить наш класс Employee позаимствовать () методы и свойства класса User и просто дополнить их своими методами и свойствами.
Класс, от которого наследуют называется ( англ. parent ), а класс, который наследует — . Класс-потомок наследует только публичные методы и свойства, но не приватные.
Наследование реализуется с помощью ключевого слова extends (переводится как расширяет ). Перепишем наш класс Employee так, чтобы он наследовал от User :
salary; > public function setSalary($salary) < $this->salary = $salary; > > ?>?php>
Проверим работу нового класса Employee :
setSalary(1000); // метод класса Employee $employee->setName(‘john’); // метод унаследован от родителя $employee->setAge(25); // метод унаследован от родителя echo $employee->getSalary(); // метод класса Employee echo $employee->getName(); // метод унаследован от родителя echo $employee->getAge(); // метод унаследован от родителя ?>?php>
Класс-потомок не унаследовал от своего родителя приватные свойства name и age — попытка обратится к ним вызовет ошибку. При этом, однако, в классе-потомке доступны геттеры и сеттеры этих свойств, так как эти геттеры и сеттеры являются публичными.
Не подсматривая в мой код реализуйте такие же классы User , Employee .
Несколько потомков
Преимущества наследования в том, что каждый класс может несколько потомков. Давайте посмотрим на примере. Пусть кроме работника нам нужен еще и класс Student — давайте также унаследуем его от User :
course; > public function setCourse($course) < $this->course = $course; > > ?>?php>
Проверим работу нашего класса:
setCourse(3); // метод класса Student $student->setName(‘john’); // метод унаследован от родителя $student->setAge(25); // метод унаследован от родителя echo $student->getCourse(); // метод класса Student echo $student->getName(); // метод унаследован от родителя echo $student->getAge(); // метод унаследован от родителя ?>?php>
Не подсматривая в мой код реализуйте такой же класс Student , наследующий от класса User .
Наследование от наследников
Пусть у нас есть класс-родитель и класс-потомок. От этого потомка также могут наследовать другие классы, от его потомков другие и так далее. Для примера пусть от класса User наследует Student , а от него в свою очередь наследует класс StudentBSU :
Сделайте класс Programmer , который будет наследовать от класса Employee . Пусть новый класс имеет свойство langs , в котором будет хранится массив языков, которыми владеет программист. Сделайте также геттер и сеттер для этого свойства.
Сделайте класс Driver ( водитель ), который будет наследовать от класса Employee . Пусть новый класс добавляет следующие свойства: водительский стаж, категория вождения (A, B, C, D), а также геттеры и сеттеры к ним.
Что такое наследование в php
Наследование является одним из основных аспектов объектно-ориентированного программирования. Наследование позволяет классу взять функционал уже имеющихся классов и при необходимости переопределить его. Если у нас есть какой-нибудь класс, в котором не хватает пары функций, то гораздо проще переопределить имеющийся класс, написав пару строк, чем создавать новый с нуля, переписывая кучу кода.
Чтобы наследовать один класс от другого, нам надо применить оператор extends . Стоит отметить, что в PHP мы можем унаследовать класс только от одного класса. Множественное наследование не поддерживается.
Например, унаследуем класс Employee от класса Person :
name = $name; > function displayInfo() < echo "Имя: $this->name
"; > > class Employee extends Person <> $tom = new Employee("Tom"); $tom -> displayInfo(); ?>
В данном случае предположим, что класс Person представляет человека в целом, а класс Employee — работника некого предприятия. В этой связи каждый работник преддставляет человека. И чтобы не дублировать один и тот же функционал, лучше в данном случае унаследовать класс работника — Employee от класа человека — Person. В этой паре класс Person еще называется родительским или базовым классом, а класс — Employee — производным классом или классом-наследником.
И так как класс Employee унаследован от Person, для объектов класса Employee мы можем использовать функционал родительского класса Person. Так, для создания объекта Employee в данном случае вызывается конструктор, который определен в классе Person и который в качестве параметра принимает имя человека:
$tom = new Employee("Tom");
И также у переменной типа Employee вызывается метод displayInfo , который определен в классе Person:
$tom -> displayInfo();
Переопределение функционала
Унаследовав функционал от родительского класса класс-наследник может добавить свои свойства и методы или переопредилить унаследованный функционал. Например, изменим класс Employee, добавив в него данные о компании, где работает работник:
name = $name; > function displayInfo() < echo "Имя: $this->name
"; > > class Employee extends Person < public $company; function __construct($name, $company) < $this->name = $name; $this->company = $company; > function displayInfo() < echo "Имя: $this->name
"; echo "Работает в $this->company
"; > > $tom = new Employee("Tom", "Microsoft"); $tom -> displayInfo(); ?>
Здесь класс Employee добавляет новое свойство — $company , которое хранит компанию работника. Также класс Employee переопределил конструктор, в который пеередаются данные для имени и компании. А также переопределен метод displayInfo() . Соответственно для создания объекта класса Employee, теперь необходимо использовать переопределенный в классе Employee конструктор:
$tom = new Employee("Tom", "Microsoft");
Класс-наследник переопределяет конструктор родительского класса, то для создания объекта класса-наследника необходимо использовать переопределенный в нем конструктор.
И также изменится поведение метода displayInfo() , который кроме имени также выведет и компанию работника:
Имя: Tom Работает в Microsoft
Вызов функционала родительского класса
Если мы посмотрим на код класса-наследника Employee, то можем увидеть части кода, которые повторяют код класса Person. Например, установка имени в конструкторе:
$this->name = $name;
Также вывод имени работника в методе displayInfo() :
echo "Имя: $this->name
";
В обоих случаях речь идет об одной строке кода. Однако что, если конструктор Employee повторяет установку не одного, а десятка свойств. Соответственно что, если метод displayInfo в классе-наследнике повторяет горадо больше действий родительского класса. В этом случае горадо рациональнее не писать повторяющийся код в классе-наследнике, а вызвать в нем соответствующий функционал родительского класса.
Если нам надо обратиться к методу родительского класса, то мы можем использовать ключевое слово parent , после которого используется двойное двоеточие :: и затем вызываемый метод.
Например, перепишем предыдущий пример:
name = $name; > function displayInfo() < echo "Имя: $this->name
"; > > class Employee extends Person < public $company; function __construct($name, $company) < parent::__construct($name); $this->company = $company; > function displayInfo() < parent::displayInfo(); echo "Работает в $this->company
"; > > $tom = new Employee("Tom", "Microsoft"); $tom -> displayInfo(); ?>
Теперь в конструкторе Employee вызывается конструктор базового класса:
parent::__construct($name);
В нем собственно и происходит установка имени. И подобным образом в методе displayInfo() вызывается реализация метода класса Person:
parent::displayInfo();
В итоге мы получим тот же самый результат.
Стоит отметить, что в реальности ключевое слово parent заменяет название класса. То есть мы также могли вызывать функционал родительского класса через имя этого класса:
class Employee extends Person < public $company; function __construct($name, $company) < Person::__construct($name); $this->company = $company; > function displayInfo() < Person::displayInfo(); echo "Работает в $this->company
"; > >
Оператор instanceof
Оператор instanceof позволяет проверить принадлежность объекта определенному класса. Слева от оператора располагается объект, котоый надо проверить, а справа — название класса. И если объект представляет класс, то оператор возвращает true . Например:
class Person < public $name; function __construct($name) < $this->name = $name; > function displayInfo() < echo "Имя: $this->name
"; > > class Employee extends Person < public $company; function __construct($name, $company) < Person::__construct($name); $this->company = $company; > function displayInfo() < Person::displayInfo(); echo "Работает в $this->company
"; > > class Manager<> $tom = new Employee("Tom", "Microsoft"); $tom instanceof Employee; // true $tom instanceof Person; // true $tom instanceof Manager; // false
Здесь переменная $tom представляет класс Employee , поэтому $tom instanceof Employee возвращает true .
Так как класс Employee унаследован от Person, то переменная $tom также представляет класс Person (работник также является человеком).
А вот класс Manager переменная $tom не преддставляет, поэтому выражение $tom instanceof Manager возвращает false .
Запрет наследования и оператор final
В примере выше метод displayInfo() переопределялся классом-наследником. Однако иногда возникают ситуации, когда надо запретить переопределение методов. Для этого в классе-родителе надо указать методы с модификатором final :
class Person < public $name; function __construct($name) < $this->name = $name; > final function displayInfo() < echo "Имя: $this->name
"; > > class Employee extends Person < public $company; function __construct($name, $company) < Person::__construct($name); $this->company = $company; > function displayEmployeeInfo() < Person::displayInfo(); echo "Работает в $this->company
"; > > $tom = new Employee("Tom", "Microsoft"); $tom -> displayEmployeeInfo();
В этом случае во всех классах-наследниках от класса Person мы уже не сможем определить метод с таким же именем. Поэтому в данном случае в классе Employee определен новый метод — displayEmployeeInfo.
Также мы можем вообще запретить наследование от класса. Для этого данный класс надо определить с модификатором final :
final class Person < public $name; function __construct($name) < $this->name = $name; > final function displayInfo() < echo "Имя: $this->name
"; > >
Теперь мы не сможем унаследовать класс Employee (да и никакой другой класс) от класса Person.
PHP: Наследование
Наследование — это механизм объектно ориентированного программирования, который позволяет описать новый класс на основе уже существующего (родительского).
Класс, который получается в результате наследования от другого, называется подклассом. Эту связь обычно описывают с помощью терминов «родительский» и «дочерний». Дочерний класс происходит от родительского и наследует его характеристики: свойства и методы. Обычно в подклассе к функциональности родительского класса (который также называют суперклассом) добавляются новые функциональные возможности.
Чтобы создать подкласс, необходимо использовать в объявлении класса ключевое слово extends , и после него указать имя класса, от которого выполняется наследование:
age = $age; > function add_age () < $this->age++; > > // объявляем наследуемый класс class my_Cat extends Cat < // определяем собственный метод подкласса function sleep() < echo '
Zzzzz. '; > > $kitty = new my_Cat(10); // вызываем наследуемый метод $kitty->add_age(); // считываем значение наследуемого свойства echo $kitty->age; // вызываем собственный метод подкласса $kitty->sleep(); ?>
Подкласс наследует доступ ко всем методам и свойствам родительского класса, так как они имеют тип public . Это означает, что для экземпляров класса my_Cat мы можем вызывать метод add_age() и обращаться к свойству $age не смотря на то, что они определены в классе cat . Также в приведенном примере подкласс не имеет своего конструктора. Если в подклассе не объявлен свой конструктор, то при создании экземпляров подкласса будет автоматически вызываться конструктор суперкласса.
Обратите внимание на то, что в подклассах могут переопределяться свойства и методы. Определяя подкласс, мы гарантируем, что его экземпляр определяется характеристиками сначала дочернего, а затем родительского класса. Чтобы лучше это понять рассмотрим пример:
age"; > > class my_Cat extends Cat < public $age = 10; >$kitty = new my_Cat; $kitty->foo(); ?>
При вызове $kitty->foo() интерпретатор PHP не может найти такой метод в классе my_Cat , поэтому используется реализация этого метода заданная в классе Cat . Однако в подклассе определено собственное свойство $age , поэтому при обращении к нему в методе $kitty->foo() , интерпретатор PHP находит это свойство в классе my_Cat и использует его.
Так как мы уже рассмотрели тему про указание типа аргументов, осталось сказать о том, что если в качестве типа указан родительский класс, то все потомки для метода будут так же доступны для использования, посмотрите на следующий пример:
> class my_Cat extends Cat <> $kitty = new Cat; // передаем методу экземпляр класса my_Cat $kitty->foo( new my_Cat ); ?>
Мы можем обращаться с экземпляром класса my_Cat так, как будто это объект типа Cat , т.е. мы можем передать объект типа my_Cat методу foo() класса Cat , и все будет работать, как надо.
Оператор parent
На практике подклассам бывает необходимо расширить функциональность методов родительского класса. Расширяя функциональность за счет переопределения методов суперкласса, в подклассах вы сохраняете возможность сначала выполнить программный код родительского класса, а затем добавить код, который реализует дополнительную функциональность. Давайте разберем как это можно сделать.
Чтобы вызвать нужный метод из родительского класса, вам понадобится обратиться к самому этому классу через дескриптор. Для этой цели в PHP предусмотрено ключевое слово parent . Оператор parent позволяет подклассам обращаться к методам (и конструкторам) родительского класса и дополнять их существующую функциональность. Чтобы обратиться к методу в контексте класса, используются символы » :: » (два двоеточия). Синтаксис оператора parent :
parent::метод_родительского_класа
Эта конструкция вызовет метод, определенный в суперклассе. Вслед за таким вызовом можно поместить свой программный код, который добавит новую функциональность:
title = $title; $this->price = $price; > > class new_book extends book < public $pages; function __construct($title, $price, $pages) < // вызываем метод-конструктор родительского класса parent::__construct($title, $price); // инициализируем свойство определенное в подклассе $this->pages = $pages; > > $obj = new new_book('азбука', 35, 500); echo "Книга: $obj->title
Цена: $obj->price
Страниц: $obj->pages"; ?>
Когда в дочернем классе определяется свой конструктор, PHP не вызывает конструктор родительского класса автоматически. Это необходимо сделать вручную в конструкторе подкласса. Подкласс сначала в своем конструкторе вызывает конструктор своего родительского класса, передавая нужные аргументы для инициализации, исполняет его, а затем выполняется код, который реализует дополнительную функциональность, в данном случае инициализирует свойство подкласса.
Ключевое слово parent можно использовать не только в конструкторах, но и в любом другом методе, функциональность которого вы хотите расширить, достигнуть этого можно, вызвав метод родительского класса:
name>."; return $str; > > class my_Cat extends Cat < public $age = 5; function getstr() < $str = parent::getstr(); $str .= "
Возраст: age> лет."; return $str; > > $obj = new my_Cat; echo $obj->getstr(); ?>
Здесь сначала вызывается метод getstr() из суперкласса, значение которого присваивается переменной, а после этого выполняется остальной код определенный в методе подкласса.
Теперь, когда мы познакомились с основами наследования, можно, наконец, рассмотреть вопрос видимости свойств и методов.
public, protected и private: управление доступом
До этого момента мы явно объявляли все свойства как public (общедоступные). И такой тип доступа задан по умолчанию для всех методов.
Элементы класса можно объявлять как public (общедоступные), protected (защищенные) и private (закрытые). Рассмотрим разницу между ними:
- К public (общедоступным) свойствам и методам, можно получить доступ из любого контекста.
- К protected (защищенным) свойствам и методам можно получить доступ либо из содержащего их класса, либо из его подкласса. Никакому внешнему коду доступ к ним не предоставляется.
- Вы можете сделать данные класса недоступными для вызывающей программы с помощью ключевого слова private (закрытые). К таким свойствам и методам можно получить доступ только из того класса, в котором они объявлены. Даже подклассы данного класса не имеют доступа к таким данным.
public — открытый доступ:
hello"; > > $obj = new human; // доступ из вызывающей программы echo "$obj->age"; // Допустимо $obj->say(); // Допустимо ?>
private — доступ только из методов класса:
age"; > > $obj = new human; // напрямую из вызывающей программы доступа к закрытым данным нет echo "$obj->age"; // Ошибка! доступ закрыт! // однако с помощью метода можно выводить закрытые данные $obj->say(); // Допустимо ?>
protected — защищенный доступ:
Модификатор protected с точки зрения вызывающей программы выглядит точно так же, как и private : он запрещает доступ к данным объекта извне. Однако в отличие от private он позволяет обращаться к данным не только из методов своего класса, но также и из методов подкласса.
Копирование материалов с данного сайта возможно только с разрешения администрации сайта
и при указании прямой активной ссылки на источник.
2011 – 2023 © puzzleweb.ru | razumnikum.ru
Наследование в объектно-ориентированном программировании PHP
Этот урок мы посвятим одной из ключевых тем объектно-ориентированного программирования – теме наследования. Благодаря реализации наследования мы можем организовать связь классов по принципу родительский-дочерний и добавлять дополнительную функциональность в разрабатываемые приложения без необходимости дублирования целых блоков кода.
Что такое наследование?
В объектно-ориентированном программировании наследование позволяет нам создать класс, который наследует функциональность и может использовать свойства и методы от другого класса. Это полезно, когда мы хотим создать класс, который расширяет функциональность исходного класса, не нарушая существующий код, который использует исходный класс.
Эту связь обычно описывают с помощью терминов «родительский» и «дочерний». Класс, от которого мы наследуем, называется базовым классом, суперклассом или родительским классом. Класс, который наследует функциональность, называется подклассом или дочерним классом. В наследовании у нас есть родительский класс со своими собственными методами и свойствами, а также дочерний класс (или классы), которые унаследуют все общедоступные и защищенные свойства и методы родительского класса. Кроме того, у них могут быть свои свойства и методы.
Используя наследование, мы можем создать повторно используемый фрагмент кода, который мы пишем только один раз в родительском классе и используем снова столько, сколько нам нужно в дочерних классах.
Как наследовать от другого класса?
Существующий класс готов к наследованию, нам не нужно делать с ним ничего особенного. Этот класс называется базовым классом, суперклассом или родительским классом.
В PHP мы используем ключевое слово extends , чтобы указать, что класс наследуется от другого класса.
Синтаксис
class ChildClass extends ParentClass < >?>
В приведенном ниже примере класс SportsCar наследует класс Car , поэтому у него есть доступ ко всем методам и свойствам Car , которые не являются приватными. Это позволяет нам писать общедоступные методы setModel() и hello() только один раз в родительском классе, а затем использовать эти методы как в родительском, так и в дочернем классах:
Пример
model = $model; > public function hello() < return "Бип! Я " . $this -> model . "
"; > > //Дочерний класс наследует код родительского класса class SportsCar extends Car < //Нет кода в дочернем классе >//Создаем экземпляр из дочернего класса $sportsCar1 = new SportsCar(); // Устанавливаем значение свойства класса // Для этого мы используем метод, который мы создали в родительском $sportsCar1 -> setModel('Mercedes Benz'); //Используем второй метод, который дочерний класс унаследовал от родительского класса echo $sportsCar1 -> hello(); ?>
Результат выполнения кода:
Бип! Я Mercedes Benz
Собственные методы и свойства дочернего класса
Так же, как дочерний класс может использовать свойства и методы своего родительского класса, он также может иметь собственные свойства и методы. Однако, хотя дочерний класс может использовать код, унаследованный от родительского, родительскому классу не разрешается использовать код дочернего класса.
В приведенном ниже примере мы добавим в дочерний класс некоторый собственный код, добавив свойство $style , а также метод driveItWithStyle() :
Пример
model = $model; > public function getModel() < return $this ->model; > > // Дочерний класс может использовать код, унаследованный от родительского класса, // а также может иметь собственный код class SportsCar extends Car < private $style = 'быстрый и надёжный'; public function driveItWithStyle() < return 'Автомобиль ' . $this ->getModel() . ' ' . $this -> style . ''; > > //создать экземпляр из дочернего класса $sportsCar1 = new SportsCar(); // Используем метод, который дочерний класс унаследовал от родительского класса $sportsCar1 -> setModel('Ferrari'); // Используем метод, который был добавлен в дочерний класс echo $sportsCar1 -> driveItWithStyle(); ?>
Результат выполнения кода:
Автомобиль Ferrari быстрый и надёжный
Наследование и модификатор защищенного доступа
В предыдущем уроке мы узнали, что можем использовать модификатор публичного доступа, чтобы разрешить доступ к методам и свойствам класса как внутри, так и за его пределами. Мы также узнали, что те методы и свойства, которые являются приватными, могут использоваться только внутри класса.
В этом уроке мы узнаем о третьем модификаторе — protected , который позволяет использовать код как внутри класса, так и из его дочерних классов.
Как вы думаете, что может случиться, когда мы попытаемся вызвать приватный метод или свойство извне класса?
Следующий пример демонстрирует, что может произойти, если мы объявляем свойство $model в родительском элементе приватным, но все же пытаемся получить к нему доступ из его дочернего класса:
Пример
model = $model; > > // Дочерний класс class SportsCar extends Car < //Пытаемся получить доступ к приватному свойству model public function hello() < return "Бип! Я " . $this -> model . "
"; > > //Создаём экземпляр из дочернего класса $sportsCar1 = new SportsCar(); //Устанавливаем имя модели класса $sportsCar1 -> setModel('Mercedes Benz'); //Получаем значение свойства model echo $sportsCar1 -> hello(); ?>
Результат выполнения кода:
Мы не вывели значение модели автомобиля $model , потому что метод hello() в дочернем классе пытается получить доступ к приватному свойству $model , которое принадлежит родительскому классу.
Мы можем решить эту проблему, объявив свойство $model в родительском классе как защищенное protected , а не приватное, потому что, когда мы объявляем свойство или метод как защищенные, мы можем обращаться к нему как из родительского, так и из дочернего классов:
Пример
model = $model; > > class SportsCar extends Car < // Теперь есть доступ к защищенному свойству, принадлежащему родителю public function hello() < return "Бип! Я " . $this -> model . "
"; > > //Создаём экземпляр из дочернего класса $sportsCar1 = new SportsCar(); //Задаём имя модели класса $sportsCar1 -> setModel('Mercedes Benz'); //Получаем имя модели класса echo $sportsCar1 -> hello(); ?>
Результат выполнения кода:
Бип! Я Mercedes Benz
Сказанное выше относится и к методам:
Пример
name = $name; $this->color = $color; > protected function intro() < echo "Автомобиль name> имеет цвет: color>."; > > class SportsCar extends Car < public function message() < echo "Какой цвет у автомобиля? " . "
"; // доступ к защищенному методу, принадлежащему родителю $this -> intro(); > > //Создаём экземпляр из дочернего класса $sportsCar1 = new SportsCar('Mercedes Benz', 'Красный'); $sportsCar1 -> message(); ?>
Результат выполнения кода:
Какой цвет у автомобиля?
Автомобиль Mercedes Benz имеет цвет: Красный.
Публичный метод message() дочернего класса SportsCar имеет доступ к методу intro() (который защищен) родительского класса.
Переопределение родительских свойств и методов
Так же, как дочерний класс может иметь свои собственные свойства и методы, он может переопределять свойства и методы родительского класса. Когда мы переопределяем свойства и методы класса, мы переписываем метод или свойство (с использованием того же имени), которое существует в родительском элементе, снова в дочернем, но присваиваем ему другое значение или код.
Посмотрите на пример ниже. Методы __construct() и intro() в дочернем классе (SportsCar) переопределят методы __construct() и intro() в родительском классе (Car):
Пример
name = $name; $this->color = $color; > public function intro() < echo "Автомобиль name> имеет цвет: color>."; > > class SportsCar extends Car < public $weight; public function __construct($name, $color, $weight) < $this->name = $name; $this->color = $color; $this->weight = $weight; > public function intro() < echo "Автомобиль name> имеет цвет color>, а его вес weight> кг."; > > $sportsCar1 = new SportsCar('Mercedes Benz', 'Красный', 1800); $sportsCar1 -> intro(); ?>
Результат выполнения кода:
Автомобиль Mercedes Benz имеет цвет Красный, а его вес 1800 кг.
Ключевое слово final
Ключевое слово final может быть использовано для предотвращения наследования класса или для предотвращения переопределения метода.
В приведенном ниже примере мы объявляем класс Car как final, чтобы предотвратить наследование класса, но все же пытаемся его наследовать. В результате мы получим ошибку:
Пример
// приведет к ошибке class SportsCar extends Car < // какой-то код >?>
Результат выполнения кода:
Fatal error: Class SportsCar may not inherit from final class (Car)
В следующем примере ключевое слово final испольуется для предотвращения переопределение метода:
Пример
> class SportsCar extends Car < public function intro() < // приведет к ошибке // какой-то код >> ?>
Результат выполнения кода:
Fatal error: Cannot override final method Car::intro()
Попытка переопределить родительский метод intro(), защищенный ключевым словом final , привела к ошибке.
Заключение
Мы используем наследование, чтобы уменьшить дублирование кода за счет использования кода из родительского класса в дочерних классах. В этом уроке мы изучили один из принципов объектно-ориентированного программирования — концепцию наследования. Мы используем наследование, чтобы уменьшить дублирование кода, используя код родительского класса в дочерних классах. Щелкните здесь, чтобы попрактиковаться в предмете.