小熊奶糖(BearCandy)
小熊奶糖(BearCandy)
发布于 2024-03-12 / 9 阅读
0
0

php面向对象 方法属性重写及final关键字

在PHP中,方法可以被重写(Override),但属性(变量成员)并不能直接重写。下面分别解释并给出方法重写和属性相关的例子:

方法重写(Override)

方法重写发生在子类继承父类,并且子类中有与父类同名且参数列表相同的非私有(public或protected)方法时。子类的方法将覆盖父类的相应方法。

PHP方法重写示例:

class ParentClass
{
    public function sayHello()
    {
        echo "Hello from ParentClass";
    }
}

class ChildClass extends ParentClass
{
    // 重写父类的sayHello方法
    public function sayHello()
    {
        echo "Hello from ChildClass";
    }
}

$parent = new ParentClass();
$parent->sayHello(); // 输出: Hello from ParentClass

$child = new ChildClass();
$child->sayHello(); // 输出: Hello from ChildClass

在这个例子中,ChildClass 重写了从 ParentClass 继承来的 sayHello() 方法,因此当我们通过 ChildClass 实例调用 sayHello() 时,执行的是子类的版本。

属性的可见性和继承

尽管属性本身不能像方法那样被“重写”,但子类可以继承父类的非私有属性(public或protected),并且可以定义具有相同名称的新属性。然而,这不是真正意义上的重写,而是隐藏(Shadowing)父类的属性。

属性隐藏示例:

class ParentClass
{
    public $message = "Message from ParentClass";
}

class ChildClass extends ParentClass
{
    // 隐藏父类的$message属性
    public $message = "Message from ChildClass";
}

$child = new ChildClass();

echo $child->message; // 输出: Message from ChildClass

// 若要访问父类的原始属性,需使用parent::
echo $child->parent::message; // 输出: Message from ParentClass

在这个例子中,ChildClass 定义了自己的 $message 属性,这使得在访问 $child 对象的 $message 时,获取的是子类的属性值而不是父类的。不过,通过 parent:: 语法仍然可以访问父类的原始属性。但请注意,这种情况通常不是推荐的做法,因为属性隐藏可能导致代码难以理解和维护。在实践中,更多时候我们会考虑通过getter和setter方法来进行控制,而不是简单地重定义属性。

在PHP中,面向对象编程允许类之间通过继承建立层次结构。**重写(Override)**是指在子类中重新定义父类中已经存在的非私有(public或protected)方法的行为。但是,若父类中的某个方法被声明为 final,则子类将无法重写该方法。

final关键字的使用

  1. 修饰类

    // 使用final关键字修饰类,禁止类被继承
    final class ParentClass {
        // ...
    }
    
    // 尝试继承final类会引发错误
    class ChildClass extends ParentClass { // 这里会出错,ChildClass不能继承ParentClass
        // ...
    }
    
  2. 修饰方法

    // 在ParentClass中定义一个final方法,子类不能重写
    class ParentClass {
        final public function display() {
            echo "This is the parent method.";
        }
    }
    
    class ChildClass extends ParentClass {
        // 下面的定义会引发错误,因为display方法在ParentClass中被声明为final
        public function display() { // 这里会出错
            echo "This is the child method.";
        }
    }
    

属性(变量成员)不能直接被final修饰,但在PHP 7.1及更高版本中,可以使用 final 修饰符来定义常量属性(即只读属性),其值在声明时就被固定,不能在构造函数或任何其他地方更改。

class MyClass {
    final public const MY_FINAL_PROPERTY = 'This is a final property';
}

// 试图修改此属性将会导致错误
MyClass::MY_FINAL_PROPERTY = 'Another value'; // 错误:不能修改常量属性

总结一下,final关键字在PHP中主要用于阻止继承行为(针对类)和方法重写(针对类的方法)。对于类属性,虽然不能直接标记为final以防止重写,但可以通过定义常量属性来达到类似的效果。


评论