Object Oriented Programming
大象裝冰箱php
面向過程數組
面向對象bash
面向過程好寫, 面向對象好改函數
類實例化 ==> 對象this
對象抽象 ==> 類spa
類有屬性 ==> 面向過程 變量 age $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 |
---|---|---|---|
類外部(實例化對象) | √ | × | × |
類內部(子類) | √ | √ | × |
類內部(自身) | √ | √ | √ |
<?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();
複製代碼
<?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();
複製代碼
<?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;
複製代碼
<?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
,則不能被繼承。
<?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();
複製代碼