Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update Language/oop5 to En #1004

Merged
merged 6 commits into from
Nov 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
153 changes: 125 additions & 28 deletions language/oop5/abstract.xml
Original file line number Diff line number Diff line change
@@ -1,69 +1,87 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- EN-Revision: 9ee9eccf455188ab6eb352194eb6f9eb99e15606 Maintainer: shein Status: ready -->
<!-- EN-Revision: 2e7c00fd314a708ecbd495ef7cc9ae8c8462c33c Maintainer: shein Status: ready -->
<!-- Reviewed: no -->
<sect1 xml:id="language.oop5.abstract" xmlns="http://docbook.org/ns/docbook">
<title>Абстрактные классы</title>
<title>Абстракция класса</title>

<para>
PHP поддерживает определение абстрактных классов и методов. На основе абстрактного класса
нельзя создавать объекты, и любой класс, содержащий хотя бы один абстрактный метод,
должен быть определён как абстрактный. Методы, объявленные абстрактными, несут, по существу,
лишь описательный смысл и не могут включать реализацию.
PHP поддерживает абстрактные классы, методы и свойства. Нельзя создавать
экземпляры абстрактных классов, и класс, в котором объявили хотя бы один абстрактный метод или свойство,
должен быть абстрактным. Абстрактные методы объявляют только сигнатуру и открытую или защищённую
область видимости метода; абстрактным методам нельзя определять реализацию.
</para>

<para>
При наследовании от абстрактного класса, все методы, помеченные абстрактными
в родительском классе, должны быть определены в дочернем классе и
следовать обычным правилам <link linkend="language.oop5.inheritance">наследования</link>
При наследовании абстрактного класса дочерний класс обязан определить методы,
которые пометили абстрактными в объявлении родительского класса,
и следовать обычным правилам <link linkend="language.oop5.inheritance">наследования</link>
и <link linkend="language.oop.lsp">совместимости сигнатуры</link>.
</para>

<simpara>
Начиная с PHP 8.4 в абстрактных классах разрешили объявлять абстрактные свойства, как с открытой,
так и с защищённой областью видимости. Защищённому абстрактному свойству удовлетворяет свойство,
которое доступно для чтения или записи как из защищённой, так и из открытой области видимости.
</simpara>
<simpara>
Абстрактному свойству удовлетворяет либо стандартное свойство, либо свойство,
для которого определили <link linkend="language.oop5.property-hooks">хуки</link>, которые соответствуют
операции чтения или записи абстрактного свойства.
</simpara>

<example>
<title>Пример абстрактного класса</title>
<programlisting role="php">
<title>Пример абстрактного метода</title>
<programlisting role="php">
<![CDATA[
<?php

abstract class AbstractClass
{
// Данные методы должны быть определены в дочернем классе
// Эти методы потребуется определить в дочернем классе
abstract protected function getValue();
abstract protected function prefixValue($prefix);

// Общий метод
public function printOut() {
public function printOut()
{
print $this->getValue() . "\n";
}
}

class ConcreteClass1 extends AbstractClass
{
protected function getValue() {
protected function getValue()
{
return "ConcreteClass1";
}

public function prefixValue($prefix) {
public function prefixValue($prefix)
{
return "{$prefix}ConcreteClass1";
}
}

class ConcreteClass2 extends AbstractClass
{
public function getValue() {
public function getValue()
{
return "ConcreteClass2";
}

public function prefixValue($prefix) {
public function prefixValue($prefix)
{
return "{$prefix}ConcreteClass2";
}
}

$class1 = new ConcreteClass1;
$class1 = new ConcreteClass1();
$class1->printOut();
echo $class1->prefixValue('FOO_') ."\n";
echo $class1->prefixValue('FOO_'), "\n";

$class2 = new ConcreteClass2;
$class2 = new ConcreteClass2();
$class2->printOut();
echo $class2->prefixValue('FOO_') ."\n";
echo $class2->prefixValue('FOO_'), "\n";

?>
]]>
</programlisting>
Expand All @@ -79,36 +97,39 @@ FOO_ConcreteClass2
</example>

<example>
<title>Пример абстрактного класса</title>
<title>Пример абстрактного метода</title>
<programlisting role="php">
<![CDATA[
<?php

abstract class AbstractClass
{
// Наш абстрактный метод требует только определить необходимые аргументы
// Абстрактный метод только определяет аргументы
abstract protected function prefixName($name);

}

class ConcreteClass extends AbstractClass
{

// Наш дочерний класс может определить необязательные аргументы, не указанные в объявлении родительского метода
public function prefixName($name, $separator = ".") {
// Дочернему классу разрешается определять в сигнатуре метода необязательные параметры,
// которые не объявляли в сигнатуре метода родительского класса
public function prefixName($name, $separator = ".")
{
if ($name == "Pacman") {
$prefix = "Mr";
} elseif ($name == "Pacwoman") {
$prefix = "Mrs";
} else {
$prefix = "";
}

return "{$prefix}{$separator} {$name}";
}
}

$class = new ConcreteClass;
$class = new ConcreteClass();
echo $class->prefixName("Pacman"), "\n";
echo $class->prefixName("Pacwoman"), "\n";

?>
]]>
</programlisting>
Expand All @@ -120,6 +141,82 @@ Mrs. Pacwoman
]]>
</screen>
</example>
<example>
<title>Пример абстрактного свойства</title>
<programlisting role="php">
<![CDATA[
<?php

abstract class A
{
// В дочернем классе потребуется объявить открытое для чтения свойство
abstract public string $readable {
get;
}

// В дочернем классе потребуется объявить защищённое или открытое для записи свойство
abstract protected string $writeable {
set;
}

// В дочернем классе потребуется объявить защищённое или открытое свойство с симметричной областью видимости
abstract protected string $both {
get;
set;
}
}

class C extends A
{
// Определение удовлетворяет требованию абстрактного свойства, и делает свойство доступным для записи, что допустимо
public string $readable;

// Такое определение того же свойства НЕ удовлетворит требованию,
// поскольку свойство недоступно для открытого чтения
protected string $readable;

// Определение на 100 % удовлетворяет требованию абстракции, поэтому такого определения достаточно.
// Свойство доступно для записи и только из защищённой области видимости
protected string $writeable {
set => $value;
}

// Определение расширяет видимость с защищенной до общедоступной, это допустимо
public string $both;
}

?>
]]>
</programlisting>
</example>
<simpara>
Абстрактное свойство абстрактного класса должно содержать объявление по крайней мере одного абстрактного хука.
При объявлении для абстрактного свойства и хука <literal>get</literal>, и хука <literal>set</literal>
одному хуку в абстрактном классе разрешается предоставить реализацию, как в приведённом примере.
</simpara>
<example>
<title>Пример абстрактного свойства</title>
<programlisting role="php">
<![CDATA[
<?php

abstract class A
{
// Определение стандартной, но переопределяемой реализации хука set,
// и требование к дочерним классам предоставить реализацию хука get
abstract public string $foo {
get;

set {
$this->foo = $value
};
}
}

?>
]]>
</programlisting>
</example>
</sect1><!-- Keep this comment at the end of the file
Local variables:
mode: sgml
Expand Down
15 changes: 9 additions & 6 deletions language/oop5/basic.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- EN-Revision: 1d92bcca7524c50fc41056ea4c04e1032eb9e055 Maintainer: sergey Status: ready -->
<!-- EN-Revision: 2f85d57a0b5a01b875cbca2b291f04389cf61ac2 Maintainer: sergey Status: ready -->
<!-- Reviewed: no -->
<sect1 xml:id="language.oop5.basic" xmlns="http://docbook.org/ns/docbook">
<title>Основы</title>
Expand All @@ -12,11 +12,14 @@
свойства и методы класса.
</para>
<para>
Для имени класса разрешается выбирать любое слово, при условии, что слово не входит в список
<link linkend="reserved">зарезервированных слов</link> PHP, начинается с буквы или
символа подчёркивания и за которым следует любое количество букв, цифр или символов
подчёркивания. Если задать эти правила в виде регулярного выражения, то получится
следующее выражение: <code>^[a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*$</code>.
Для класса разрешается выбирать произвольное название, при условии,
что это не <link linkend="reserved">зарезервированное слово</link> языка PHP.
Начиная с PHP 8.4.0 объявление названия класса, которое состоит из одного символа подчёркивания <literal>_</literal>,
устарело.
Допустимое название класса начинается с буквы или подчеркивания,
за которым идёт произвольное количество букв, цифр или символов подчеркивания.
В виде регулярного выражения правило именования классов выглядят так:
<code>^[a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*$</code>.
</para>
<para>
Классы содержат <link linkend="language.oop5.constants">константы</link>,
Expand Down
Loading
Loading