В предыдущем занятии по наследованию вы узнали, как определить класс SavingAccount, который наследует класс BankAccount:
Однако мы не обсудили конструкторы родительского и дочернего классов в контексте наследования.
В этом примере класс конструктор BankAccount имеет метод конструктор, который принимает параметр $balance. Конструктор присваивает аргумент $balance свойству $balance:
<?php
class BankAccount
{
private $balance;
public function __construct($balance)
{
$this->balance = $balance;
}
public function getBalance()
{
return $this->balance;
}
public function deposit($amount)
{
if ($amount > 0) {
$this->balance += $amount;
}
return $this;
}
}
Класс SavingAccount остается прежним и не имеет собственного конструктора:
<?php
class SavingAccount extends BankAccount
{
private $interestRate;
public function setInterestRate($interestRate)
{
$this->interestRate = $interestRate;
}
public function addInterest()
{
// calculate interest
$interest = $this->interestRate * $this->getBalance();
// deposit interest to the balance
$this->deposit($interest);
}
}
Когда вы создаете новый экземпляр класса SavingAccount, PHP вызывает конструктор класса SavingAccount. Однако PHP не может найти конструктор в классе SavingAccount. Поэтому он продолжает поиск конструктора родительского класса класса SavingAccount, которым является класс BankAccount. И он вызывает конструктор класса BankAccount.
$account = new SavingAccount();
Если вы не передадите аргумент конструктору класса SavingAccount, вы получите сообщение об ошибке:
Fatal error: Uncaught ArgumentCountError: Too few arguments to function BankAccount::__construct(), 0 passed in ... on line 5 and exactly 1 expected in ...
Но если вы передадите аргумент конструктору, он будет работать отлично:
$account = new SavingAccount(100);
У дочернего класса может быть собственный конструктор. Например, вы можете добавить конструктор в класс SavingAccount следующим образом:
<?php
class SavingAccount extends BankAccount
{
private $interestRate;
public function __construct($interestRate)
{
$this->interestRate = $interestRate;
}
public function setInterestRate($interestRate)
{
$this->interestRate = $interestRate;
}
public function addInterest()
{
// calculate interest
$interest = $this->interestRate * $this->getBalance();
// deposit interest to the balance
$this->deposit($interest);
}
}
Класс SavingAccount имеет конструктор, который инициализирует свойство interestRate.
Когда у дочернего класса есть собственный конструктор, конструктор в дочернем классе не будет автоматически вызывать конструктор своего родительского класса.
Например, следующий пример создает новый экземпляр класса SavingAccount и инициализирует свойство $interestRate значением 0,05.
$account = new SavingAccount(0.05);
Чтобы вызвать конструктор родительского класса из конструктора дочернего класса, вы используете синтаксис parent::__ construct (arguments).
В следующем примере изменим конструктор класса SavingAccount, который будет принимать два аргумента: баланс и процентную ставку. Конструктор дочернего класса также будет вызываеть конструктор класса BankAccount для инициализации свойства $balance:
<?php
class SavingAccount extends BankAccount
{
private $interestRate;
public function __construct($balance, $interestRate)
{
parent::__construct($balance);
$this->interestRate = $interestRate;
}
public function setInterestRate($interestRate)
{
$this->interestRate = $interestRate;
}
public function addInterest()
{
// calculate interest
$interest = $this->interestRate * $this->getBalance();
// deposit interest to the balance
$this->deposit($interest);
}
}