File: abstract.xml

package info (click to toggle)
php-doc 20241205~git.dfcbb86%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 70,956 kB
  • sloc: xml: 968,269; php: 23,883; javascript: 671; sh: 177; makefile: 37
file content (239 lines) | stat: -rw-r--r-- 5,927 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
<?xml version="1.0" encoding="utf-8"?>
<!-- $Revision$ -->
 <sect1 xml:id="language.oop5.abstract" xmlns="http://docbook.org/ns/docbook">
  <title>Class Abstraction</title>

  <para>
   PHP has abstract classes, methods, and properties.
   Classes defined as abstract cannot be instantiated, and any class that
   contains at least one abstract method or property must also be abstract.
   Methods defined as abstract simply declare the method's signature and whether it is public or protected;
   they cannot define the implementation. Properties defined as abstract
   may declare a requirement for <literal>get</literal> or <literal>set</literal>
   behavior, and may provide an implementation for one, but not both, operations.
  </para>

  <para>
   When inheriting from an abstract class, all methods marked abstract in
   the parent's class declaration must be defined by the child class,
   and follow the usual
   <link linkend="language.oop5.inheritance">inheritance</link> and
   <link linkend="language.oop.lsp">signature compatibility</link> rules.
  </para>

  <simpara>
   As of PHP 8.4, an abstract class may declare an abstract property, either public or protected.
   A protected abstract property may be satisfied by a property that is readable/writeable from either
   protected or public scope.
  </simpara>
  <simpara>
   An abstract property may be satisfied either by a standard property or by a property
   with defined <link linkend="language.oop5.property-hooks">hooks</link>, corresponding to the required operation.
  </simpara>

  <example>
   <title>Abstract method example</title>
   <programlisting role="php">
<![CDATA[
<?php

abstract class AbstractClass
{
    // Force extending class to define this method
    abstract protected function getValue();
    abstract protected function prefixValue($prefix);

    // Common method
    public function printOut()
    {
        print $this->getValue() . "\n";
    }
}

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

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

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

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

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

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

?>
]]>
   </programlisting>
   &example.outputs;
   <screen>
<![CDATA[
ConcreteClass1
FOO_ConcreteClass1
ConcreteClass2
FOO_ConcreteClass2
]]>
   </screen>
  </example>

  <example>
   <title>Abstract method example</title>
    <programlisting role="php">
<![CDATA[
<?php

abstract class AbstractClass
{
    // An abstract method only needs to define the required arguments
    abstract protected function prefixName($name);
}

class ConcreteClass extends AbstractClass
{
    // A child class may define optional parameters which are not present in the parent's signature
    public function prefixName($name, $separator = ".")
    {
        if ($name == "Pacman") {
            $prefix = "Mr";
        } elseif ($name == "Pacwoman") {
            $prefix = "Mrs";
        } else {
            $prefix = "";
        }

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

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

?>
]]>
   </programlisting>
   &example.outputs;
   <screen>
<![CDATA[
Mr. Pacman
Mrs. Pacwoman
]]>
   </screen>
  </example>
  <example>
   <title>Abstract property example</title>
    <programlisting role="php">
<![CDATA[
<?php

abstract class A
{
    // Extending classes must have a publicly-gettable property
    abstract public string $readable {
        get;
    }

    // Extending classes must have a protected- or public-writeable property
    abstract protected string $writeable {
        set;
    }

    // Extending classes must have a protected or public symmetric property
    abstract protected string $both {
        get;
        set;
    }
}

class C extends A
{
    // This satisfies the requirement and also makes it settable, which is valid
    public string $readable;

    // This would NOT satisfy the requirement, as it is not publicly readable
    protected string $readable;

    // This satisfies the requirement exactly, so is sufficient.
    // It may only be written to, and only from protected scope
    protected string $writeable {
        set => $value;
    }

    // This expands the visibility from protected to public, which is fine
    public string $both;
}

?>
]]>
   </programlisting>
  </example>
  <simpara>
   An abstract property on an abstract class may provide implementations for any hook,
   but must have either <literal>get</literal> or <literal>set</literal> declared but not defined (as in the example above).
  </simpara>
  <example>
   <title>Abstract property example</title>
   <programlisting role="php">
<![CDATA[
<?php

abstract class A
{
    // This provides a default (but overridable) set implementation,
    // and requires child classes to provide a get implementation
    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
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
-->