php 面向对象编程(class)之从入门到崩溃 基础篇

一、面向对象的发展历程

学习目标:理解面向对象编程思想,了解计算机编程语言的演变过程,掌握PHP面向对象的基础语法,使用面向对象编程思想和面向对象语法实现编程解决需求问题

编程语法发展史:计算机编程在历史的发展长河中,经历了多次版本变革,变化的轨迹是伴随着硬件的发展和人们对于计算机的认知以及需求。

  • 机器语言:即开发者(科学家)使用01组成命令,然后在特定计算机上执行

    • 优点:执行效率高

    • 缺点:开发难度大、移植性差、开发成本高

  • 汇编语言:开发者使用简洁英文字母符号组成,让计算机读取后根据符号进行加工执行

    • 优点:指令简单明了、推广性高
    • 缺点:移植性差、功能简单
  • 高级计算机语言:开发者使用类似自然语言的符号组成,高级语言根据编程思想分为面向过程编程面向对象编程两种,然后系统对程序代码进行编译(需要第三方编译器)然后执行

    • 优点:移植性强、可读性强、推广性非常高
    • 缺点:执行效率降低

面向过程编程思想: 将要解决的问题(功能需求)分解成具体的步骤,然后通过函数编程实现每一个步骤,最后通过函数规定好的顺序调用完成

  • 面向过程编程思想的优点

    • 能够针对步骤拆分,进行模块化封装(函数)
    • 可以实现代码复用,从而节省开发成本
  • 面向过程编程思想的缺点

    • 不够灵活维护,流程一旦确定就必须按照既定方式执行到底。

小结

  1. 计算机编程从对开发人员要求极高到要求不高,是一代代人坚持不懈的结果
  2. 面向对象编程是目前最为符合人类思维逻辑的一种编程思想

面向对象编程思想:面向对象编程也叫做OOP编程(Objected Oriented Programming),是一种基于面向过程的开发思想。与面向过程强调分解事务步骤相似,面向对象更需要追求事务操作的“主体”,也就是对象

  • 面向对象编程是一种编程思想,不是一种具体技术

  • 面向对象是在面向过程基础之上发展而来,因此也是一种模块化编程思想(有函数)

  • 面向对象能够更加方便的实现代码的重复利用(适用于大型项目)

  • 在面向对象思维中,任何动作的执行或者数据都属于对象(一切皆对象)

小结

  1. 面向对象编程是一种编程思想,与技术无关
  2. 面向对象编程的本质是增加数据和功能的操作主体,即对象
  3. 面向对象中所有的数据和功能都是由主体(对象)来调用和操作

1、面向过程编程思想原理

在这里插入图片描述

2、面向对象编程思想原理

在这里插入图片描述

二、面向对象基础

1、面向对象关键字说明

面向对象关键字:基于面向对象开发时,所用到的一些关键字,用来表明不同的结构或者类型

  • 类:class,是定义面向对象主体的最外层结构,用来包裹主体的数据和功能(函数)。类是一类具有共性事务的代表,代表的是事务的共性。

  • 对象:object,是某类事务的具体代表,也是实际数据和功能操作的具体单元,也被称之为实例(instance)

  • 实例化:new,从一个抽象的概念得到一个符合抽象概念的具体实例的过程

  • 类成员:member,指类class结构中的所有内容,类成员里有三种

    • 方法:method,本质是在类class结构中创建的函数,也称之为成员方法或者成员函数
    • 属性:property,本质是在类class结构中创建的变量,也称之为成员变量
    • 类常量:const,本质是在类class结构中创建的常量

2、类的定义、实例化和对象

:根据对象分析后得到的一种通用结构(分类)

  • class关键字声明类
  • 类名:自定义名字,通常首字母大写,一般多单词组成类使用驼峰法(大驼峰法)
  • 大括号:类内部的结构(member,类成员)
class 类名{
    
}
  • 实例化:类产生对象的过程
new 类名;
new 类名();	# 使用较多
  • 对象(实例):根据类产生的某个具体存在的实体(instance),对象一般使用变量保存
$object = new 类名();

小结

  1. 通过class关键字 + 类名 +{}创建类
  2. 类是一种结构,不会自动运行,也不能输出
  3. 通过new 类名实例化对象得到类的具体对象
  4. 可以通过new实例化无限个对象

3、类成员

类成员:指直接定义在类结构{}内部的一级成员,即直接依赖{}的成员

  • 类成员分类
    • 成员变量(属性):给对象存储数据的变量
    • 成员函数(方法):给对象调用解决问题的函数
    • 类常量:属于类内部的常量,使用const关键字定义
  • 属性和方法需要使用访问修饰限定符修饰,姑且使用public修饰
class 类名{
    # 类常量(可以多个)
    const 常量名 =;
    # 属性(可以多个)
    public $属性名 [ =];	# 可以赋值也可以不赋值,只声明
    # 方法(可以多个)
    [public] function 方法名([形参列表]){
        # 方法体(返回值)
    }
}
  • 成员访问:属性和方法都属于对象访问,类常量和静态成员属于类访问
    • 对象访问属性和方法,使用->
    • 类常量和静态成员,使用::

使用步骤:

  1. 声明类结构
  2. 明确类产生的对象是否需要有数据的存储:确定属性
  3. 明确类产生的对象是否需要函数实现功能:确定方法
  4. 明确类是否需要定义常量:确定类常量
  5. 对象实例化
  6. 类成员访问(属性和方法)

示例:

  1. 声明类结构
# 定义买家类:买家有姓名,有钱
class Buyer{
    # 属性声明
	$name;				# 错误,类内部属性必须使用访问修饰限定符
    public $name;		# 正确:没有赋值
    public $money = 0;	# 正确:有赋值
    
    # 类常量声明
    const BIG_NAME = 'BUYER';
    
    # 方法声明
    function display(){
        echo __CLASS__;	# 魔术常量,输出类名
    }
}
  1. 成员变量访问(属性和方法):成员必须通过对象才能进行访问,需要先通过实例化得到对象,然后通过对象实现对成员进行操作
	# 实例化对象
	$b = new Buyer();
	# 访问属性
	echo $b->money;
	# 修改属性
	$b->money = 1000;
	# 删除属性
	unset($b->name);
	# 新增属性
	$b->age = 20;
	
	# 访问方法
	$b->display();

注意

  • 删除属性和新增属性通常使用较少,更多的属性操作是访问和修改

  • 类常量不是由对象来进行访问,而是有类访问

  • 属性和方法的使用都必须确保类中已经定义(属性可以新增)

  1. 类成员中:属性、类常量和方法都可以无限定义,但是定义的原则是相关性。除了以上三个类成员,不能在类结构{}中直接写其他任何代码
class Buyer{
    echo __CLASS__;					# 错误
    define('PI',3.14);	 			# 错误
    if(true){ echo 'hello world'}	# 错误
}    

小结

1、PHP类结构中有且仅有三种成员:属性、方法和类常量,其他直接属于类的内容都会报错

2、类声明需要根据业务来确定类成员的存在和数量

3、类中属性和方法的访问方式都是通过对象来调用:$对象->属性名/方法名();注意属性名不带$符号

4、类中定义属性不能直接属性名,需要使用符号public修饰(访问修饰限定符中的一种)

4、访问修饰限定符

访问修饰限定符:用在属性或者方法前的修饰关键字,是用来控制属性或者方法的访问位置

  • 访问修饰限定符分类
    • public:公有,类内和类外都可以访问
    • protected:受保护,只允许在相关类内部访问
    • private:私有,只允许在定义类内部访问
  • 属性必须有访问修饰限定符,方法可以没有访问修饰限定符(默认public)

示例:

  1. 公有成员访问
class Saler{
    # 属性
    public $count = 100;
    # 方法
    public function getCount(){
        echo __METHOD__;		# 魔术常量,显示当前方法名(包含类名)
    }
    
    function setCount(){
        echo __METHOD__;
    }
}

# 实例化对象
$s = new Saler();

# 访问(类外)
echo $s->count;
$s->getCount();
$s->setCount();
  1. 受保护和私有成员设定
class Buyer{
    # 属性
    protected $money = 10;
    private $account = '6226000000000001';
    
    # 方法
    protected function getMoney(){
        echo __METHOD__;
    }
    
    private function getAccount(){
        echo __METHOD__;
    }
}

# 实例化
$b = new Buyer();
echo $b->money;		# 错误:当前属于类外部,不能访问
echo $b->account;	# 错误:当前属于类外部,不能访问

$b->getMoney();		# 错误:当前属于类外部,不能访问
$b->getAccount();	# 错误:当前属于类外部,不能访问

总结

1、访问修饰限定符分为三种:public、protected和private,访问权限依次降低(类对成员控制权限依次增加)

2、访问修饰限定符限定的是成员到底在哪里能被访问,私有和受保护都只能在类内部访问,公有可以在任何地方访问(但都必须是对象去访问)

3、属性必须写清楚访问修饰限定符,方法可以省去(不建议),因为系统默认是public

5、类内部对象$this

内部对象:$this,方法内部内置的一个对象,会自动指向来调用方法的对象

  • $this存在于方法内部(仅限内部使用),所以相当于在类的结构内部
    • 可以访问任意访问修饰限定符修饰的成员
    • 私有成员都是通过公有方法来实现访问(公有方法可以在类外部访问)
  • 类内部对类成员的访问也需要通过对象才能访问,所以必须通过$this内部对象访问类成员

示例:

1、尝试在类内部方法中访问属性

class Saler{
  	# 属性
  	public $count = 100;
  	protected $discount = 0.8;
  	private $money = 100;
    
    public function getAll(){
        echo $count,$discount,$money;	# 全部错误:提示未定义的“变量”
    }					
}
$s = new Saler();
$s->getAll();

注意:方法本质是定义在类内部的函数,因此受制于作用域的问题,在方法内部访问的变量系统认定为局部变量(必须内部定义或者参数传入),否则就会提示未定义

2、类内部访问类成员,需要通过对象来进行访问

class Saler{
  	# 属性
  	public $count = 100;
  	protected $discount = 0.8;
  	private $money = 100;
    
    public function getAll(){
    
    	# 第一种访问方式
        # 需要获取到对象名字:因为方法本身就是函数,访问外部全局变量可以通过global引入实现
        global $s;
        echo $s->count,$s->discount,$s->money;		#正确输出
        # 上述代码规定死了以后对象只能是$s,不能有其他对象或者其他命名,所以非常不友好
        
        
		#第二种方式,使用内置对象$this访问,一般都使用这种方式
		var_dump($this);
        echo $this->count,$this->discount,$this->money;		#正确输出
    }					
}

$s = new Saler();
$s->getAll();

注意:$this代表的是对象,而​$this所在环境为类内部的方法内部,所以$this对象是在类内部访问,因此可以访问所有的属性和方法,不受访问修饰限定符限制

$this、class和new之间的关系原理

  • class是定义类结构,属于非执行段代码,因此会被加载到代码段(编译阶段)

  • new是实例化对象,先判定类在内存(代码段)是否存在

    • 类不存在,报错;
    • 类存在,将类内部的属性部分复制一份,然后在内存(堆区)开辟一块内存空间,将属性放到里面,同时内部有一个指针指向类的内存空间(代码段)
    • 对象访问属性即访问的是对象空间里存储的部分
    • 对象访问方法是对象通过内部指针找到类空间中的方法,然后在内存(栈区)开辟运行
  • $this是系统在方法内置的对象通用名字

    • 对象在调用方法的时候,系统会自动找到对象所保存的内存地址(堆区),然后把地址赋值给$this
  • 方法内部的$this就代表调用当前$this所在方法的外部对象

    • $this的本质是函数内部的一个局部变量,只是系统自动对其进行赋值,而且一定是调用方法的对象本身
  • 面向对象编程代码运行内存关系

在这里插入图片描述

小结

1、类内部方法内有一个内置对象$this,代表访问该方法的外部对象

2、类在实例化对象的时候要保证内存中有该类

3、一个类可以实例化多个对象,每个对象访问成员方法时,$this就代表对应对象

6、构造方法

构造方法:__construct(),是一种类结构特有的特殊方法,该方法由系统规定好,开发人员在定义的时候只需要一遍,有了构造方法的类在实例化对象之后,对象就会自动调用。

  • 构造方法是一种魔术方法:魔术方法是会自动被触发,不需要手动调用的方法
  • 构造方法的目标是为了实现对象的初始化
    • 对象实例化之后会自动调用
    • 构造方法通常是为了实现对象所需资源的初始化(属性、资源)
  • 构造方法虽然为魔术方法,但本质依然是一个方法
    • 受访问修饰限定符控制(对象的产生位置会发生改变)
    • 对象可以选择调用(一般不会)
  • 构造方法可以设定形参,形参对应的实参是在实例化对象的时候传入:new 类名(实参传递给形参)

示例:

1、构造方法实现:在类中增加一个方法__construct()即可

class Saler{
    # 构造方法,实例化之后就自动调用
    public function __construct(){
        echo __CLASS__;
    }
}

2、构造方法也是一个方法,不普通的地方在于,类实例化得到的对象会马上自动调用

# 实例化
new Saler();				# 输出Saler

小结

1、构造方法__construct()是一种系统内置的方法,该方法的特性是会在对象实例化之后,对象立即自动调用

2、构造方法的目的就是为了初始化资源,包含对象属性和其他资源

3、一旦构造方法定义好之后,且构造方法自带参数,那么就只能使用new 类名(参数列表)方式才能正确实例化

4、构造方法可以当做普通方法由对象调用(不建议)

7、析构方法

析构方法:__destruct(),也是一种类结构中魔术方法,与构造方法一样,也是系统规定好,只需要开发人员一遍即可,对象在被销毁时会自动调用

  • 析构方法是用来对象销毁时主动释放资源的
  • 对象销毁
    • 对象无变量指向(变量指向其他数据)
    • 对象被主动销毁(unset销毁对象变量)
    • 脚本执行结束(自动释放资源)
  • PHP脚本执行结束会释放所有资源,所以一般较少使用析构方法

示例:

1、析构方法实现:类中增加一个__destruct()方法

class Saler{
  	# 析构方法
    public function __destruct(){
        echo __FUNCTION__;
    }
}

2、析构方法调用:析构方法是在对象被销毁时自动,对象的“垂死挣扎”

	# 实例化对象
	$s = new Saler();
	
	# 对象变量指向其他数据
	$s = 1;	
	
	# 主动销毁对象变量
	unset($s);			
	
	# 脚本执行结束自动释放

3、析构方法也是普通方法,可以由对象直接调用

# 接析构方法实现代码
$s = new Saler();
$s->__destruct();		# 思考:此时对象是否被销毁?

小结

1、析构方法是一种对象销毁时自动调用的方法

2、析构方法是用来对象销毁自身所占用的资源

3、PHP中脚本执行结束,系统会自动回收所有资源,因此一般PHP中很少使用析构方法

8、范围解析操作符(类常量访问)

范围解析操作符:由两个冒号组成“::”,是专门用于类实现类成员操作的,可以实现类直接访问类成员

  • 范围解析操作符是用于给类(类名)访问类成员使用的
类名::类成员
  • 范围解析操作符也可以被对象用来当做类使用(不建议使用)
$对象名::类成员
  • 类常量只能被类访问

示例:

1、类常量的普通访问尝试:尝试使用对象进行访问

class Saler{
	# 类常量
    const PI = 3.14;
}
$s1 = new Saler();
echo $s1->PI;			# 错误,$s1->PI最终转换的访问方式为:$PI,这个在类中并不存在

2、以上案例可以看出,对象无法访问类常量,那是因为类常量的定义本身就是用来给类访问的,对象是用来访问属性和方法的,类常量的访问方式为:类名::常量名

# 类+范围解析操作符访问类常量
echo Saler::PI;			# 输出3.14

3、对象本身也依赖于类,因此也可以使用对象对类控制成员进行访问,需要使用范围解析操作符

$s = new Saler();
echo $s::PI;			# 输出3.14

注意:以上方式能访问,但是不建议使用(以上方式也能看出,成员谁来访问,关键看用什么符号:①使用范围解析操作符::就是类访问;②使用对象操作符号->就是对象访问)

4、分析:类常量是固定的,而对象的属性是不同对象而不同的,成员方法简单的理解也是为属性本身进行加工的。因此有一些东西是专属于类的,而有部分内容是专门为对象提供的,所以就会有不同的成员拥有不同的访问方式

小结

1、类访问成员的方式是使用范围解析操作符“::”访问,由类名直接访问:类名::类常量

2、类本身是通过对同类对象的抽象而形成,所以属性和方法本身都是由对象来访问

3、类也需要有一些自身的数据和操作,这些就由类来进行访问

9、静态成员

静态成员:使用static关键字修饰的类成员,表示该成员属于类访问

  • PHP静态成员有两种
    • 静态属性
    • 静态方法
  • 静态成员是明确用来给类访问的,而不是对象
  • 静态成员只是多了一个static关键字修饰,本身也可以被对象访问
  • 静态成员同样可以使用不同访问修饰限定符限定,效果一致

示例

1、静态属性:在类中定义属性的时候使用static关键字修饰,访问的时候只能使用类+范围解析操作符+静态属性访问

class Saler{
	# 属性
    public $money = 0;
    public static $count = 0;	# 静态属性
}

# 静态成员可以直接使用类访问,而不需要先实例化对象
echo Saler::$count;

2、静态方法:在类中定义方法的时候使用static关键字修饰,访问的时候使用类+范围解析操作符+静态方法名字()访问

class Saler{
	# 方法
    public static function showClass(){
        echo __CLASS__;
    }
}

# 类直接访问
Saler::showClass();

3、在类的内部也可以访问静态成员,同样是使用类名+范围解析操作符+静态属性/静态方法()

class Saler{
    # 属性
    private static $count = 0;			# 私有,不允许外部直接访问
	# 方法
    public static function showClass(){
        echo Saler::$count;
    }
}

# 类直接访问
Saler::showClass();

4、静态方法本质也是类中定义的方法,因此也可以使用对象进行访问,但是不建议

# 对象访问静态方法
$s = new Saler();
$s->showClass();						# 输出0

5、同理,方法也是在类内部,在编译时就存在,因此可以通过类来进行访问,使用范围解析操作符,但是非常不建议(会报错:因为类只允许访问静态成员和类常量)

class Saler{
    public function testStatic(){
        echo __FUNCTION__;
    }
}

# 类访问普通成员方法
Saler::testStatic();				# 输出testStatic,但是报错,当前访问的不是静态方法

6、静态方法本质是给类访问,所以不允许在静态方法内部使用$this对象

class Saler{
    public static function testStaticThis(){
        var_dump($this);				# 致命错误:$this放到了不该放的位置
    }
}			

小结

1、为了保障类能直接访问数据和操作数据,可以在属性和方法前增加static关键字变成静态属性和静态方法

2、类通过类名+范围解析操作符+静态成员的方式进行访问

3、静态成员也受访问修饰限定符的限定,访问权限与普通属性和方法的限制一样

4、对象可以无条件访问静态方法,而类只能访问不带$this的普通方法(不建议)

5、静态成员是给类访问的,非静态成员是给对象访问的

  • 静态属性和方法(静态和非静态)都是保存在类结构中(代码段)
  • 普通属性保存在对象生成的对象空间里(堆)

6、静态成员的访问效率比非静态成员高,因此有种说法是能用静态的时候就不用非静态(对象的特点是多元化,而静态的特点是单一化)

10、self关键字

self关键字:在类的内部(方法里面)使用,代替类名的写法

  • self如同$this代表内部对象一样,能够在方法内部代替当前类名

  • 能够保障用户方便修改类名字

  • self关键字是代替类名,所以需要配合范围解析操作符::

示例:

1、self是用来代替类名的,与范围解析操作符::一起使用的

class Saler{
    # 静态属性
    private static $count = 0;			# 私有,不允许外部直接访问
	# 静态方法
    public static function showClass(){
        echo Saler::$count;
        echo self::$count;				# 代替类名
    }
}

2、self也可以在类的内部方便实例化对象:比如构造方法被私有化之后,就没有办法在类外部实例化对象,此时可以在类内部进行对象实例化

class Saler{
    # 属性
    private static $count = 0;			# 私有,不允许外部直接访问
    private function __construct(){}	# 私有,不允许外部实例化(因为对象不能外部调用)
	# 方法
    public static function getInstance(){
        return new Saler();				# 使用类名实例化
        return new self();				# 使用self关键字实例化
    }
}

$s = Saler::getInstance();

小结

1、self是一种在类内部用来代替类名的关键字

2、self可以用来在类内部访问静态成员

3、self也可以在类内部用来实例化对象

4、帮助类名修改时,不用修改任何类的内部结构

11、对象克隆

克隆对象:clone,即通过已有的对象复制一个新的同样的对象,但是两者之间并非同一个对象

  • 克隆对象与原来对象内容一致(表象)
  • 克隆出来的对象是新对象
  • 对象克隆出来后会自动调用魔术方法__clone()(如果有该方法)

步骤:

1、定义类时考虑对象是否允许被克隆,以及允许克隆后是否需要针对克隆对象做操作

  • 不允许克隆:私有化__clone()魔术方法(不允许外部克隆,使用者一般都是外部)
  • 允许克隆处理:在__clone()方法中设定好克隆对象的处理

2、实例化对象并保存到变量

3、需要从已有对象产生新对象(不是赋值)

4、使用clone产生对象

示例:

1、对象克隆是通过clone关键字实现,即:clone 对象;

class Saler{
  	# 属性
  	public $count;				
  	private $money;
}
# 实例化
$s1 = new Saler();
$s1->count = 1;

# 克隆
$s2 = clone $s1;

2、克隆出来的对象与原来对象是两个内存地址,因此是两个不同的对象

# 接上述代码
$s2->count = 2;

echo $s1->count;		# 1,没有变化

3、对象在实例化的时候会自动调用存在的构造方法__construct(),同样的,在类的内部,PHP允许定义一个__clone()的方法,在对象被克隆后,新克隆出来的对象会自动调用

class Saler{
  	# 属性
  	public $count;				
  	private $money;
    # 克隆方法
    public function __clone(){
        var_dump($this);			# 编号为2,代表是克隆出来的对象
        $this->count++;
    }
}
# 实例化
$s1 = new Saler();
$s1->count = 1;

# 克隆
$s2 = clone $s1;

4、如果不允许对象被克隆,可以将__clone()方法私有化(本质是不允许对象在外部被克隆)

class Saler{
  	# 属性
  	public $count;				
  	private $money;
    # 私有化克隆方法
    private function __clone(){}
}
# 实例化
$s1 = new Saler();
$s1->count = 1;

# 克隆
$s2 = clone $s1;			# 致命错误:不允许对象在外部访问一个私有方法

小结

1、对象可以通过克隆来得到新的对象(以前只有实例化)

2、克隆出来的对象会自动调用类中对应的__clone()方法(如果有)

3、因为克隆对象是新对象,不会改变原来的对象,如果需要一个和当前对象一致状态的对象,但是又不想改变当前对象的状态,那么就可以通过克隆来实现

4、可以通过私有化克隆方法来实现禁止外部对象克隆

15、总结

1、面向对象编程核心是“万物皆对象”的思想,与面向过程编程思想的本质区别是事务操作的主体:每一次操作都是由明确的对象来执行

2、面向对象思想的本质是将数据(属性)、数据操作(函数)进行的一次二次封装(类),而往后的所有操作都必须由类或者类产生的对象进行调用

3、面向对象核心关键字

  • 类:class,结构主体,某一类相似主体的公共部分抽离

  • 类成员:类结构中能够直接定义的成员

    • 属性(property):存储数据的变量
    • 方法(method):数据操作的逻辑
    • 类常量(const):存储固定数据的内部常量(const定义)
  • 实例化:new,类结构产生对象的过程

  • 实例:instance,一个具体的对象

4、访问修饰限定符:限定被修饰成员的方位位置(所有类成员都能被访问)

  • public:公有,表示不限定访问区域
  • protected:受保护,表示限定范围为关联类内部(本质是方法内部,关联类需要学习继承)
  • private:私有,表示限定范围为自己类内部(内部方法内)

5、类内部对象:$this

  • 普通方法内部,代表来访对象
  • 因为在类内部,所以不论任何访问修饰限定符限定,都可以访问

6、魔术方法:自动调用的方法

  • 构造方法:__construct(),对象初始化资源,对象实例化后自动调用
  • 析构方法:__destruct(),对象销毁资源,销毁时对象自动调用
  • 克隆方法:__clone(),对象被克隆后,克隆对象自动调用

7、对象传值:对象是引用传值,不会产生新对象

8、范围解析操作符:::,用于类直接访问成员的符号

  • 类访问类专属成员:类常量(静态属性和静态方法)
  • 对象也可以使用该符号访问类成员(不建议)

9、静态成员:使用static关键字修饰的成员,用来给类访问的成员(对象也能访问)

  • 静态成员:静态属性和静态方法
  • 静态成员在编译(类加载到内存)时初始化,不用产生对象即可访问(效率高)
  • 静态属性不会出现在对象的内存空间

10、self关键字:类内部用来代表类名访问类成员的

  • self与范围解析操作符结合访问:self::类成员
  • self可以代替类名在类内部进行实例化:new self()

11、对象克隆:从已有对象产生新对象

  • 防止克隆:私有化话克隆魔术方法

在这里插入图片描述

posted @ 2022-04-02 09:47  coderwcb  阅读(102)  评论(0编辑  收藏  举报