|
4 | 4 | <title>Class Abstraction</title>
|
5 | 5 |
|
6 | 6 | <para>
|
7 |
| - PHP has abstract classes and methods. |
| 7 | + PHP has abstract classes, methods, and properties. |
8 | 8 | Classes defined as abstract cannot be instantiated, and any class that
|
9 |
| - contains at least one abstract method must also be abstract. |
10 |
| - Methods defined as abstract simply declare the method's signature; |
11 |
| - they cannot define the implementation. |
| 9 | + contains at least one abstract method or property must also be abstract. |
| 10 | + Methods defined as abstract simply declare the method's signature and whether it is public or protected; |
| 11 | + they cannot define the implementation. Properties defined as abstract |
| 12 | + may declare a requirement for <literal>get</literal> or <literal>set</literal> |
| 13 | + behavior, and may provide an implementation for one, but not both, operations. |
12 | 14 | </para>
|
13 | 15 |
|
14 | 16 | <para>
|
|
19 | 21 | <link linkend="language.oop.lsp">signature compatibility</link> rules.
|
20 | 22 | </para>
|
21 | 23 |
|
| 24 | + <para> |
| 25 | + As of PHP 8.4, an abstract class may declare an abstract property, either public or protected. |
| 26 | + A protected abstract property may be satisfied by a property that is readable/writeable from either |
| 27 | + protected or public scope. |
| 28 | + </para> |
| 29 | + <para> |
| 30 | + An abstract property may be satisfied either by a standard property or by a property |
| 31 | + with defined <link linkend="language.oop5.property-hooks">hooks</link>, corresponding to the required operation. |
| 32 | + </para> |
| 33 | + |
22 | 34 | <example>
|
23 |
| - <title>Abstract class example</title> |
| 35 | + <title>Abstract method example</title> |
24 | 36 | <programlisting role="php">
|
25 | 37 | <![CDATA[
|
26 | 38 | <?php
|
@@ -80,7 +92,7 @@ FOO_ConcreteClass2
|
80 | 92 | </example>
|
81 | 93 |
|
82 | 94 | <example>
|
83 |
| - <title>Abstract class example</title> |
| 95 | + <title>Abstract method example</title> |
84 | 96 | <programlisting role="php">
|
85 | 97 | <![CDATA[
|
86 | 98 | <?php
|
@@ -121,6 +133,66 @@ Mrs. Pacwoman
|
121 | 133 | ]]>
|
122 | 134 | </screen>
|
123 | 135 | </example>
|
| 136 | + <example> |
| 137 | + <title>Abstract property example</title> |
| 138 | + <programlisting role="php"> |
| 139 | +<![CDATA[ |
| 140 | +<?php |
| 141 | +abstract class A |
| 142 | +{ |
| 143 | + // Extending classes must have a publicly-gettable property. |
| 144 | + abstract public string $readable { get; } |
| 145 | +
|
| 146 | + // Extending classes must have a protected- or public-writeable property. |
| 147 | + abstract protected string $writeable { set; } |
| 148 | +
|
| 149 | + // Extending classes must have a protected or public symmetric property. |
| 150 | + abstract protected string $both { get; set; } |
| 151 | +} |
| 152 | +
|
| 153 | +class C extends A |
| 154 | +{ |
| 155 | + // This satisfies the requirement and also makes it settable, which is valid. |
| 156 | + public string $readable; |
| 157 | +
|
| 158 | + // This would NOT satisfy the requirement, as it is not publicly readable. |
| 159 | + protected string $readable; |
| 160 | +
|
| 161 | + // This satisfies the requirement exactly, so is sufficient. |
| 162 | + // It may only be written to, and only from protected scope. |
| 163 | + protected string $writeable { |
| 164 | + set => $value; |
| 165 | + } |
| 166 | +
|
| 167 | + // This expands the visibility from protected to public, which is fine. |
| 168 | + public string $both; |
| 169 | +} |
| 170 | +?> |
| 171 | +]]> |
| 172 | + </programlisting> |
| 173 | + </example> |
| 174 | + <para> |
| 175 | + An abstract property on an abstract class may provide implementations for any hook, |
| 176 | + but must have either <literal>get</literal> or <literal>set</literal> declared but not defined (as in the example above). |
| 177 | + </para> |
| 178 | + <example> |
| 179 | + <title>Abstract property example</title> |
| 180 | + <programlisting role="php"> |
| 181 | +<![CDATA[ |
| 182 | +<?php |
| 183 | +abstract class A |
| 184 | +{ |
| 185 | + // This provides a default (but overridable) set implementation, |
| 186 | + // and requires child classes to provide a get implementation. |
| 187 | + abstract public string $foo { |
| 188 | + get; |
| 189 | + set { $this->foo = $value }; |
| 190 | + } |
| 191 | +} |
| 192 | +?> |
| 193 | + ]]> |
| 194 | + </programlisting> |
| 195 | + </example> |
124 | 196 | </sect1>
|
125 | 197 | <!-- Keep this comment at the end of the file
|
126 | 198 | Local variables:
|
|
0 commit comments