diff --git a/language/oop5/final.xml b/language/oop5/final.xml
index 8c7b89e52..bd3f7715c 100644
--- a/language/oop5/final.xml
+++ b/language/oop5/final.xml
@@ -1,11 +1,11 @@
-
-
+
+
Final 关键字
- final 关键字通过在定义方法和常量之前加上 final 来防止被子类覆盖。
+ final 关键字通过在定义方法、属性和常量之前加上 final 来防止被子类覆盖。
如果一个类被声明为 final,则不能被继承。
@@ -62,11 +62,27 @@ class ChildClass extends BaseClass {
-
-
- PHP 8.1.0 起可用的 final 常量示例
-
-
+ PHP 8.4.0 起可用的 final 属性示例
+
+
+]]>
+
+
+
+ PHP 8.1.0 起可用的 final 常量示例
+
+
]]>
-
-
-
+
+
- 属性和常量不能被定义为 final,只有类、方法、常量(PHP 8.1.0 起)才能被定义为 final。
+ 从 PHP 8.0.0 起,除了构造函数之外,私有方法也不能声明为 final 。
- 从 PHP 8.0.0 起,除了构造函数之外,私有方法也不能声明为 final 。
+ 声明为 private(set) 的属性是隐式的 final。
diff --git a/language/oop5/properties.xml b/language/oop5/properties.xml
index 7cee729e7..becbb6031 100644
--- a/language/oop5/properties.xml
+++ b/language/oop5/properties.xml
@@ -1,6 +1,6 @@
-
+
属性
@@ -181,6 +181,9 @@ Fatal error: Uncaught Error: Typed property Shape::$numberOfSides must not be ac
只读属性
自 PHP 8.1.0 起,可以使用 readonly 修饰符声明属性,防止初始化后修改属性。
+ 在 PHP 8.4.0 之前,readonly 属性是隐式的私有设置,只能从同一类写入。
+ 从 PHP 8.4.0 开始,readonly 属性是隐式的 protected(set),
+ 因此可以从子类设置。如果需要,可以显式覆盖。
只读属性示例
diff --git a/language/oop5/visibility.xml b/language/oop5/visibility.xml
index 00809415c..c768811eb 100644
--- a/language/oop5/visibility.xml
+++ b/language/oop5/visibility.xml
@@ -1,6 +1,6 @@
-
+
访问控制(可见性)
@@ -16,7 +16,6 @@
类属性可以定义为public, private 或者 protected。在没有任何访问控制关键字的情况下,属性声明为 public。
-
属性声明
@@ -73,7 +72,118 @@ $obj2->printHello(); // 输出 Public2、Protected2 和 Undefined
]]>
-
+
+ 不对称属性可见性
+
+ 从 PHP 8.4 开始,属性也可以设置不对称的可见性,读取(get)
+ 和写入(set)可以有不同的范围。
+ 具体来说,可以单独指定set可见性,只要它不比默认可见性更宽。
+
+
+ 不对称属性可见性
+
+author = $author; // OK
+ $this->pubYear = $year; // Fatal Error
+ }
+}
+
+$b = new Book('How to PHP', 'Peter H. Peterson', 2024);
+
+echo $b->title; // Works
+echo $b->author; // Works
+echo $b->pubYear; // Fatal Error
+
+$b->title = 'How not to PHP'; // Fatal Error
+$b->author = 'Pedro H. Peterson'; // Fatal Error
+$b->pubYear = 2023; // Fatal Error
+?>
+]]>
+
+
+ 关于不对称可见性有一些注意事项:
+
+
+
+ 只有声明了类型的属性才能有单独的set可见性。
+
+
+
+
+ set 可见性必须和 get 可见性相同或更严格。
+ 也就是说,public protected(set) 和 protected protected(set)
+ 是允许的,但是 protected public(set) 会导致语法错误。
+
+
+
+
+ 如果一个属性是 public,那么主要可见性可能被省略。
+ 也就是说,public private(set) 和 private(set)
+ 会有相同的结果。
+
+
+
+
+ 一个属性的 private(set) 可见性会自动变为 final,
+ 并且不能在子类中重新声明。
+
+
+
+
+ 读取属性的引用遵循 set 可见性,而不是 get。
+ 这是因为引用可能用于修改属性值。
+
+
+
+
+ 同样,试图写入数组属性会涉及到内部的 get 和 set 操作,
+ 因此会遵循 set 可见性,因为这总是更严格的。
+
+
+
+
+ 当一个类继承另一个类时,子类可以重新定义任何不是 final 的属性。
+ 这样做时,可以扩大主要可见性或 set 可见性,只要新的可见性和父类相同或更宽。
+ 但是要注意,如果一个 private 属性被重写,它实际上并没有改变父类的属性,
+ 而是创建了一个具有不同内部名称的新属性。
+
+
+ 不对称属性继承
+
+
+]]>
+
+
+
@@ -81,8 +191,7 @@ $obj2->printHello(); // 输出 Public2、Protected2 和 Undefined
类中的方法可以被定义为 public、private 或 protected。如果没有设置这些关键字,则该方法默认为 public。
-
-
+
方法声明
test(); // Bar::testPrivate
// Foo::testPublic
?>
]]>
-
-
-
+
+
@@ -180,32 +288,31 @@ $myFoo->test(); // Bar::testPrivate
PHP 7.1.0 开始,类的常量可以定义为 public、private 或 protected。如果没有设置这些关键字,则该常量默认为 public。
-
-
- PHP 7.1.0 中的常量声明
-
+
+ PHP 7.1.0 中的常量声明
+
foo(); // 将会输出:Public Protected Private
/**
- * Define MyClass2
- */
+* Define MyClass2
+*/
class MyClass2 extends MyClass
{
- // This is public
- function foo2()
- {
- echo self::MY_PUBLIC;
- echo self::MY_PROTECTED;
- echo self::MY_PRIVATE; // 这行会产生一个致命错误
- }
+ // This is public
+ function foo2()
+ {
+ echo self::MY_PUBLIC;
+ echo self::MY_PROTECTED;
+ echo self::MY_PRIVATE; // 这行会产生一个致命错误
+ }
}
$myclass2 = new MyClass2;
@@ -234,9 +341,8 @@ echo MyClass2::MY_PUBLIC; // 这行可以正常执行
$myclass2->foo2(); // 将会输出:Public Protected,MY_PRIVATE 是私有常量,无法输出
?>
]]>
-
-
-
+
+