[PHP從小白到大牛]-033 PHP-面向對象(一)

面向對象(OOP)-Object Oriented Programming

面向對象和麪向過程

大象裝冰箱php

面向過程數組

  1. 打開冰箱門();
  2. 把大象裝進去();
  3. 關閉冰箱門();

面向對象bash

  1. 創建對象, 冰箱, 大象
    1. 冰箱.開門();
    2. 大象.進冰箱();
    3. 冰箱.關門();

面向過程好寫, 面向對象好改函數

類 對象

類實例化 ==> 對象this

對象抽象 ==> 類spa

類有屬性 ==> 面向過程 變量 nameage $sexcode

類有方法 ==> 面向過程 函數 eat() drink() whore() bet()對象

封裝繼承

把內部邏輯封裝起來, 外部只有調用的權限, 沒有修改的權限get

繼承

子類能夠繼承父類的屬性和方法

金剛鸚鵡(學舌(),毛,飛(),生長()) 鸚鵡類(學舌(),毛,飛(),生長()) ===> 鳥類(毛,飛(),生長()) ====> 生物(生長())

多態

調用者不同, 執行邏輯不一樣

如何聲明一個類

語法

[修飾符] class 類名{
	[屬性]
	[方法]
}
複製代碼

類名的命名規範(大駝峯)

<?php

class Person {
    public $name = 'xujunhao';
    public $sex = "male";
    public $age = "18";
}
複製代碼

屬性中的變量能夠初始化, 可是初始化的值, 必須是常數, 能夠直接獲取值, 不須要運算

從類實例化對象

$對象名 = new 類名() // ()可加可不加
複製代碼

調用類的屬性和方法, 用->

<?php

class Person {

    public $name = null;
    public $sex = null;
    public $age = null;

    public function eat() {
        echo "吃肉!";
    }

    public function drink() {
        echo "我要喝酒!";
    }

}

$student = new Person();

$student->drink();
複製代碼
$student->name = "zhangsan"; // 屬性賦值

echo $student->name; // 屬性調用
複製代碼

$this 當前方法或屬性的調用者

複習: 按值傳遞, 按引用傳遞

按引用傳遞

$a = 123;
$b = &$a;
$a = 456;
echo $b; // 456
複製代碼

按值傳遞

$a = 123;
$b = $a;
$a = 456;
echo $b; // 123
複製代碼

對象之間的賦值, 是按引用傳遞

<?php

class Person{
    public $name = null;
}

$student = new Person();
$teacher = $student;
$student->name = "zhangsan";
echo $teacher->name;
複製代碼

繼承

class A extends B{

}
// A是子類, B是父類
複製代碼

封裝

權限控制符, 用來修飾屬性或者方法

權限控制符 public(公共的) protected(受保護的) private(私人的)

調用位置 public protected private
類外部(實例化對象) × ×
類內部(子類) ×
類內部(自身)
  • public 均可以訪問到
<?php
// 類外部, 對象
class Person{
    public $name = "zhansan";

}
$student = new Person();
echo $student->name;
複製代碼
<?php
// 類內部, 自身
class Person{
    public $name = "zhansan";
    public function getName(){
        echo $this->name;
    }
}
$student = new Person();
echo $student->getName();
複製代碼
<?php
// 類內部, 子類
class Person{
    public $name = "zhansan";
    public function getName(){
        echo $this->name;
    }
}

class Student extends Person{
    public function test(){
        echo $this->name;
    }
}

$student = new Student();
echo $student->test();
複製代碼
  • protected 子類和自身能夠調用, 外部不能調用
<?php

class Person{
    protected $name = "zhansan";
    public function getName(){
        echo $this->name;
    }
}

class Student extends Person{
    public function test(){
        echo $this->getName(); // 子類
    }
}

$student = new Student();
echo $student->test();
複製代碼
<?php

class Person{
    protected $name = "zhansan";
    public function getName(){
        echo $this->name;
    }
}

class Student extends Person{

}

$student = new Student();
echo $student->name; // 外部不能直接調用
複製代碼
<?php
// 自身能夠調用
class Person{
    protected $name = "zhansan";
    public function getName(){
        echo $this->name;
    }
}

$student = new Person();
echo $student->getName();
複製代碼
  • privated 私人, 最嚴格的權限, 只有自身能夠調用
<?php

class Person{
    private $name = "zhansan";
    public function getName(){
        echo $this->name; // 自身能夠調用
    }
}

$student = new Person();
echo $student->getName();
複製代碼
<?php

class Person{
    private $name = "zhansan";
    public function getName(){
        echo $this->name;
    }
}

class Student extends Person{
    public function test(){
        echo $this->name; // 子類中不能調用父類的private屬性
    }
}

$student = new Student();
echo $student->test();
複製代碼
<?php

class Person{
    private $name = "zhansan";
    public function getName(){
        echo $this->name;
    }
}

class Student extends Person{
    public function test(){
        echo $this->getName();
    }
}

$student = new Person();
echo $student->name; // 類外部, 不能直接調用private屬性
複製代碼

魔術方法

構造方法__construct()

實例化對象的時候, 自動觸發

析構方法__destruct

對象銷燬的時候, 自動觸發

<?php

class Person{
    public $name = "zhansan";

    public function __construct() {
        echo "對象已經實例化了!";
    }
    
    public function __destruct() {
        echo "對象被銷燬了!";
    }

    public function getName(){
        echo $this->name;
    }
}

$student = new Person;
echo '------';
$student = null;
複製代碼
  • 觸發析構方法的三種狀況
    • 腳本結束
    • unset(對象)
    • 對象=null
<?php
// 使用構造方法, 給初始化對象時賦值
class Person{
    public $name = null;
    public $age = null;
    public $sex = null;

    public function __construct($a,$b,$c) {
        $this->name = $a;
        $this->age = $b;
        $this->sex = $c;
    }


}

$student1 = new Person('張三',18,'male');
$student2 = new Person('李四',19,'female');
$student3 = new Person('王五',20,'unknown');


echo $student1->name;
echo $student2->name;
echo $student3->name;
複製代碼

靜態屬性, 靜態方法

static 來定義靜態屬性和靜態方法, 不用實例化對象, 就能夠直接訪問, 只能用類來訪問, 使用::來調用

<?php

class Test{
    public static $course = "English";
    public static $score;
}
echo Test::$course;
複製代碼
<?php

class Test{
    public static $course = "English";
    public static $score = 0;

    public static function hello(){
        echo self::$score = 100; // 內部調用, 使用self::屬性/方法名
    }

}
echo Test::hello();
複製代碼

定義常量, 使用const關鍵字來定義一個常量, 通常常量名都是大寫的, 區分大小寫

常量不能修改值

<?php

class Test {
    const age = 123;

}


Test::age = 456; // 報錯
複製代碼

常量只能使用靜態方式來調用::

<?php

class Test {
    const age = 123;

}

$obj = Test();
echo $obj->age; // 報錯
echo Test::age; // 123
複製代碼

重載

經過魔術方法, 動態的建立類屬性和類方法

屬性重載

當調用當前環境下未定義或者不可見的類屬性或類方法時, 重載方法會被調用

  • 不可訪問的屬性賦值, 觸發__set()
<?php

class Person {
    private $sex = 'male';

    public function __set($name, $value) {
        echo $name, ' ', $value;
    }

}

$stu = new Person();
$stu->sex = 'female';
複製代碼
  • 獲取不可訪問的屬性值, 觸發__get()
<?php

class Person {
    private $sex = 'male';
    protected $age = 39;

    public function __get($name) {
        if ($name == 'age') {
            echo "年齡 不是你想看, 想看就能看";
        }
    }


}

$stu = new Person();
$stu->age;
複製代碼
  • 當對不可訪問屬性調用isset()empty()時,__isset()會被調用
<?php

class Person {
    private $sex = 'male';
    protected $age = 39;


    public function __isset($name) {
        echo $name;
    }

}

$stu = new Person();
isset($stu->sex);
複製代碼
  • 當對不可訪問屬性調用unset()時,__unset()會被調用。
<?php

class Person {
    private $sex = 'male';
    protected $age = 39;


    public function __unset($name) {
        echo "您正在嘗試銷燬一個沒有權限的屬性 $name";
        unset(this->$name);
    }
}

$stu = new Person();
unset($stu->sex);
複製代碼

方法重載

  • 在對象中調用一個不可訪問方法時,__call()會被調用。
<?php

class Person {
    private $sex = 'male';
    protected $age = 39;


    public function __call($name, $arguments) {
        var_dump($name); // 方法名字
        var_dump($arguments); // 參數數組
    }

    protected function getSex() {
        echo $this->sex;
    }
}

$stu = new Person();
$stu->getSex(1, 2, 3, 4);
複製代碼
  • 在靜態上下文中調用一個不可訪問方法時,__callStatic()會被調用
<?php

class Animal {
    private function eat() {
        echo 'eat';
    }


    public static function __callStatic($name, $arguments) {
        echo '調用不存在的--靜態--方法名是:' . $name . '參數是:';
        print_r($arguments);
    }
}

$animal = new Animal();

Animal::smile('可愛', '大笑', '微笑');
複製代碼

繼承extends

子類繼承父類全部公有的和受保護的屬性和方法子類

<?php

class People {
    public $name = "lisi";
    protected $age = 39;
    private $salary = 1000;
}

class Person extends People {

}

$P1 = new Person();
echo $P1->name;
echo $P1->age; // 報錯
echo $P1->salary; // 報錯
複製代碼

繼承關鍵字extends一個類繼承另外一個類,不能繼承多個

<?php

class People {
    public $name = "lisi";
    protected $age = 39;
    private $salary = 1000;
}

class Biology {
    public $life = 100;
    public $sex = null;
}

class Person extends People,Biology {
 	// php不支持多繼承
}
複製代碼

重寫

重寫:繼承父類中的方法,子類中定義的與父類同名的方法

當一個子類重寫其父類中的方法時,PHP不會調用父類中已被重寫的方法。是否調用父類的方法取決於子類

<?php


class Person {
    public function sayHi() {
        echo "hi";
    }
}

class Student extends Person {
    public function sayHi() {
        echo 'hello';
    }
}

$stu = new Student();
$stu->sayHi();
複製代碼

關鍵字parent::訪問父類中的被重寫的屬性和方法

能夠父類原有的代碼上追加新的代碼

<?php


class Person {
    public function sayHi() {
        echo "hi";
    }
}

class Student extends Person {
    public function sayHi() {
        parent::sayHi();
        echo " and say Hello";
    }
}

$stu = new Student();
$stu->sayHi();
複製代碼

final

若是一個類被聲明爲final,則不能被繼承。

<?php

final class Person{
    public $name = 'lisi';
}

class Student extends Person{
    public $sex = 'male';
} // 報錯, 不能繼承
複製代碼
<?php

// 去掉final, 則沒有問題
class Person {
    public $name = 'lisi';
}

class Student extends Person {
    public $sex = 'male';
}
複製代碼

若是父類中的方法被聲明爲final,則子類沒法重寫該方法。

<?php

// 繼承父類的方法
class Person {
    public $name = 'lisi';

    public function getName() {
        echo $this->name;
    }
}

class Student extends Person {
    public function getName() {
        parent::getName();
        echo "\n";
        echo "能夠繼承父類!";
    }
}

$stu = new Student();
$stu->getName();
複製代碼

一樣的代碼, 若是在getName函數前, 添加final, 則會報錯

<?php


class Person {
    public $name = 'lisi';

    final public function getName() // 會報錯 {
        echo $this->name;
    }
}

class Student extends Person {
    public function getName() {
        parent::getName();
        echo "\n";
        echo "能夠繼承父類!";
    }
}

$stu = new Student();
$stu->getName();
複製代碼
相關文章
相關標籤/搜索