1
0
mirror of https://github.com/php/doc-ru.git synced 2026-04-25 08:18:16 +02:00
Files
archived-doc-ru/language/oop5/inheritance.xml
T
2024-04-23 03:46:09 +03:00

210 lines
9.3 KiB
XML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?xml version="1.0" encoding="utf-8"?>
<!-- EN-Revision: f94d903985119d3ac00f4528551df947f57b667f Maintainer: mch Status: ready -->
<!-- Reviewed: no -->
<sect1 xml:id="language.oop5.inheritance" xmlns="http://docbook.org/ns/docbook">
<title>Наследование</title>
<para>
Наследование — это хорошо зарекомендовавший себя принцип программирования, и PHP
использует этот принцип в своей объектной модели. Этот принцип повлияет на то,
как многие классы и объекты связаны друг с другом.
</para>
<para>
Например, при расширении класса дочерний класс наследует все
общедоступные и защищённые методы, свойства и константы родительского класса.
До тех пор пока
эти методы не будут переопределены, они будут сохранять свою
исходную функциональность.
</para>
<para>
Это полезно для определения и абстрагирования функциональности и позволяет
реализовать дополнительную функциональность в похожих объектах без
необходимости реализовывать всю общую функциональность.
</para>
<para>
Закрытые методы родительского класса недоступны для дочернего класса. В результате
дочерние классы могут повторно реализовать закрытый метод без учёта обычных
правил наследования. Однако до PHP 8.0.0 к закрытым методам применялись ограничения
<literal>final</literal> и <literal>static</literal>. Начиная с PHP 8.0.0,
единственное ограничение закрытого метода, которое применяется - это конструкторы <literal>private final</literal>,
поскольку это обычный способ «отключить» конструктор при использовании вместо него статичных фабричных методов.
</para>
<para>
<link linkend="language.oop5.visibility">Видимость</link> методов,
свойств и констант можно ослабить, например, <literal>защищённый</literal> метод
может быть помечен как <literal>общедоступный</literal>, но нельзя ограничить видимость,
например, нельзя пометить <literal>общедоступное</literal> свойство как <literal>закрытое</literal>.
Исключением являются конструкторы, видимость которых может быть ограничена,
например, <literal>общедоступный</literal> конструктор может быть помечен
как <literal>закрытый</literal> в дочернем классе.
</para>
<note>
<para>
Если не используется автозагрузка, классы должны быть объявлены до того, как они
будут использоваться. Если класс расширяет другой, то родительский класс должен быть
объявлен до наследующего класса. Это правило применяется к классам, которые наследуют
другие классы или интерфейсы.
</para>
</note>
<note>
<para>
Не разрешается переопределять свойство чтения-записи с помощью <link linkend="language.oop5.properties.readonly-properties">readonly-свойства</link> или наоборот.
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
class A
{
public int $prop;
}
class B extends A
{
// Нельзя: read-write -> readonly
public readonly int $prop;
}
?>
]]>
</programlisting>
</informalexample>
</para>
</note>
<example>
<title>Пример наследования</title>
<programlisting role="php">
<![CDATA[
<?php
class Foo
{
public function printItem($string)
{
echo 'Foo: ' . $string . PHP_EOL;
}
public function printPHP()
{
echo 'PHP просто супер.' . PHP_EOL;
}
}
class Bar extends Foo
{
public function printItem($string)
{
echo 'Bar: ' . $string . PHP_EOL;
}
}
$foo = new Foo();
$bar = new Bar();
$foo->printItem('baz'); // Выведет: 'Foo: baz'
$foo->printPHP(); // Выведет: 'PHP просто супер'
$bar->printItem('baz'); // Выведет: 'Bar: baz'
$bar->printPHP(); // Выведет: 'PHP просто супер'
?>
]]>
</programlisting>
</example>
<sect2 xml:id="language.oop5.inheritance.internal-classes">
<title>Совместимость типов возвращаемых значений с внутренними классами</title>
<para>
До PHP 8.1.0 большинство внутренних классов или методов не объявляли свои типы возвращаемых значений
и при их расширении допускался любой тип возвращаемого значения.
</para>
<para>
Начиная с PHP 8.1.0, большинство внутренних методов начали "предварительно" объявлять тип возвращаемого значения.
В этом случае тип возвращаемого значения методов должен быть совместим с расширяемым родителем;
в противном случае выдаётся уведомление об устаревании.
Обратите внимание, что отсутствие явного объявления типа возвращаемого значения также считается несоответствием сигнатуры
и, соответственно, приводит к уведомлению об устаревании.
</para>
<para>
Если тип возвращаемого значения не может быть объявлен для переопределяемого метода из-за проблем с совместимостью
с различными версиями PHP, может быть добавлен атрибут <classname>ReturnTypeWillChange</classname>, чтобы заглушить уведомление об устаревании.
</para>
<example>
<title>Переопределяющий метод не объявляет никакого типа возвращаемого значения</title>
<programlisting role="php">
<![CDATA[
<?php
class MyDateTime extends DateTime
{
public function modify(string $modifier) { return false; }
}
// "Deprecated: Return type of MyDateTime::modify(string $modifier) should either be compatible with DateTime::modify(string $modifier): DateTime|false, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice", начиная с PHP 8.1.0
?>
]]>
</programlisting>
</example>
<example>
<title>Переопределяющий метод объявляет неверный тип возвращаемого значения</title>
<programlisting role="php">
<![CDATA[
<?php
class MyDateTime extends DateTime
{
public function modify(string $modifier): ?DateTime { return null; }
}
// "Deprecated: Return type of MyDateTime::modify(string $modifier): ?DateTime should either be compatible with DateTime::modify(string $modifier): DateTime|false, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice", начиная с PHP 8.1.0
?>
]]>
</programlisting>
</example>
<example>
<title>Переопределяющий метод объявляет неверный тип возвращаемого значения без уведомления об устаревании</title>
<programlisting role="php">
<![CDATA[
<?php
class MyDateTime extends DateTime
{
/**
* @return DateTime|false
*/
#[\ReturnTypeWillChange]
public function modify(string $modifier) { return false; }
}
// Уведомление об устаревании не выводится
?>
]]>
</programlisting>
</example>
</sect2>
</sect1>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-omittag:t
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:1
sgml-indent-data:t
indent-tabs-mode:nil
sgml-parent-document:nil
sgml-default-dtd-file:"~/.phpdoc/manual.ced"
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
vim600: syn=xml fen fdm=syntax fdl=2 si
vim: et tw=78 syn=sgml
vi: ts=1 sw=1
-->