4面向?qū)ο?/h2>

[TOC]

面向?qū)ο?/h1>

1. 面向?qū)ο蟮幕靖拍?/h2>

1.1 什么是面向?qū)ο缶幊獭?/h3>

準(zhǔn)確的說面向?qū)ο缶幊涛覀兘?OOP.面向?qū)ο蟮木幊谭譃槿糠郑好嫦驅(qū)ο蠓治觯∣bject Oriented Analysis,OOA)、面向?qū)ο笤O(shè)計(Object Oriented Design,OOD),以及面向?qū)ο缶幊蹋∣bject Oriented Programming)。面向?qū)ο缶幊痰膬蓚€中個重要的概念是類和對象。

1.2. 類

世間萬物皆對象,萬事萬物皆對象。當(dāng)然,這是在 js 當(dāng)中的一個概念。在其他的編程語言當(dāng)中,我們說時間萬物都具有它自身的屬性和方法,通過這些屬性和方法,可以將不同的事物區(qū)分開來,這就是我們在座的面向?qū)ο箢惖某橄?。例?人具有身高。體重和膚色等等這些屬性。還可以吃飯,學(xué)習(xí)走路可以做一些活動。這些活動就是人具有的功能。而前面所說的體重,膚色,身高等等這些是什么呢?是屬性。所以我們就可以把人看作是程序當(dāng)中的一個類。那么人的身高可以看做什么?可以看做類的屬性走路啊,吃飯呀,可以看做類的方法。所以什么是類,類是屬性和方法的集合.是面向?qū)ο缶幊套詈诵牡臇|西。也是它的基礎(chǔ)。所以通過類呢,我們可以將一些零散的用來去實(shí)現(xiàn)某一個功能的代碼進(jìn)行一些管理。比如說,我們可以創(chuàng)建一個運(yùn)動類。愛運(yùn)動類里面包括有這么些個屬性姓名身高體重年齡。和性別,然后我再定義幾個方法,他能踢足球,他能打籃球啊,能舉重能跳高。能吃能玩。

1.3. 對象

類只是具備某項功能。一個抽象模型實(shí)際應(yīng)用當(dāng)中呢,我們需要使用的是對象。所以我們就需要從那當(dāng)中去實(shí)例化出來這個對象,然后去使用這些對象。對象呢,是類進(jìn)行實(shí)例化之后的一個產(chǎn)物。它是一個實(shí)體,是一個獨(dú)立的個體。例如,我們?nèi)匀灰匀藶槔?黃種人是人"這句話里邊兒。沒有錯誤對吧,但是反過來說 "人是黃種人",就有問題,因為除了黃種人,還有白人,黑人等就,這里的"黃種人"就是"人"這個類中的一個實(shí)例對象。

1.4. 面向?qū)ο蟮娜筇卣?/h3>

面向?qū)ο缶幊痰拇蟠筇卣骶褪欠庋b性,繼承性,多態(tài)性

1.4.1. 封裝性

封裝性也可稱之為信息隱藏,就是把一個類的使用和實(shí)現(xiàn)分開,只保留有限的接口(方法)與外部練習(xí)。同時也避免程序之間的 相互依賴而產(chǎn)生的不便。

1.4.2. 繼承性

繼承性就是派生類(子類)自動繼承一個或多個基類(父類)中的屬性與方法。并且我們可以重寫和添加新的屬性方法??梢院喕瘜ο蠛皖惖膭?chuàng)建,提高代碼的可復(fù)用性,繼承分單繼承和多繼承。PHP 中支持的是單繼承。一個子類有且只有一個父類。

1.4.3. 多態(tài)性

同一個類的不同對象,調(diào)用一個方法可以獲得不同的結(jié)果。增強(qiáng)程序的靈活性和重用性。

2. PHP 對象

2.1. 類的定義

和很多其他面向?qū)ο蟮恼Z言一樣,PHP 通過 class 關(guān)鍵字加類名來定義類。

<?php
class SportObject{
    // ----
}
?>

2.2. 成員方法

類中的函數(shù)被稱為成員方法,函數(shù)與成員方法唯一的區(qū)別就是函數(shù)實(shí)現(xiàn)的是某個獨(dú)立的功能。而成員方法實(shí)現(xiàn)的是類的一個行為,它是類的其中一部分。
關(guān)鍵字(修飾符) 成員方法

<?php
class SportObject{
    function bealBasketBall($name,$age,$height,$sex){
        echo $name.'<br>';
        echo $age.'<br>';
        echo $height.'<br>';
        // return ;
    }
}
?>

2.3. 類的實(shí)例化

首先我們要實(shí)例化對象(通過 new 關(guān)鍵字 實(shí)例化對象),才能通過對象執(zhí)行對應(yīng)的行為方法。通過對象->成員方法 來調(diào)用成員方法。

<?php
class SportObject{
    function bealBasketBall($name,$age,$height,$sex){
        if($height>=180){
            return $name.'符合打籃球的身體素質(zhì)要求!';
        }else{
            return $name.'不符合打籃球的身體素質(zhì)要求!';
        }
    }
}
$s1=new SportObject();
echo $s1->bealBasketBall('曾輝',20,170,'男');
$s2=new SportObject();
echo $s1->bealBasketBall('曾輝2號',40,181,'男');
?>

2.4. 成員變量

類中的變量,也稱為成員變量。有些人也把它叫做屬性或者字段。成員變量的是用來保存數(shù)據(jù)信息?;蛘吲c成員方法進(jìn)行一些交互來實(shí)現(xiàn)某項功能。
定義成員變量和成員方法:
關(guān)鍵字(修飾符) 成員變量名

關(guān)鍵字可以使用public ,private, protected, static 中的任意一個。

訪問成員變量和成員方法的方法一樣,對象->成員變量

class SportObject{
    // 聲明成員變量。
    public $name;
    public $height;
    public $sex;
    public function boolFootBall($name,$height,$sex){
            return $name.'是個足球運(yùn)動員';
    }
}
$s1=new SportObject;
$s1->name='佚名';
var_dump($s1);
// $s1->boolFootBall('佚名');

<table> <tr><td bgColor="orange"><strong>注: this-> 所用是調(diào)用本類中的 成員變量或成員方法。 無論使用的是"this->" 還是"對象名->"哪種格式,后面的變量名是沒有$符號的.
</strong></td></tr></table>

2.5. 類常量

常量是在程序運(yùn)行期間,不可改變的量,我們說他是一個恒值,舉例圓周率就是一個常量。定義常量,我們使用關(guān)鍵字 const。

class SportObject{
    const SPORT_TYPE="體育運(yùn)動";
    public $name;
    function setName($name){
        $this->name=$name;
    }
    function getName(){
        return $this->name;
    }
}
$s1=new SportObject;
$s1->setName('aaa');
echo $s1->getName().'<br>';
echo $s1->name.'<br>';
echo SportObject::SPORT_TYPE.'通過類::常量名';

2.6 構(gòu)造函數(shù)和析構(gòu)函數(shù)

2.6.1 構(gòu)造函數(shù)

當(dāng)一個類實(shí)例化為一個對象的時候,可能可能會隨著對象的初始化而初始化一些成員變量。就是給一些成員變量復(fù)制值。這種情況下我們就可以使用構(gòu)造函數(shù)。因為咱對象實(shí)例化過程當(dāng)中構(gòu)造函數(shù)是自動執(zhí)行的。

class Person{
    public $name;
    public $age;
    public $sex;
    public $height;
    // 我們可以通過"__construct()"
    public function __construct(){
        echo '123';
    }
}

$p1=new Person;
// 如果成員變量過多,寫起來比較麻煩
// $p1->name='aa';

構(gòu)造函數(shù)是在初始化對象時使用的,如果類中沒有構(gòu)造方法,PHP 會自動生成一個構(gòu)造函數(shù),自動生成的構(gòu)造方法是沒有參數(shù)的。

2.6.2 析構(gòu)函數(shù)

析構(gòu)函數(shù)的作用和構(gòu)造方法方法剛好相反,是對象被銷毀時被調(diào)用的,作用呢是釋放內(nèi)存。

<?php
class Person{
    public $name;
    public $age;
    public $sex;
    public $height;
    // 我們可以通過"__construct()"
    // 構(gòu)造函數(shù)
    public function __construct($name,$height,$age,$sex){
        // 為成員變量賦值。
        $this->name=$name;
        $this->height=$height;
        $this->age=$age;
        $this->sex=$sex;
        echo $this->sayHi();
    }
    public function sayHi(){
        return "你好,我叫$this->name ,我今年$this->age 歲了,身高$this->height,性別$this->sex";
    }
    // 析構(gòu)函數(shù)
    public function __destruct(){
        echo '已經(jīng)被釋放掉了';
    }
}
$p2=new Person("佚名",180,23,'女');

2.7 繼承和多態(tài)

其實(shí)繼承和多態(tài)啊最根本的作用就是完成代碼的重用。

2.7.1 繼承

子類繼承父類的所有成員變量方法,包括構(gòu)造方法,當(dāng)子類被實(shí)例化的時候,PHP 會先在子類當(dāng)中找構(gòu)造方法,如果子類已經(jīng)有自己的構(gòu)造方法。PHP 會先調(diào)用子類的方法。當(dāng)子類當(dāng)中沒有的時候,PHP 才會去調(diào)用。父類當(dāng)中的構(gòu)造方法,這就是繼承。

// 父類(基類)
class SportClass{
    // 定義成員變量
    public $name;//姓名
    public $age;//年齡
    public $weight;//體重
    public $sex;//性別
    public function __construct($name,$age,$weight,$sex){
        $this->name=$name;
        $this->age=$age;
        $this->weight=$weight;
        $this->sex=$sex;
    }
    function sayHi(){
        echo '你好,我是'.$this->name;
    }
}

/**子類(派生類)BealBasketBall*/
class BealBasketBall extends SportClass{//定義子類,繼承父類
    // 定義成員變量  身高
    public $height;
    public function __construct($name,$height){
        $this->height=$height;
        $this->name=$name;
    }  
    
    // function sayHi(){
    //     echo '你好,我是'.$this->name;
    // }
}

$b1=new BealBasketBall('曾輝',198);

2.7.2 多態(tài)

多態(tài)好比有一個成員,方法是讓大家去游泳,這時有人帶著游泳圈還有人拿著浮板。還有人什么也不帶。雖然是同一種方法,但是卻產(chǎn)生了不同的形態(tài),這就叫多態(tài)。

多態(tài)存在兩種形式,覆蓋和重載。
1).所謂的覆蓋,在子類中重寫父類的方法。而在子類的對象當(dāng)中,雖然調(diào)用的是父類當(dāng)中相同的方法,但返回的結(jié)果是不一樣的。你看啊,上面的那個例子當(dāng)中都調(diào)用了父類當(dāng)中的說明方法。但是返回的結(jié)果卻不同。
2).再就是重載,重載是類的多態(tài)的另外一種體現(xiàn)。函數(shù)在重載的時候會有一個標(biāo)識符。被當(dāng)做多個函數(shù)名稱。而且呢,能夠通過函數(shù)的參數(shù)的個數(shù)或者參數(shù)的類型,將這些同名的函數(shù)區(qū)分開來,(方法名稱是相同的),可能是參數(shù)的數(shù)量或者參數(shù)的類型不同。以便于去使用和調(diào)用的時候不發(fā)生混淆。
PHP所提供的重載(overloading)是指動態(tài)地創(chuàng)建類屬性和方法。我們是通過魔術(shù)方法(magic methods)來實(shí)現(xiàn)的。

class A{
    function __call($name,$num){
        echo "方法名稱:".$name.'<br>';
        echo '參數(shù)存在的個數(shù):'.count($num).'<br>';
        if(count($num)==1){
            echo $this->list1();
        }
        if(count($num)==2){
            echo $this->list2();
        }
    }

    public function list1($a){
        return "這是list1函數(shù),:參數(shù):$a";
    }
    public function list2($a,$b){
        return "這是list1函數(shù),:參數(shù)1:$a ,參數(shù)2:$b ";
    }
}

$a=new A;
$a->list(1);

2.8 "$this->" 和"::"的使用

PHP通過為變量"this->"和作用域操作符"::"來實(shí)現(xiàn)訪問自己的成員變量和成員方法的。 **1.this->**
在本類內(nèi)部我們可以通過"this" 訪問當(dāng)前類實(shí)例化的對象。調(diào)用方法或成員變量的話,則使用"this->成員變量"||"this->成員方法" 來訪問成員方法和變量。所以"this->"只在類的內(nèi)部使用

class Demo{
    function exam(){
        if(isset($this)){
            echo '$this的值:'.get_class($this);
        }else{
            echo '$this 未定義';
        }
    }
}
$d1=new Demo;
$d1->exam();

2. 操作符::
$this只能在類的內(nèi)部去使用。操作符"::"可以在沒有聲明任何實(shí)例的情況下,訪問類當(dāng)中的成員方法或成員變量。

關(guān)鍵字::變量名/常量名/方法名

關(guān)鍵字有三種情況:

  • parent: 可以調(diào)用父類中的 成員變量,成員方法和常量
  • self:可以調(diào)用當(dāng)前類中的 靜態(tài)成員和常量
  • 類名:可以調(diào)用本類中的靜態(tài)變量,常量和靜態(tài)方法
class A{
    const NAME_='A';
    public $name;
    public $age;
    public $sex;
    public function __construct($name,$age,$sex){
        $this->name=$name;
        $this->age=$age;
        $this->sex=$sex;
    }
}

class B extends A{
    const NAME_='B';
    public $height;
    public $weight;
    public function __construct($name,$age,$sex,$height,$weight){
        parent::__construct($name,$age,$sex);  
        $this->height=$height;
        $this->weight=$weight;
    }
    public function a(){
        self::NAME_;
        parent::NAME_;
    }
}
$b1=new B('姓名','年齡','xingbie','身高','體重');
B::NAME_;

2.9 修飾符

public、private、protected、static和final。這些關(guān)鍵字是用來限定類成員(包括方法和變量)的訪問權(quán)限。

2.9.1 public(公共成員)

顧名思義就是可以公開的,沒有必要去隱藏的一些數(shù)據(jù)信息。可以用public來去修飾當(dāng)前的成員方法或者成員變量。它可以在程序的任何位置出現(xiàn)(類的內(nèi)部,類的外部)??梢员黄渌念惡蛯ο笕フ{(diào)用。子類呢可以繼承和使用父類當(dāng)中所有的,公共成員。

class Person{
    public $name="李雷";
    public function fn(){
        // 1.可以在類的內(nèi)部訪問,對當(dāng)前類的 內(nèi)部可見
        echo $this->name;
    }
}

class Students extends Person{
    public function fn1(){
        // 2.可以在子類的內(nèi)部訪問,對子類的內(nèi)部可見
        echo $this->name;   
        $this->fn();
    }
}
// 3.在類的外部可見
$s1=new Person();
$s1->fn();
$s2=new Students();
$s2->fn();
$s2->fn1();

2.9.2 private(私有成員)

被private關(guān)鍵字所修飾的成員方法和變量,只能在所屬類的內(nèi)部被調(diào)用和修改,不可以在類外部訪問,在子類中也不可以。

<?php
class Book{
    private $name='HTML';
    public function setName($name){
        // 1.在當(dāng)前類內(nèi)部 可訪問
        $this->name=$name;
    }
    public function getName(){
        echo $this->name;
    }
    private function c1(){
        echo '123';
    }
}

class Histoty extends Book{
    public function getBookName(){
        // 2.在子類內(nèi)部不可見 不可訪問繼承來的父類中的私有成員變量 私有方法
        echo $this->name;
        $this->c1();
    }
}
// $b1=new Book;
// $b1->setName('PHP');
// $b1->getName();
// 3.在類的外部不可訪問 私有成員變量或私有成員方法
// $b1->name='js';
// $b1->c1();

$h1=new Histoty();
$h1->getBookName();

對于成員方法和成員變量,如果沒有指定關(guān)鍵字,那就默認(rèn)是public。

2.9.3 protected(保護(hù)成員)

被protected 修飾的類成員,可以在當(dāng)前類和子類中被調(diào)用。去其他地方則不可以訪問。

class Person{
    protected $money=10;
    public function fn(){
        echo $this->money;
        // 1.在當(dāng)前的內(nèi)部可以訪問
    }
}
class Stu extends Person{
    public function fn1(){
        echo $this->money;
        // 2. 可以在子類的內(nèi)部訪問
    }
}
// 3. 在類的外部不能直接訪問,
$p1=new Person;
$p1->fn();
// echo $p1->money;
$s1=new Stu;
$s1->fn1();

2.10 靜態(tài)成員(變量,方法)

不是所有的方法都要通過創(chuàng)建對象來去調(diào)用的,我們可以。通過給變量或者方法加上static關(guān)鍵字來直接調(diào)用。也叫做訪問靜態(tài)成員。

關(guān)鍵字::靜態(tài)成員

關(guān)鍵字可以有兩種:

  • self,在類的內(nèi)部調(diào)用靜態(tài)成員是使用。
  • 靜態(tài)成員所在的類名,在類的外部調(diào)用類內(nèi)部的靜態(tài)成員時所使用。
    在靜態(tài)方法當(dāng)中只能調(diào)用靜態(tài)變量,而不能調(diào)用普通的變量。而普通方法里面可以調(diào)用靜態(tài)變量。
    使用靜態(tài)成員,除了可以不需要實(shí)例化對象外,另一個作用就是在對象被銷毀后,仍然保留被修改的靜態(tài)數(shù)據(jù),以便于下次繼續(xù)使用。
class Book{
    static $num=0;//聲明一個靜態(tài)變量$num,初始值為0;
    public function showMe(){
        echo '您是第'.self::$num.'位訪客';
        self::$num++;//
    }
}
$b1=new Book();
$b1->showMe();
$b2=new Book();
$b2->showMe();
echo '一共有'.Book::$num.'位訪客';

2.11 final 關(guān)鍵字

被final修飾過的類和方法就是"最終的版本",如果類被final修飾過,該類不可以再被繼承,也不能再有子類。

final class Book{
    public $name='';
    public function __construct($name){
        $this->name=$name;
    }
}
class Histoty extends Book{
    public $height='';   
}
//結(jié)果: Fatal error: Class Histoty may not inherit from final class (Book)

如果方法被final修飾過,方法在子類中不可以進(jìn)行重寫,也不可能被覆蓋。


class Book{
    public $name='';
    public function __construct($name){
        $this->name=$name;
    }
    final public function getName(){
        echo $this->name;
    }
}
class Histoty extends Book{
    public $height='';   
    public function  getName(){
        echo '123';
    }
}
//結(jié)果:Fatal error: Cannot override final method Book::getName() in
 

2.12 對象類型檢測

instanceof操作符可以檢測當(dāng)前對象是屬于哪一個類。

ObjectName instanceof ClassName
class Book{
    public $name='';
    public function __construct($name='佚名'){
        $this->name=$name;
    }
}
class History{

}
$a=new Book;
$b=new History;
// var_dump($a instanceof Book);//true
var_dump($b instanceof Book);//false

3.魔術(shù)方法(__)

3.1 __get和__set() 方法

這兩個魔術(shù)方法的作用分別是:

  • 當(dāng)程序試圖去寫入一個不存在或者不可見的成員變量的時候PHP就會執(zhí)行__set()方法。__set()方法呢,包括有兩個參數(shù),分別是變量名稱和變量的值,這兩個參數(shù)不可省略。

  • 當(dāng)程序調(diào)用一個未定義或者不可見的成員變量的時候,可以通過__get()方法來去讀取變量的值.__get()這個方法有一個參數(shù)表示你要調(diào)用的這個變量名稱。

<?php
class SportClass{
    public $height='1231';
    private $type='21312';
    public function __get($name){
        if(isset($this->$name)){//判斷變量是否被聲明
            echo '變量'.$name.'值:'.$this->$name.'<br>';
        }else{
            echo '變量'.$name.'未定義';
            $this->$name=0;
            echo $this->$name;
        }
    }
    public function __set($name,$value){
        if(isset($this->$name)){
            echo '私有成員';
            echo '變量'.$name.'賦值:'.$value.'<br>';
        }else{
            $this->$name=$value;
            echo '變量不存在';
        }
    }
}
$b=new SportClass();
// echo $b->type;
// echo $b->sex;
// $b->type='213';
$b->sex=234;
echo $b->sex;

3.2 __tostring()方法

當(dāng)使用echo或print輸出對象時,將對象轉(zhuǎn)化為字符串。

class SportClass{
    private $type='21312';
    public function __tostring(){
        return $this->type;
    }
}
$b=new SportClass;
echo $b;

3.3 __autoload()方法

嘗試加載未定義的類是,觸發(fā)__autoload()方法,__autoload()接受一個參數(shù),參數(shù)是類的名稱。

function __autoload($classname){
    $class_path=lcfirst($classname).'Class.php';
    if(file_exists($class_path)){
        include_once($class_path);
    }
}


$b=new BaseFile;
var_dump($b);
$c=new Base();
var_dump($c);

3.4 中文字符串截取類

在Php當(dāng)中??!我們經(jīng)常要去對字符串進(jìn)行一些截取。如果是英文字符串的話,我們可以直接使用substr()函數(shù)來去完成。但是當(dāng)出現(xiàn)中文字符串的時候,如果你依然使用這個substr()函數(shù),就有可能會出現(xiàn)亂碼的情況。因為一個漢字是由兩個字節(jié)組成的。所以當(dāng)截取的字符如果出現(xiàn)奇數(shù)的時候,就有可能將一個漢字給拆分開來。從而導(dǎo)致輸出一個不完整的漢字,顯示出來就是亂碼。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容