https://ithelp.ithome.com.tw/articles/10207680

fbpic.jpg

Modern Web

VUE & PHP (Apache2) & Docker 實戰開發系列 第 25 篇

本篇接續上篇PHP-物件導向(OOP)介紹-Part3

七、屬性和方法的可視性(The Visibility of Properties and Methods)

加入可視性(Visibility),可視性有三個public、protected、private, 可以決定能不能從物件外面控制物件的方法和屬性。

1.Public Properties and Methods

當一個變數或方法的可視性被宣告為public。這表示這些方法和屬性可以在類別的裡面與外面被存取。 前幾篇了範例都是使用public,新的類別以及所有的子類別都可使用被宣告為public的屬性或方法。

2.Protected Properties and Methods

當一個變數或方法的可視性被宣告為protected,該變數或方法只能在類別以及子類別的內部存取

下方範例替換MyClass的getProperty()的可視性宣告為protected,並且試著從外部呼叫

<?php
class MyClass
{
    public $prop1 = "I'm a class property!";

    public function __construct()          //物件被建立時呼叫訊息。
    {
        echo 'The class "' . __CLASS__ . '" was initiated!<br />';
    }

    public function __destruct()           //物件被結束時呼叫訊息。
    {
        echo 'The class "' . __CLASS__ . '" was destroyed.<br />';
    }

    public function __toString()           //將物件轉換為字串。
    {
        echo "Using the toString method: ";
        return $this->getProperty();
    }

    public function setProperty($newval)
    {
        $this->prop1 = $newval;
    }

    protected function getProperty()
    {
        return $this->prop1 . "<br />";
    }
}

class MyNewClass extends MyClass
{
    public function __construct()
    {
        echo 'A new constructor in "'. __CLASS__ . '".<br />';
    }

    public function newMethod()           //在新類別裡宣告一個屬性與方法。
    {
        echo 'From a new method in "' . __CLASS__ . '".<br />';
    }
}

$obj = new MyNewClass;                    //建立`MyNewClass`的新物件。

echo $obj->getProperty();                 //呼叫繼承父類別的`getProperty()`。

輸出到畫面會顯示Call to protected method的錯誤訊息

A new constructor in "MyNewClass". Fatal error: Uncaught Error: Call to protected method MyClass::getProperty() from context '' in /Users/caizhiwei/test.php:48 Stack trace: #0 {main} thrown in /Users/caizhiwei/test.php on line 48

這裡我們在子類別MyNewClass中新增一個public來調用getProperty()

<?php
class MyClass
{
    public $prop1 = "I'm a class property!";

    public function __construct()          //物件被建立時呼叫訊息。
    {
        echo 'The class "' . __CLASS__ . '" was initiated!<br />';
    }

    public function __destruct()           //物件被結束時呼叫訊息。
    {
        echo 'The class "' . __CLASS__ . '" was destroyed.<br />';
    }

    public function __toString()           //將物件轉換為字串。
    {
        echo "Using the toString method: ";
        return $this->getProperty();
    }

    public function setProperty($newval)
    {
        $this->prop1 = $newval;
    }

    protected function getProperty()
    {
        return $this->prop1 . "<br />";
    }
}

class MyNewClass extends MyClass
{
    public function __construct()
    {
        echo 'A new constructor in "'. __CLASS__ . '".<br />';
    }

    public function newMethod()           //在新類別裡宣告一個屬性與方法。
    {
        echo 'From a new method in "' . __CLASS__ . '".<br />';
    }

    public function getProperty()         //使用`public`從父類別繼承`getProperty()`。
    {
        return $this->prop1 . "<br />";
    }
}

$obj = new MyNewClass;                    //建立`MyNewClass`的新物件。

echo $obj->getProperty();                 //呼叫繼承父類別的`getProperty()`。

輸出到畫面會顯示

A new constructor in "MyNewClass". I'm a class property! The class "MyClass" was destroyed.