進階篇/Chapter 3

類和對象

類是面向?qū)ο蟪绦蛟O(shè)計的基本概念。類是一類東西的結(jié)構(gòu)描述策精,而對象則是一類東西的一個具體實例舰始。
通俗的理解:汽車可以抽象為一個類,汽車擁有名字咽袜、輪胎丸卷、速度、重量等屬性询刹,可以有換擋谜嫉、前進、后退等操作方法凹联。而我的Fiat 500C沐兰,你的Porsche或Golf都是類具體化之后的對象。

// 定義一個汽車類
class Car {
    $name = '汽車';
    function getName() {
        return $this->name;
    }
}

// 通過new關(guān)鍵字對類進行實例化
$car = new Car();
echo $car->getName();

語法:

//定義一個類
class Car {
    //定義屬性
    public $name = '汽車';

    //定義方法
    public function getName() {
        //方法內(nèi)部可以使用$this偽變量調(diào)用對象的屬性或者方法
        return $this->name;
    }
}

類的屬性

在類中定義的變量稱之為屬性匕垫。屬性聲明是由關(guān)鍵字public僧鲁,protected 或者 private 開頭,后面跟一個普通的變量聲明來組成。

public:公開的
protected:受保護的
private:私有的

注意:外部只能訪問public屬性寞秃,protected和private都不允許外部的訪問U宓稹!

舉例:

class Car {
    //定義公共屬性
    public $name = '汽車';
    //定義受保護的屬性
    protected $corlor = '白色';
    //定義私有屬性
    private $price = '100000';
}

$car = new Car();
echo $car->name;   //調(diào)用對象的屬性
echo $car->color;  // ! 錯誤 受保護的屬性不允許外部調(diào)用
echo $car->price;  // ! 錯誤 私有屬性不允許外部調(diào)用

類的方法

方法就是在類中的function春寿,很多時候我們分不清方法與函數(shù)有什么差別朗涩,在面向過程的程序設(shè)計中function叫做函數(shù),在面向?qū)ο笾衒unction則被稱之為方法绑改。
同屬性一樣谢床,類的方法也具有publicprotected 以及private的訪問控制厘线。
舉例:

class Car {
    public $speed = 0;
    //增加speedUp方法识腿,使speed加10
    public function speedUp(){
        $this->speed+=10;
    }
}

$car = new Car();
$car->speedUp();
echo $car->speed;

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

PHP5在類中使用__construct()定義一個構(gòu)造函數(shù):會在每次對象創(chuàng)建的時候調(diào)用該函數(shù),因此常用來在對象創(chuàng)建的時候進行一些初始化工作造壮。

class Car {
   function __construct() {
       print "構(gòu)造函數(shù)被調(diào)用\n";
   }
}
$car = new Car(); // 實例化的時候 會自動調(diào)用構(gòu)造函數(shù)__construct渡讼,這里會輸出一個字符串

注意:在子類中如果定義了__construct則不會調(diào)用父類的__construct,如果需要同時調(diào)用父類的構(gòu)造函數(shù)耳璧,需要使用parent::__construct()顯式的調(diào)用成箫。

class Car {
   function __construct() {
       print "父類構(gòu)造函數(shù)被調(diào)用\n";
   }
}
class Truck extends Car {
   function __construct() {
       print "子類構(gòu)造函數(shù)被調(diào)用\n";
       parent::__construct();
   }
}
$car = new Truck();

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

PHP5支持析構(gòu)函數(shù),使用__destruct()進行定義旨枯,析構(gòu)函數(shù)指的是當(dāng)某個對象的所有引用被刪除蹬昌,或者對象被顯式的銷毀時會執(zhí)行的函數(shù)。

class Car {
   function __construct() {
       print "構(gòu)造函數(shù)被調(diào)用 \n";
   }
   function __destruct() {
       print "析構(gòu)函數(shù)被調(diào)用 \n";
   }
}
$car = new Car(); //實例化時會調(diào)用構(gòu)造函數(shù)
echo '使用后攀隔,準(zhǔn)備銷毀car對象 \n';
unset($car); //銷毀時會調(diào)用析構(gòu)函數(shù)

Tipp: 當(dāng)PHP代碼執(zhí)行完畢以后皂贩,會自動回收與銷毀對象,因此一般情況下不需要顯式的去銷毀對象竞慢。

Static 靜態(tài)

靜態(tài) 屬性與方法可以在不實例化類的情況下調(diào)用先紫,直接使用類名::方法名的方式進行調(diào)用治泥。

class Car {
    private static $speed = 10;
    
    public static function getSpeed() {
        return self::$speed;
    }
}
echo Car::getSpeed(); 

靜態(tài)方法也可以通過變量來進行動態(tài)/可變調(diào)用:

$func = 'getSpeed';
$className = 'Car';
echo $className::$func();  //動態(tài)調(diào)用靜態(tài)方法

注意:
1)靜態(tài)屬性不允許對象使用->操作符調(diào)用筹煮。用::代替
2)靜態(tài)方法中,$this偽變量不允許使用居夹“芰剩可以使用selfparent准脂,static在內(nèi)部調(diào)用靜態(tài)方法與屬性劫扒。

class Car {
    private static $speed = 10;
    public static function getSpeed() {
        return self::$speed;
    }
    public static function speedUp() {
        return self::$speed+=10;
    }
}

class BigCar extends Car {
    public static function start() {
        parent::speedUp();
    }
}

BigCar::start();
echo BigCar::getSpeed();

訪問控制

前面的小節(jié),我們已經(jīng)接觸過訪問控制了狸膏,訪問控制通過關(guān)鍵字public沟饥,protectedprivate來實現(xiàn)。
public:可以在任何地方被訪問
protected:可以被其自身以及其子類和父類訪問
private:只能被其定義所在的類訪問

注意: 類屬性和方法必須定義為公有、受保護贤旷、私有之一广料。未定義的情況下,兩者默認都為public幼驶。

私人構(gòu)造函數(shù) private function __construct

如果構(gòu)造函數(shù)定義成了私有艾杏,則不允許直接實例化對象了。
==> 這時候一般通過 靜態(tài)方法getInstance() 進行實例化
在設(shè)計模式中會經(jīng)常使用這樣的方法來控制對象的創(chuàng)建盅藻,比如單例模式只允許有一個全局唯一的對象购桑。
舉例:

class Car {
    private function __construct() {
        echo 'object create';
    }

    private static $_object = null;
    public static function getInstance() {
        if (empty(self::$_object)) {
            self::$_object = new Car(); //內(nèi)部方法可以調(diào)用私有方法,因此這里可以創(chuàng)建對象
        }
        return self::$_object;
    }
}
//$car = new Car(); //這里不允許直接實例化對象
$car = Car::getInstance(); //通過靜態(tài)方法來獲得一個實例

繼承

繼承是面向?qū)ο蟪绦蛟O(shè)計中常用的一個特性氏淑,汽車是一個比較大的類勃蜘,我們也可以稱之為基類,除此之外假残,汽車還分為卡車元旬、轎車,因為這些子類具有很多相同的屬性和方法守问,可以采用繼承汽車類來共享這些屬性與方法匀归,實現(xiàn)代碼的復(fù)用。
舉例:Truck的速度比基類Car的速度快50耗帕。

class Car {
    public $speed = 0; //汽車的起始速度是0
    
    public function speedUp() {
        $this->speed += 10;
        return $this->speed;
    }
}
//定義繼承于Car的Truck類
class Truck extends Car{
    public function speedUp(){
                $this->speed=parent::speedUp() + 50;
    }
}

$car = new Truck();
$car->speedUp();
echo $car->speed;

重載

PHP中的重載指的是動態(tài)的創(chuàng)建屬性與方法穆端,是通過魔術(shù)方法來實現(xiàn)的。
1)屬性的重載
通過__set仿便,__get体啰,__isset__unset來分別實現(xiàn)對不存在屬性的賦值嗽仪、讀取荒勇、判斷屬性是否設(shè)置、銷毀屬性闻坚。

class Car {
    private $ary = array();
    
    public function __set($key, $val) {
        $this->ary[$key] = $val;
    }
    
    public function __get($key) {
        if (isset($this->ary[$key])) {
            return $this->ary[$key];
        }
        return null;
    }
    
    public function __isset($key) {
        if (isset($this->ary[$key])) {
            return true;
        }
        return false;
    }
    
    public function __unset($key) {
        unset($this->ary[$key]);
    }
}
$car = new Car();
$car->name = '汽車';  // name屬性動態(tài)創(chuàng)建并賦值
echo $car->name;

2)方法的重載
方法的重載通過__call來實現(xiàn)沽翔,
=> 調(diào)用不存在的方法的時候,將會轉(zhuǎn)為參數(shù)調(diào)用__call方法
=> 調(diào)用不存在的靜態(tài)方法 時會使用__callStatic重載窿凤。

class Car {
    public $speed = 10;

    //在這里使用重載實現(xiàn)speedDown方法
    public function __call($name, $args){
        if($name == 'speedDown'){
            $this->speed-=10;
        }
    }
}
$car = new Car();
$car->speedDown(); //調(diào)用不存在的speedDown方法
echo $car->speed;

對象復(fù)制

在一些特殊情況下仅偎,可以通過關(guān)鍵字clone來復(fù)制一個對象,這時__clone方法會被調(diào)用雳殊,通過這個魔術(shù)方法來設(shè)置屬性的值橘沥。

class Car {
    public $name = 'car';
    
    public function __clone() {
        $obj = new Car();
        $obj->name = $this->name;
    }
}
$a = new Car();
$a->name = 'new car';
$b = clone $a;
var_dump($b);

對象序列化

對象序列化,可以通過serialize方法將對象 序列化 為字符串夯秃,用于存儲或者傳遞數(shù)據(jù)座咆,然后在需要的時候通過unserialize將字符串 反序列化 成對象進行使用痢艺。

class Car {
    public $name = 'car';
}
$a = new Car();
$str = serialize($a); //對象序列化成字符串
echo $str.'<br>';
$b = unserialize($str); //反序列化為對象
var_dump($b);

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市介陶,隨后出現(xiàn)的幾起案子腹备,更是在濱河造成了極大的恐慌,老刑警劉巖斤蔓,帶你破解...
    沈念sama閱讀 219,427評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件植酥,死亡現(xiàn)場離奇詭異,居然都是意外死亡弦牡,警方通過查閱死者的電腦和手機友驮,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來驾锰,“玉大人卸留,你說我怎么就攤上這事⊥衷ィ” “怎么了耻瑟?”我有些...
    開封第一講書人閱讀 165,747評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長赏酥。 經(jīng)常有香客問我喳整,道長,這世上最難降的妖魔是什么裸扶? 我笑而不...
    開封第一講書人閱讀 58,939評論 1 295
  • 正文 為了忘掉前任框都,我火速辦了婚禮,結(jié)果婚禮上呵晨,老公的妹妹穿的比我還像新娘魏保。我一直安慰自己,他們只是感情好摸屠,可當(dāng)我...
    茶點故事閱讀 67,955評論 6 392
  • 文/花漫 我一把揭開白布谓罗。 她就那樣靜靜地躺著,像睡著了一般季二。 火紅的嫁衣襯著肌膚如雪檩咱。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,737評論 1 305
  • 那天戒傻,我揣著相機與錄音税手,去河邊找鬼蜂筹。 笑死需纳,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的艺挪。 我是一名探鬼主播不翩,決...
    沈念sama閱讀 40,448評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼兵扬,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了口蝠?” 一聲冷哼從身側(cè)響起器钟,我...
    開封第一講書人閱讀 39,352評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎妙蔗,沒想到半個月后傲霸,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,834評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡眉反,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,992評論 3 338
  • 正文 我和宋清朗相戀三年昙啄,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片寸五。...
    茶點故事閱讀 40,133評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡梳凛,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出梳杏,到底是詐尸還是另有隱情韧拒,我是刑警寧澤,帶...
    沈念sama閱讀 35,815評論 5 346
  • 正文 年R本政府宣布十性,位于F島的核電站叛溢,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏劲适。R本人自食惡果不足惜雇初,卻給世界環(huán)境...
    茶點故事閱讀 41,477評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望减响。 院中可真熱鬧靖诗,春花似錦、人聲如沸支示。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,022評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽颂鸿。三九已至促绵,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間嘴纺,已是汗流浹背败晴。 一陣腳步聲響...
    開封第一講書人閱讀 33,147評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留栽渴,地道東北人尖坤。 一個月前我還...
    沈念sama閱讀 48,398評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像闲擦,于是被迫代替她去往敵國和親慢味。 傳聞我的和親對象是個殘疾皇子场梆,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,077評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法纯路,內(nèi)部類的語法或油,繼承相關(guān)的語法,異常的語法驰唬,線程的語...
    子非魚_t_閱讀 31,644評論 18 399
  • 前言 把《C++ Primer》[https://book.douban.com/subject/25708312...
    尤汐Yogy閱讀 9,519評論 1 51
  • 前言 人生苦多顶岸,快來 Kotlin ,快速學(xué)習(xí)Kotlin叫编! 什么是Kotlin蜕琴? Kotlin 是種靜態(tài)類型編程...
    任半生囂狂閱讀 26,215評論 9 118
  • { "Unterminated string literal.": "未終止的字符串文本。", "Identifi...
    Elbert_Z閱讀 10,839評論 0 2
  • 撥片在抽屜里宵溅,吉他矗在墻角凌简,偶爾發(fā)出一點低沉的聲音,因為沒有多余的空間給它恃逻,需要挪來挪去雏搂,我嫌棄,它也煩寇损。...
    鬼二er閱讀 140評論 0 0