安全区研究院

文章目录

面向对象概念关键字说明关于类类成员访问修饰限定符类内部对象-this对象开发规范构造方法析构方法对象传值范围解析操作符(类常量访问)静态成员self关键字对象克隆

面向对象高级封装继承多态

面向对象概念

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

面向对象编程是一种编程思想,不是一种具体技术面向对象是在面向过程基础之上发展而来,因此也是一种模块化编程思想(有函数)面向对象能够更加方便的实现代码的重复利用(适用于大型项目)在面向对象思维中,任何动作的执行或者数据都属于对象(一切皆对象)

总结

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

关键字说明

1.类:class,是定义面向对象主体的最外层结构,用来包裹主体的数据和功能(函数)

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

3.实例化:new,从一个抽象的概念(类)得到一个符合抽象概念的具体实例(对象)的过程

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

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

关于类

1.定义类基本语法:class 类名{},类class是一种结构,如果写好没有语法错误的情况下,代码不会自动执行(与函数定义一样),也无法打印输出

class Nothing{} //空类

var_dump(Nothing); //错误,提示未定义的常量

2.类的命名规范:类的命名规范与函数类似,区别在于人为的通常会将类名的首字母大写,如果碰到多单词组成的类名,通常使用驼峰法

3.类无法直接访问,需要得到类的具体对象才能访问,可以通过实例化new来实现对象的创建:new 类名[()]

4.对象创建后可以直接使用或者打印,但是为了方便后续使用,通常使用变量保存实例化的对象

var_dump(new My);

$m = new My;

var_dump($m); //输出:object(My)#1 (0) { } object(My)#2 (0) { }

打印分析:

object:对象 (My):类名 #1:编号 (0):成员变量(属性)个数 {}:具体成员变量信息(键值对)

类成员

类成员,指直接定义在类结构{}内部的一级成员,即直接依赖{}的成员。在PHP中类成员有三种:成员变量(属性),成员方法(成员函数)和类常量

类成员中:属性、类常量和方法都可以无限定义,但是定义的原则是相关性。除了以上三个类成员,不能在类结构{}中直接写其他任何代码

class Buyer{

echo __CLASS__; //错误

define('PI',3.14); //错误

if(true){ echo 'hello world'} //错误

}

关于成员变量

1.成员变量:就是在类结构{}下直接定义的变量,但是定义的方式与普通变量稍微有点不同,需要在变量名字前使用一个访问控制符修饰

定义语法:访问控制符 变量名字 [= 值] 成员变量可以赋值也可以不赋值。

class Buyer{

//$name; //错误

public $name; //正确:没有赋值

public $money = 0; //正确:有赋值

}

2.成员变量的访问:成员变量必须通过对象才能进行访问,也就是需要先通过实例化得到对象,然后通过对象实现对成员变量的增删改查

访问/修改/删除/新增属性语法:$对象名->属性名;注意属性名不需要带$符号

$b = new Buyer();

//访问属性

echo $b->money;

//修改属性

$b->money = 1000;

//删除属性

unset($b->name);

//新增属性

$b->age = 20;

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

关于成员方法

成员方法:在类当中定义的函数

成员方法访问:成员方法也是需要通过对象进行访问的

访问语法为:$对象名->方法名字();

class Buyer{

//定义方法

public function display(){

echo __CLASS__; #输出类名

}

}

$b = new Buyer();

$b->display();

关于类常量

类常量是在类结构{}下定义的常量,类常量的定义只能使用一种方式:const 常量名 = 值;

注意:类常量不是由对象来进行访问,而是通过类域来访问

class Buyer{

//定义类常量

const PI = 3.14;

}

echo Buyer::PI;//3.14

访问修饰限定符

关于类内部和类外部

类内部:是指类定义的内容内部,即类名后{}内部

类外部:是指类定义的外部内容,即类名后{}之外的所有地方

类成员的访问权限控制是内部访问(私有)、链内部访问(受保护)和全部访问(公有)

在PHP中访问修饰限定符分为三种:public、protected和private

1.public:公有,即表示所修饰的内容(属性或者方法)可以在当前类的内部访问,也可以在类的外部访问

2.protected:受保护,即表示所修饰的内容只能在类的内部访问,外部不能访问

3.private:私有,即表示所修饰的内容只能在当前类的内部访问

4.访问修饰限定符不只是限定属性,也用来限定方法

属性(成员变量)必须写清楚访问修饰限定符,方法可以省去(不建议),因为方法的访问限定符默认是public

class Saler{

//属性

public $count = 100;

protected $discount = 0.8;

private $money = 100;

public function getCount(){}

protected function getDiscount(){}

private function getMoney(){}

function getAll(){} #如果没有指定访问修饰限定符,默认public

}

类内部对象-this对象

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

关于class,new,$this的关系

class是定义类结构,属于非执行段代码,因此会被加载到代码段(编译阶段)new是实例化对象,先判定类在内存(代码段)是否存在

类不存在,报错类存在,将类内部的属性部分复制一份,然后在内存(堆区)开辟一块内存空间,将属性放到里面,同时内部有一个指针指向类的内存空间(代码段)

对象访问属性即访问的是对象空间里存储的部分,对象访问方法是对象通过内部指针找到类空间中的方法,然后在内存(栈区)开辟运行

$this是系统在方法内置的对象通用名字

对象在调用方法的时候,系统会自动找到对象所保存的内存地址(堆区),然后把地址赋值给$this$this的本质是函数内部的一个局部变量,代表的是调用方法的对象本身

开发规范

属性的初始化:

属性在类中定义的时候,通常不会初始化值,除非所有类实例化得到的对象的某个属性需要是统一值

属性在类中初始化的基本判定就是数据是否初始化的时候统一

访问修饰限定符选择:

设定好的类成员本身不会被外部用到,那么应该使用private或者protected设定好的类成员一定会给外部访问,使用public属性通常private居多,如果需要外部访问属性,通常会定义相关方法来实现属性的查看和修改,因为可以在方法内对数据逻辑进行代码控制,安全总之一句话:尽可能增加类对成员的控制(尽可能多使用private,少使用public)

class Saler{

//属性

public $count;

private $money = 0;

//增加方法操作私有属性money

public function getMoney(){

return $this->money;

}

public function setMoney($money){

//可以对逻辑进行修改,对数据进行安全判定,保证数据的安全性

$this->money = $money;

//$this->money是属性,$money是外部传入的参数,二者同名但是性质完全不同

}

}

构造方法

构造方法__construct(),是一种类结构特有的特殊方法,在实例化对象的时候,对象就会自动调用构造方法。

说明:

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

2.构造方法的意义:构造方法是对象实例化的时候用来初始化对象的资源的,所以通常是用来初始化对象的属性或者其他资源初始化

3.一旦构造方法拥有了形参,那么对象在调用该方法的时候就需要传入对应的实参,而构造方法又是自动调用的,所以需要在实例化对象的时候使用new 类名(构造方法对应的实参列表)来实现

注意:之前的new 类名 和new 类名()没有区别是因为没有构造方法,或者构造方法没有参数限定,一旦构造方法有了参数,那么new 类名 就不能直接使用了。

4…我们也可以手动调用构造方法(但是一般没有价值,因为对象实例化时会自动调用)

class Saler{

//属性

public $count;

private $money;

//构造方法:初始化属性

public function __construct($count,$money){

$this->count = $count;

$this->money = $money;

}

}

//实例化

$s = new Saler(100,100); //系统在new Saler(100,100)好之后,会自动调用一次

$s->__construct(1000,1000); //允许手动调用

析构方法

析构方法__destruct(),也是一种类结构中特殊的方法,析构方法是在对象被销毁时自动调用

说明

1.析构方法是对象用来调用释放对象中的资源,不是用来删除对象的

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

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

对象传值

在PHP中,对象的传值是引用传递的:即一个对象变量赋值给另外一个变量,两个变量指向同一个对象的内存地址,即只有一个对象。所以不管对象赋值给多少个变量,内存中只有一个对象

class Saler{}

$s1 = new Saler();

$s2 = $s1;

//证明

var_dump($s1,$s2); //同一个对象

$s1->name = 'Saler'; //更改一个变量所保存对象的属性

echo $s2->name; //输出Saler

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

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

对象无法访问类常量,那是因为类常量的定义本身就是用来给类访问的,对象是用来访问属性和方法的,类常量的访问方式为:类名::常量名

class Saler{

//类常量

const PI = 3.14;

}

echo Saler::PI; //输出3.14

静态成员

使用static关键字修饰的类成员,表示该成员属于类访问。PHP静态成员有两种,静态属性和静态方法。

静态属性

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

class Saler{

//属性

public $money = 0;

public static $count = 0; //静态属性

}

//静态成员可以直接使用类访问,而不需要先实例化对象

echo Saler::$count;

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

静态方法

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

在类的内部也可以访问静态成员,同样是使用类名+范围解析操作符+静态属性/静态方法()静态方法本质也是类中定义的方法,因此也可以使用对象进行访问,但是不建议静态方法本质是给类访问,所以不允许在静态方法内部使用$this对象

class Saler{

//属性

private static $count = 0; //私有,不允许外部直接访问

//方法

public static function showClass(){

echo Saler::$count;

}

}

//类直接访问

Saler::showClass();

//对象访问静态方法

$s = new Saler();

$s->showClass(); //输出0

静态成员的访问效率比非静态成员高,因此有种说法是能用静态的时候就不用非静态

self关键字

self关键字是一种在类内代替类名的写法。能够保障用户方便修改类名字。

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

class Saler{

private static $count = 0; //私有,不允许外部直接访问

public static function showClass(){

echo Saler::$count;

echo self::$count; //代替类名self ==> Saler

}

}

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();

3.self可以用来在类内部访问静态成员 / 类常量

对象克隆

上述我们已经得知:对象的传值是引用传递的,所以不管对象赋值给多少个变量,内存中只有一个对象。

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

1.对象克隆是通过clone关键字实现,即:clone 对象。克隆出来的对象与原来对象是两个内存地址,因此是两个不同的对象

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

class Saler{

//属性

public $count;

private $money;

//克隆方法

public function __clone(){

var_dump($this);

$this->count++;

}

}

//实例化

$s1 = new Saler();

$s1->count = 1;

//克隆

$s2 = clone $s1;

?>

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

面向对象高级

面向对象的三大特性:封装,继承,多态

封装

封装,字面意思就是将内容装到某个容器中,并进行密封保存。在面向对象思想中,封装指将数据和对数据的操作捆绑到一起,形成对外界的隐蔽,同时对外提供可以操作的接口。

数据:即要操作的数据,在面向对象的具体体现就是类成员属性(属性和静态属性)和类常量,这些都是在类的内部定义的用来保存数据的捆绑到一起:即使用类结构{}将属性、类常量和方法存放到一起,成为一个整体对外提供可操作的接口:即提供可以供外部访问的类成员(通常是方法)

//封装特性

class Saler{ //捆绑内容到一起,形成对外界隐蔽的整体

const ALLOW = true;

private static $count = 0;

private $money = 0; //数据:属性和类常量保存

public function getMoney(){ //数据操作

return $this->money;

}

}

//外部

$s = new Saler();

$s->getMoney(); //外部只能访问类中公有的方法,具体实现不可见

继承

0.继承extends是面向对象思想中实现代码在类级别重复利用的重要特性

1.继承的基础:子类(要继承其他类的类,也称之为派生类)与父类(被继承类,也称之为基类)之间本身是一种包含于被包含关系(is - a),如此才有可继承的前提

2.继承关键字:extends,子类想要继承父类,则必须在子类结构声明时明确使用extends关键字来继承相关类

3.继承效果:子类可以不用自己去实现某些功能,而可以直接访问父类中已经存在的成员,继承是指子类可以直接访问父类中已经存在的成员

//父类

class Human{

public function eat(){

echo '吃饭';

}

}

//子类

class Man extends Human{} //子类为空类:没有类成员

//实例化子类对象

$m = new Man();

$m->eat(); //输出吃饭

4.继承可以节省代码工作,同时允许子类中进行扩展,即在子类中增加必要的父类不存在的功能

多态

1.多态:是指在发生类的继承的情况下,同时出现方法的重写(override),即子类拥有与父类同名的方法。然后在实例化对象的时候让父类对象指向子类对象(强制类型,PHP不支持),父类对象表现的子类对象的特点。

2.PHP是弱类型语言,所以不存在变量的强制类型,因此PHP不支持多态。