程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 網頁編程 >> PHP編程 >> 關於PHP編程 >> 前端學PHP之面向對象系列第三篇——三大特性,第三篇三大

前端學PHP之面向對象系列第三篇——三大特性,第三篇三大

編輯:關於PHP編程

前端學PHP之面向對象系列第三篇——三大特性,第三篇三大


×
目錄
[1]封裝 [2]繼承[3]多態

前面的話

  php面向對象編程的三大特性是封裝性、繼承性和多態性。本文將介紹php的這三大特性

 

封裝

  封裝就是把對象中的成員屬性和成員方法加上訪問修飾符( public(公有),protected(受保護)或 private(私有)),使其盡可能隱藏對象的內部細節,以達到對成員的訪問控制

  被定義為公有的類成員可以在任何地方被訪問。被定義為受保護的類成員則可以被其自身以及其子類和父類訪問。被定義為私有的類成員則只能被其定義所在的類訪問

  類屬性必須定義為公有,受保護,私有之一。如果用 var 定義,則被視為公有

<?php
class MyClass
{
    public $public = 'Public';
    protected $protected = 'Protected';
    private $private = 'Private';
    function printHello()
    {
        echo $this->public;
        echo $this->protected;
        echo $this->private;
    }
}
$obj = new MyClass();
echo $obj->public; // 這行能被正常執行
echo $obj->protected; // 這行會產生一個致命錯誤
echo $obj->private; // 這行也會產生一個致命錯誤
$obj->printHello(); // 輸出 Public、Protected 和 Private

class MyClass2 extends MyClass
{
    // 可以對 public 和 protected 進行重定義,但 private 而不能
    protected $protected = 'Protected2';
    function printHello()
    {
        echo $this->public;
        echo $this->protected;
        echo $this->private;
    }
}
$obj2 = new MyClass2();
echo $obj2->public; // 這行能被正常執行
echo $obj2->private; // 未定義 private
echo $obj2->protected; // 這行會產生一個致命錯誤
$obj2->printHello(); // 輸出 Public、Protected2 和 Undefined
?>

  類中的方法可以被定義為公有,私有或受保護。如果沒有設置這些關鍵字,則該方法默認為公有

<?php
class MyClass
{
    public function __construct() { }
    public function MyPublic() { }
    protected function MyProtected() { }
    private function MyPrivate() { }
    function Foo()
    {
        $this->MyPublic();
        $this->MyProtected();
        $this->MyPrivate();
    }
}
$myclass = new MyClass;
$myclass->MyPublic(); // 這行能被正常執行
$myclass->MyProtected(); // 這行會產生一個致命錯誤
$myclass->MyPrivate(); // 這行會產生一個致命錯誤
$myclass->Foo(); // 公有,受保護,私有都可以執行

class MyClass2 extends MyClass
{
    function Foo2()
    {
        $this->MyPublic();
        $this->MyProtected();
        $this->MyPrivate(); // 這行會產生一個致命錯誤
    }
}
$myclass2 = new MyClass2;
$myclass2->MyPublic(); // 這行能被正常執行
$myclass2->Foo2(); // 公有的和受保護的都可執行,但私有的不行
?>

 

繼承

  繼承已為大家所熟知的一個程序設計特性,PHP 的對象模型也使用了繼承。繼承將會影響到類與類,對象與對象之間的關系

  當擴展一個類,子類就會繼承父類所有公有的和受保護的方法。除非子類覆蓋了父類的方法,被繼承的方法都會保留其原有功能

  繼承對於功能的設計和抽象是非常有用的,而且對於類似的對象增加新功能就無須重新再寫這些公用的功能

類繼承

  一個類可以在聲明中用 extends 關鍵字繼承另一個類的方法和屬性。PHP不支持多重繼承,一個類只能繼承一個基類

  被繼承的方法和屬性可以通過用同樣的名字重新聲明被覆蓋。但是如果父類定義方法時使用了 final,則該方法不可被覆蓋

  當覆蓋方法時,參數必須保持一致否則 PHP 將發出 E_STRICT 級別的錯誤信息。但構造函數例外,構造函數可在被覆蓋時使用不同的參數

<?php
class foo
{
    public function printItem($string) 
    {
        echo 'Foo: ' . $string . PHP_EOL;
    }
    public function printPHP()
    {
        echo 'PHP is great.' . PHP_EOL;
    }
}
class bar extends foo
{
    public function printItem($string)
    {
        echo 'Bar: ' . $string . PHP_EOL;
    }
}

$foo = new foo();
$bar = new bar();
$foo->printItem('baz'); // Output: 'Foo: baz'
$foo->printPHP();       // Output: 'PHP is great' 
$bar->printItem('baz'); // Output: 'Bar: baz'
$bar->printPHP();       // Output: 'PHP is great'
?>

  在子類中,使用parent訪問父類中的被覆蓋的屬性和方法

<?php
    class Person {                      
        protected $name;            
        protected $sex;                     
        public function __construct($name=“”, $sex=“男”) { }
        public function say(){}   
    }
   class Student extends Person {  
        private $school;            
        public function __construct($name="", $sex="男", $school="") {   
            parent::__construct($name,$sex); 
            $this->school = $school;
        }
        public function say( ) {
            parent::say();     
            echo "在".$this->school."學校上學<br>";
        }   
    }
$student = new Student("張三","男",20, "edu"); 
$student->say(); 

抽象

  在面向對象語言中,一個類可以有一個或多個子類,而每個類都有至少一個公有方法作為外部代碼訪問其的接口。而抽象方法就是為了方便繼承而引入的

  當類中有一個方法,他沒有方法體,也就是沒有花括號,直接分號結束,像這種方法我們叫抽象方法,必須使用關鍵字abstract定義

public abstract function fun();

  包含這種方法的類必須是抽象類也要使用關鍵字abstract加以聲明

  定義為抽象的類不能被實例化。任何一個類,如果它裡面至少有一個方法是被聲明為抽象的,那麼這個類就必須被聲明為抽象的。被定義為抽象的方法只是聲明了其調用方式(參數),不能定義其具體的功能實現

  抽象方法的作用就是規定了子類必須有這個方法的實現,功能交給子類,只寫出結構, 而沒有具體實現,實現交給具體的子類按自己的功能去實現;抽象類的作用是要求子類的結構,所以抽象類就是一個規范

  繼承一個抽象類的時候,子類必須定義父類中的所有抽象方法;另外,這些方法的訪問控制必須和父類中一樣(或者更為寬松)。例如某個抽象方法被聲明為受保護的,那麼子類中實現的方法就應該聲明為受保護的或者公有的,而不能定義為私有的。此外方法的調用方式必須匹配,即類型和所需參數數量必須一致。例如,子類定義了一個可選參數,而父類抽象方法的聲明裡沒有,則兩者的聲明並無沖突

<?php
    abstract class Person {
        public $name;
        public $age;
        abstract function say();        
        abstract function eat();
        function run() {
            echo "11111111111111<br>";
        }
        function sleep() {
            echo "2222222222222222<br>";
        }
    }
    class StudentCn extends Person {
        function say() {
            echo "中文<br>";
        }
        function eat() {
            echo "筷子";
        }
    }
    class StudentEn extends Person {
        function say() {
            echo "english<br>";
        }
        function eat() {
            echo "刀叉";
        }
    }
    $s1 = new StudentEn();
    $s1 -> say();//english
    $s1 -> eat();//刀叉
?>

接口

  PHP與大多數面向對象編程語言一樣,不支持多重繼承,也就是說每個類只能繼承一個父類。為了解決這個這個問題,PHP引入了接口,接口的思想是指定了一個實現了該接口的類必須實現的一系列函數

  使用接口(interface),可以指定某個類必須實現哪些方法,但不需要定義這些方法的具體內容。接口是通過interface關鍵字來定義的,就像定義一個標准的類一樣,但其中定義所有的方法都是空的

  接口中定義的所有方法都必須是公有,這是接口的特性。要實現一個接口,使用 implements 操作符。類中必須實現接口中定義的所有方法,否則會報一個致命錯誤。類可以實現多個接口,用逗號來分隔多個接口的名稱。接口中也可以定義常量。接口常量和類常量的使用完全相同,但是不能被子類或子接口所覆蓋

//實現一個接口
<?php
interface iTemplate
{
    public function setVariable($name, $var);
    public function getHtml($template);
}
class Template implements iTemplate
{
    private $vars = array();
    public function setVariable($name, $var)
    {
        $this->vars[$name] = $var;
    }
    public function getHtml($template)
    {
        foreach($this->vars as $name => $value) {
            $template = str_replace('{' . $name . '}', $value, $template);
        }
 
        return $template;
    }
}
?>
//常量不能被覆蓋
<?php
interface a
{
    const b = 'Interface constant';
}
echo a::b;
// 錯誤寫法,因為常量不能被覆蓋。接口常量的概念和類常量是一樣的。
class b implements a
{
    const b = 'Class constant';
}
?>
//繼承多個接口
<?php
interface a
{
    public function foo();
}
interface b
{
    public function bar();
}
interface c extends a, b
{
    public function baz();
}
?>

 

多態

  對象的多態性是指在父類中定義的屬性或行為被子類繼承之後,可以具有不同的數據類型或表現出不同的行為。這使得同一個屬性或行為在父類及其各個子類中具有不同的語義。例如:"幾何圖形"的"繪圖"方法,"橢圓"和"多邊形"都是"幾何圖"的子類,其"繪圖"方法功能不同

單態

  說到多態,首先要提到單態設計模式,單態模式的主要作用是保證在面向對象編程設計中,一個類只能有一個實例對象存在

<?php
    class DB {
        private static $obj = null;          
        private function __construct() {  
            echo "連接數據庫成功<br>";
        }   
        public static function getInstance() {   
            if(is_null(self::$obj))                
                self::$obj = new self();           
            return self::$obj;                     
        }
        public function query($sql) {     
            echo $sql;
        }
    }
    $db = DB::getInstance();                 
    $db -> query("select * from user");   
?>

  多態展現了動態綁定的功能,也稱為“同名異式”,多態可以讓軟件在開發和維護時,達到充分的延伸性

  在php中,多態性就是指方法的重寫,一個子類可中可以重新修改父類中的某些方法,使其具有自己的特征。重寫要求子類的方法和父類的方法名稱相同,這可以通過聲明抽象類或是接口來規范

<?php
    interface USB {
        const WIDTH = 12;
        const HEIGHT = 3;            
        function load();
        function run();
        function stop();    
    }
    class Cumputer {
        function useUSB(USB $usb) {
            $usb -> load();
            $usb -> run();
            $usb -> stop();        
        }
    
    }
    class Mouse implements USB{
        function load() {
            echo "加載鼠標成功!<br>";
        }
        function run() {
            echo "運行鼠標功能!<br>";
        }
        function stop() {
            echo "鼠標工作結束!<br>";
        }
    }
    class KeyPress implements USB {
        function load() {
            echo "加載鍵盤成功!<br>";
        }
        function run() {
            echo "運行鍵盤成功!<br>";
        }
        function stop() {
            echo "停止鍵盤使用!<br>";
        }
    }
    class Worker {
        function work() {
            $c = new Cumputer();
            $m = new Mouse;
            $k = new KeyPress;
            $c->useUSB($k);
            $c->useUSB($m);
        }
    }
    $w = new Worker;
    $w -> work();
?>

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved