① 类名只能由字母、数字和下划线组成。 不能以数字开头,且必须遵守大驼峰式规则;
②类名必须用class修饰,类名后面不能有();
③属性必须有访问修饰符,而方法可以没有访问修饰符。
3、调用实例化对象和对象属性方法:
$对象名称 = 新类名称(); //()可以省略
在类外部调用属性和方法:
$对象名称->$属性名称; //使用->调用属性时,属性名不能包含$符号
在类中调用属性和方法:
$this -> $属性名称;
三个构造函数
1.什么是构造函数?
构造函数是类中的特殊函数。 当我们使用new关键字来实例化一个对象时,就相当于调用了该类的构造函数。
2、构造函数的作用是什么?
实例化对象时,会自动调用并用于为对象的属性赋值初始值!
3、构造函数怎么写:
①构造函数名必须与类名相同
[]($名称){
$this -> 名称 = $name;
②使用魔法方法
[]($名称){
$this -> 名称 = $name;
4. 构造函数注意事项:
①第一种写法,构造函数的名称必须与类相同! ! ! !
②如果一个类没有手写构造函数,系统会默认有一个空参构造函数,所以可以使用new();
如果我们写一个带参数的构造函数,就不会再出现空参数的构造函数,即不能直接使用new();
下面()中的参数列表必须满足构造函数的要求! ! ! !
③如果两个构造函数同时存在,则将使用它们。
5. 析构函数:():
①在对象销毁和释放之前自动调用析构函数;
②析构函数不能有任何参数;
③析构函数常用于对象使用后释放资源、关闭资源等。
6.魔术方法:
在PHP中,我们为我们提供了一系列以__开头的函数。 这些函数不需要手动调用。
它将在正确的时间自动调用。 这种类型的函数称为魔术函数。
例如:当class new一个对象时,(){}会被自动调用
(){} 在对象被销毁时自动调用
我们要求,除了魔术方法之外,自定义函数和方法不能以 __ 开头。
最后,一般对于功能比较复杂的类,我们会把它们写到一个单独的类文件中。
类文件的名称必须相同小写,采用“类名小写.class.php”的方法。
在其他文件中使用该类时,可以导入这个“.class.php”文件。
2、封装与继承
1.什么是包装?
通过访问修饰符,将类中不需要外部访问的属性和方法私有化,实现访问控制。
*注:这是为了实现访问控制,而不是拒绝访问。 也就是说,我们将属性私有化后,需要提供相应的方法,以便用户可以通过我们提供的方法来处理属性。
2、包装的作用是什么?
① 用户只关心该类能够提供的功能,而不关心功能实现的细节! (封装方法)
②控制用户的数据,防止非法数据被设置,控制返回给用户的数据(属性封装+set/get方法)
3. 实现封装操作?
①方法封装
对于一些只在类内部使用而不提供给外部使用的方法,那么我们可以使用此类方法将其私有化。
private function formatName(){} //这个方法仅仅能在类内部使用$this调用 function showName(){ $this -> formatName(); }
登录后复制
②属性封装+set/get方法
为了控制属性的设置和读取,可以将属性私有化,要求用户通过我们提供的set/get方法来设置。
private $age; //set方法 function setAge($age){ $this->age=$age; } //get方法 function getAge(){ return $this->age; }
登录后复制
$对象->();
$对象->(12);
③属性封装+魔法方法
private $age; function __get($key){ return $this->$key; } function __set($key,$value){ $this->$key=$value; }
登录后复制
$对象->年龄; //当访问对象的私有属性时,会自动调用__get()魔术方法,并将访问的属性名传递给__get()方法;
$对象->年龄=12; //设置对象私有属性时,会自动调用__set()魔术方法,并将设置的属性名和属性值传递给__set()方法;
注意:在magic方法中,可以利用分支结构来判断$key的差异,并执行不同的操作。
4.关于封装的神奇方法:
①__set($key,$value):为类私有属性赋值时自动调用。 调用时,向方法传递两个参数:需要设置的属性名、属性值。
②__get($key,$value):读取类的私有属性时自动调用。 调用时,向方法传递一个参数,需要读取的属性名称;
③($key):外部使用isset()函数检测私有属性时自动调用。
>>>使用 isset(); 在类之外检测私有属性,默认情况下不检测私有属性。 错误的
>>>所以,我们可以使用 (); 自动调用时返回内部检测结果的函数。
function __isset($key){ return isset($this -> $key); }
登录后复制
When isset($对象名称->私有属性); 外部使用进行检测,上面()返回的结果会被自动调用!
④($key):外部使用unset()函数删除私有属性时自动调用;
1 ($key){ 2 未设置($this -> $key); 3 }
当未设置时($对象名称->私有属性); 外部使用删除某个属性时,属性名会自动传递给(),交给这个魔术方法处理。
继承的基础知识:
1、如何实现继承?
子类使用关键字,让子类继承父类;
班级 {}
2. 实现继承有哪些注意事项?
①子类只能继承父类的非私有属性。
②子类继承父类后,相当于将父类的属性和方法复制到子类中,可以直接使用$this调用。
③PHP只能支持单继承,不支持一个类继承多个类。 但一个类有多个继承级别。
班级 {}
成人类{}
成人班{}
// 该类同时具有Adult类和该类的属性和方法
3.方法覆盖(方法重写)
条件1:子类继承父类
情况2:子类重写了父类已有的方法
满足以上两个条件就称为方法覆盖率。 重写后,当子类调用方法时,会调用子类自己的方法。
同样,除了方法重写之外,子类也可以有与父类同名的属性进行属性重写。
如果子类重写了父类方法,如何在子类中调用同名的父类方法?
::方法名();
因此,当子类继承父类时,子类构造的第一步必须首先调用父类的构造函数进行复制。
function __construct($name,$sex,$school){ partent::__construct($name,$sex); $this -> school = $school; }
登录后复制
3.PHP关键字
1.决赛
①final修饰类,这个类是final类,不能被继承!
②最终修改方法,该方法是最终方法,不能被覆盖!
③Final不能修改属性。
2、
① 可以修改属性和方法,分别称为静态属性和静态方法,也称为类属性和类方法;
②静态属性和静态方法只能使用类名直接调用。
使用“类名::$静态属性”、“类名::静态方法()”
::$性; ::说();
③静态属性和方法将在类加载和生成时先于对象进行声明。
④ 静态方法中,不能调用非静态属性或方法;
非静态方法可以调用静态属性和方法。
(因为静态属性和方法在类加载时已经生成,非静态属性方法还没有实例化)
⑤在类中,可以使用self关键字来引用类名。
class Person{ static $sex = "nan"; function say(){ echo self::$sex; } }
登录后复制
⑥静态属性是共享的,即new产生的许多对象也共享相同的属性。
3.const关键字:
在类中声明常量,不能是()函数! 必须使用const关键字。
与()声明类似,const关键字不能用$来声明常量,必须全部大写!
常量一旦声明就不能更改。 调用时,使用类名来调用::。
4. 操作员:
检查对象是否是类的实例。 (包括父亲、祖父、曾祖父……)
$zhangsan instanceof Person;
登录后复制
【小结】几个特殊的算子:
①. 只能连接字符串; “”。””
② => 声明数组时,关联键和值["key" => "value"]
③ -> (来自$this new的对象)调用成员属性和成员方法;
④:: ①使用关键字调用父类中的同名方法:::say();
② 使用类名(和self)调用类中的静态属性、静态方法和常量。
4. 单例
单例模式也称为单态模式。 保证一个类只能有一个对象实例。
实施要点:
① 构造函数私有化,不允许使用new关键字创建对象。
② 提供外部方法获取对象,并在方法中判断对象是否为空。
如果为空,则创建并返回该对象; 如果不为空则直接返回。
③实例对象的属性和获取对象的方法必须是静态的。
④之后就只能使用我们提供的静态方法来创建对象了。
例如:$s1 = ::();
5. 对象序列化和魔术方法
***关键词:clone and、()、序列化与反序列化( and )、类型约束、魔术方法总结(12)
克隆与
1、用=讲一个对象,并将其赋值给另一个对象时,赋值的实际上是该对象的地址。
两个对象都指向相同的地址,因此如果一个对象发生变化,另一个对象也会发生变化。
例如: $lisi = $;
2、如果想将一个对象完全克隆成另一个对象,两个对象是独立的,互不干扰。
需要使用clone关键字;
例如: $lisi = 克隆 $; //两个对象互不干扰
3.():
①当使用clone关键字克隆一个对象时,会自动调用clone函数。
②()函数,类似于克隆时使用的构造函数,可以为新克隆的对象赋一个初始值。
③()函数中的$this指的是新克隆的对象
在某些版本中,您可以使用 $that 来引用克隆的对象,但大多数版本不支持它。
4.()
使用echo等输出语句直接打印对象时,调用echo $;
然后,可以指定()函数返回的字符串;
function __toString(){ return "haha"; } echo $zhangsan; //结果为:haha
登录后复制
5.()
当调用类中未定义或未公开的方法时,()方法会自动执行。
自动执行时,会传递两个参数给()方法;
参数1:被调用的方法名称
参数二:(数组)调用方法的参数列表。
二()
①这是班级中唯一没有使用的魔法方法;
②实例化一个不存在的类时,会自动调用这个魔术方法;
③调用时会自动传入()一个参数:实例化的类名
所以可以使用该方法来实现自动加载文件的功能。
function __autoload($className){ include "class/".strtolower($className).".class.php"; } $zhangsan=new Person();//本文件内没有Person类,会自动执行__autoload()加载person.class.php文件
登录后复制
三、面向对象的序列化和反序列化( and )
1、序列化:通过一系列操作将对象转换为字符串的过程称为序列化。
(对象通过写出描述其状态的数值来记录自己)
2、反序列化:将序列化后的字符串转换为对象的过程称为反序列化;
3.什么时候使用序列化?
①当对象需要通过网络传输时
② 当对象需要持久化到文件或者数据库中时
4.如何实现序列化和反序列化
序列化:$str=($);
反序列化:$=($str);
5.()魔术方法:
①执行对象序列化后,()函数会自动执行;
②()函数需要返回一个数组。 数组中的值是可以序列化的属性; 不在数组中的属性无法序列化;
(){
数组(“姓名”,“年龄”); //只有name/age这两个属性可以序列化。
6.()魔法方法
①反序列化对象时,自动调用()方法;
②自动调用时,用于对反序列化生成的新对象属性进行重新赋值。
1 (){ 2 $this -> name = "李思"; 3 }
四种类型的约束
1、类型约束:是指给变量添加一个数据类型,约束该变量只能存储对应的数据类型。
(这种操作在强类型语言中很常见,在PHP中只能实现数组和对象的类型约束)
2、如果类型约束是某个类,则该类的对象以及该类的子类都可以通过。
3、在PHP中,类型约束只能出现在函数的形参中。
class Person{} class Student extends Person{} function func(Person $p){ //约束函数的形参,只接受Person类及Person子类 echo "1111"; echo $p -> name; }
登录后复制
函数(新()); √
函数(新()); √
函数(“111”); ×
以new();的形式,我们称之为“匿名对象”;
※※※基类:父类
※※※派生类:子类
五种魔法方法总结
1. ():构造函数,new一个对象时自动调用。
2. ():析构函数,当对象被销毁时自动调用。
3. __get():访问类中私有属性时自动调用。传递读取的属性名,返回$this->属性名
4. __set():为类的私有属性赋值时自动调用。 传递需要设置的属性名称和属性值;
5. ():使用isset()检测对象私有属性时自动调用。 传递检测到的属性名称并返回 isset($this -> 属性名称);
6. ():使用unset()删除对象私有属性时自动调用。 传入删除的属性名,并在方法中执行unset($this -> 属性名);
7. ():使用echo打印对象时自动调用。 返回打印对象时想要显示的内容; 返回值必须是一个字符串;
8.():调用类中未定义或未公开的方法时自动调用。 传递被调用的函数名和参数列表数组;
9. ():使用clone关键字克隆对象时自动调用。 它的作用是对新克隆的对象进行初始化并赋值;
10.():对象序列化时自动调用。 返回一个数组,数组中的值是可以序列化的属性;
11.():对象反序列化时自动调用。 通过反序列化对新生成的对象进行初始化并赋值;
12.():函数需要在类外声明。 当实例化未声明的类时自动调用。 通过传递实例化的类名,可以使用类名自动加载对应的类文件。
6. 抽象类和抽象方法
1.什么是抽象方法?
没有方法体{}的方法必须用关键字修饰。 此类方法称为抽象方法。
说(); //抽象方法
2.什么是抽象类?
用关键字修饰的类是抽象类。
班级 {}
3、抽象类注意事项:
① 抽象类可以包含非抽象方法;
② 含有抽象方法的类一定是抽象类,抽象类不一定含有抽象方法;
③ 抽象类不能被实例化。 (抽象类可能包含抽象方法,抽象方法没有方法体,实例化调用没有意义)
使用抽象类的目的是为了限制实例化! ! !
4、如果子类继承了抽象类,那么子类必须重写父类的所有抽象方法,除非子类也是抽象类。
5、使用抽象类有什么作用?
① 限制实例化。 (抽象类是不完整的类,里面的抽象方法没有方法体,所以无法实例化)
② 抽象类为子类的继承提供了规范。 如果子类继承了抽象类,则子类必须包含并实现抽象类中定义的抽象方法。
7. 接口和多态性
一个接口
1.什么是接口?
接口是一种规范,它提供了一组必须由实现该接口的类来实现的方法。
接口使用关键字声明;
国际米兰{}
2、接口中的所有方法都必须是抽象方法。
接口中的抽象方法不需要也不能使用装饰。
3、接口中不能声明变量,不能有属性。 只能使用常量! ! !
4.接口可以继承接口并使用关键字!
接口使用继承接口来实现多重继承。
int1 国际米兰,{}
5.类可以实现接口并使用关键字!
类使用实现接口,可以同时实现多个接口。 多个接口之间用逗号分隔;
类间,{}
如果一个类实现了一个或多个接口,那么这个类必须实现所有接口中的所有抽象方法!
除非,这个类是一个抽象类。
【接口&&抽象类的区别】:
① 从声明方式上来说,接口使用关键字,抽象类使用类。
②从实现/继承来看,类使用继承的抽象类,使用实现接口。
③抽象类只能以单一方式继承,而接口可以以多种方式实现。 (接口)、多种实现(类接口)
④抽象类可以有非抽象方法,接口只能有抽象方法,不能有抽象方法。 抽象类中的抽象方法必须用关键字修饰,接口中的抽象方法不能用关键字修饰。
⑤抽象类是可以有属性和变量的类; 接口只能有常量。
两种多态性
2、多态性
1.一个类被多个子类继承。
如果该类的一个方法在多个子类中表现出不同的功能,我们称这种行为为多态。
2、实现多态的必要途径:
① 子类继承父类;
②子类重写父类方法;
③ 父类引用指向子类对象