php面向对象基础

参考:
1、PHP面向对象编程(玉女心经版)
2、谈谈我对php中面向对象的理解

摘要:

面向对象编程:面向对象运用封装好的对象以及对象中所拥有的具体属性和方法来处理问题(白话:专业的人做专业的事);
面向过程编程:面向过程专注于解决一个问题的过程,最大的特点就是由一个一个的函数去解决处理这个问题的一系列过程(白话:一堆没有解耦的代码在一起)。

一、面向对象基础语法

面向对象
类:具有相同属性(特征)和方法(行为)的一系列个体的集合,类是一个抽象的概念。
对象:从类中,拿到的具有具体属性值的个体,称为对象。对象是一个具体的个体。
类和对象的关系:类是对象的抽象化,对象是类的具体化。

类的声明与实例化
类的声明:

class 类名{
	访问修饰符 $属性[=默认值];
	[访问修饰符] function 方法(){}
}

声明一个类的注意事项:

  1. 类名只能有字母数字下划线组成,开头不能是数字,必须符合大驼峰法则;
  2. 类名必须使用class修饰,类名后面一定不能有();
  3. 属性必须要带访问修饰符,方法可以不带访问修饰符。

实例化对象及对象属性方法的调用:

$对象名 = new 类名(); //()可以不带

类外部调用属性和方法:
$对象名 -> $属性名; //使用->调用属性时,属性名不能带$符号

类内部调用属性和方法:
$this -> $属性名;

权限修饰符有三个:public、protected、private
权限修饰符访问权限:
在这里插入图片描述

二、继承的基础知识

1、如何实现继承?

1)子类使用extends关键字,让子类继承父类;
2)class Student extends Person{}

2、实现继承的注意事项?
1)子类只能继承父类的非私有属性。
2)子类继承父类后,相当于将父类的属性和方法copy到子类,可以直接使用$this调用。
3)PHP只能单一继承,不支持一个类继承多个类。但是一个类进行多层继承。

 class Person{}
 class Adult extends Person{}
 class Student extends Adult{} 
 //Student 类就同时具有了Adult类和Person类的属性和方法

3、父类中的方法覆盖(方法重写)

条件一: 子类继承父类
条件二:子类重写父类已有方法
符合上述两个条件,称为方法覆盖。覆盖之后,子类调用方法,将调用子类自己的方法。
同样,除了方法覆盖,子类也可以具有与父类同名的属性,进行属性覆盖。

4、子类重写了父类方法,如何在子类中调用父类同名方法?

使用 partent::方法名();
所以,当子类继承父类时,需在子类的构造中的第一步,首先调用父类构造进行复制。

function __construct($name,$sex,$school){
	partent::__construct($name,$sex);
	$this -> school = $school;
}

三、PHP关键字

1、final
1)final修饰类,此类为最终类,不能被继承!
2)final修饰方法,此方法为最终方法,不能被重写!
3)final不能修饰属性。

2、static
1)可以修饰属性和方法,分别称为静态属性和静态方法,也叫类属性,类方法;
2)静态属性,静态方法,只能使用类名直接调用。

使用"类名::$静态属性" , "类名::静态方法()"
Person::$sex; 
Person::say();

3)静态属性和方法,在类装载时就会声明,先于对象产生
4)静态方法中,不能调用非静态属性或方法;非静态方法,可以调用静态属性和方法。
原因:因为静态属性和方法在类装载时已经产生,而非静态的属性方法,此时还没有实例化诞生
5)在类中,可以使用self关键字,代指本类名

class Person{
	static $sex = "nan";
	function say(){
		echo self::$sex;
	}
}
注:在类的内部调用时,用  self::常量名;
   在类的外部调用时,用  类名::常量名

6)静态属性是共享的,也就是new出很多对象,也是共用一个属性
可以简单的理解为: $this代表的实例化的对象,self代表类本身

深度理解static
static方法是类中的一个成员方法,属于整个类,即使不用创建任何对象也可以直接调用!静态方法效率上要比实例化高,静态方法的缺点是不自动进行销毁,而实例化的则可以做销毁。静态方法和静态变量创建后始终使用同一块内存,而使用实例的方式会创建多个内存。因为PHP的解释运行机制使得每个PHP页面被解释执行后,所有的相关资源都会被回收。
PHP在语言级别上没有办法让某个对象常驻内存。在PHP中,所有的变量都是页面级的,无论是全局变量, 还是类的静态成员,都会在页面执行完毕后被清空,结果会重新建立新的对象,这样也就完全失去了Singleton的意义。
不过,在实际应用中同一个页面中可能会存在多个业务逻辑,这时单例模式就起到了很重要的作用,有效的避免了重复。
* new 对象(注: new 对象会消耗内存资源)这么一个行为,所以我们说PHP的单例模式是相对而言的)。

3、const
在类中声明常量,不能是define()函数!必须使用const关键字。
与define()声明相似,const关键字声明常量不能带$,必须全部大写!
常量一旦声明,不能改变。调用时与static一样,使用类名调用Person::常量。

4、instanceof
检测一个对象,是否是某一个类的实例。(包括爹辈,爷爷辈,太爷爷辈……)

$zhangsan instanceof Person;

【小总结】几种特殊操作符:
1) . 只能连接字符串; “”.""
2)=> 声明数组时,关联键与值[“key”=>“value”]
3) -> 对象($this new出的对象)调用成员属性,成员方法;
4) :: (1)使用parent关键字,调用父类中的同名方法:parent::say();
( 2)使用类名(和self)调用类中的静态属性,静态方法,以及常量。

四、抽象类和抽象方法

1、抽象方法

没有方法体{}的方法,必须使用abstract关键字修饰。这样的方法,我们称为抽象方法。

abstract function say(); //抽象方法  

2、抽象类
使用abstract关键字修饰的类就是抽象类。

abstract class Person{}

3、抽象类的注意事项
1) 抽象类可以包含非抽象方法;
2) 包含抽象方法的类必须是抽象类,抽象类并不一定必须包含抽象方法;
3) 抽象类,不能实例化。(抽象类中可能包含抽象方法,抽象方法没有方法体,实例化调用没有意义)
我们使用抽象类的目的,就是限制实例化!!!
子类继承抽象类,那么子类必须重写父类的所有抽象方法,除非,子类也是抽象类。

4、抽象类的作用
1)限制实例化。(抽象类是一个不完整的类,里面的抽象方法没有方法体,所以不能实例化)
2) 抽象类为子类的继承提供一种规范,子类继承一个抽象类,则必须包含并且实现抽象类中已定的抽象方法。

五、接口

1、接口
1)接口是一种规范,提供了一组实现接口的类所必须实现的方法组合。
接口使用interface关键字声明;

interface Inter{}

2)接口中的所有方法,必须都是抽象方法。
接口中的抽象方法不需要也不能使用abstract修饰。
3)接口中不能声明变量,不能有属性,只能使用常量!!!
4)接口可以继承接口,使用extends关键字!接口使用extends继承接口,可以实现多继承。

interface int1 extends Inter,Inter2{}

5)类可以实现接口,使用implements关键字!
类使用implements实现接口,可同时实现多个接口,多个接口间逗号分隔;

abstract class Person implements Inter,Inter2{}

一个类实现一个或多个接口,那么这个类,必须实现所有接口中的所有抽象方法!除非,这个类是抽象类。

2、接口&&抽象类区别
①声明方式上,接口使用interface关键字,抽象类使用abstract class。
②实现/继承方式上,一个类使用extends继承抽象类,使用implements实现接口。
③抽象类只能单继承,接口可以多实现。(接口extends接口)、多实现(类implements接口)
④抽象类中可以有非抽象方法,接口中只能有抽象方法,不能有非抽象方法。抽象类中的抽象方法必须使用abstract关键字修饰,接口中抽象方法不能带修饰词。
⑤抽象类是个类,可以有属性、变量;接口中只能有常量。

六、多态

1、一个类,被多个子类继承。
如果,这个类的某个方法,在多个子类中,表现出不同的功能,我们称这种行为为多态。
2、实现多态的必要途径:
① 子类继承父类;
② 子类重写父类方法;
③ 父类引用指向子类对象

七、串行化和反串行化

1、串行化:将对象通过一系列操作,转化为一个字符串的过程,称为串行化。(对象通过写出描述自己状态的数值来记录自己)
2、反串行化:将串行化后的字符串,再转为对象的过程,称为反串行化;
3、什么时候使用串行化?
①对象需要在网络中传输的时候
② 对象需要在文件或数据库中持久保存的时候
4、怎样实现串行化与反串行化

串行化: $str=serialize($zhangsan);
反串行化:$duixiang=unserialize($str);

5、__sleep()魔术方法
①当执行对象串行化的时候,会自动执行__sleep()函数;
②__sleep()函数要求返回一个数组,数组中的值,就是可以串行化的属性;不在数组中的属性,不能被串行化;

function __sleep(){
	return array("name","age"); //只有name/age两个属性可以串行化。
}

6、__wakeup()魔术方法
①当反串行化对象时,自动调用__wakeup()方法;
②自动调用时,用于给反串行化产生的新对象属性,进行重新赋值。

function __wakeup(){ $this -> name = "李四";  }

八、面向对象中的魔术方法

1、构造函数
构造函数:当我们使用new关键字实例化对象时,相当于调用了类的构造函数。
构造函数作用:实例化对象时,自动调用,用于给对象的属性赋初值!
构造函数的写法:

①构造函数名,必须与类同名
[public] function Person($name){
	$this -> name = $name;
}
②使用魔术方法__construct
[public] function __construct($name){
	$this -> name = $name;
}

构造函数注意事项:

  1. 第一种写法,构造函数名必须与类同名!!!!
  2. 如果一个类没有手写构造函数,则系统默认会有一个空参构造,因此可以使用new Person();
    如果我们写了带参数的构造函数,则将不会再有空参构造,也就是不能直接使用new Person();
    Person后面的()中的参数列表,必须符合构造函数的要求!!!!
  3. 如果两种构造函数同时存在,将使用__construct。

2、析构函数
概念:

  1. 析构函数在对象被销毁释放之前自动调用;
  2. 析构函数不能带有任何的参数;
  3. 析构函数常用于对象使用完以后,释放资源,关闭资源等。

3、其它魔术方法
在这里插入图片描述

注:
1、__call($a,$b)  中的两个参数,第一是不存在的方法名称,第二个参数是传递的参数;
2、魔术方法是在类的内部;魔术函数是在类的外部使用.
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值