【学习:php面向对象编程】
文章目录
- 一、类与对象
- 1.1 成员属性
- 二、构造函数
- 2.1 语法
- 2.2 this说明
- 三、析构函数
- 3.1 语法
- 3.2 垃圾回收机制
- 四、魔术方法
- 4.1 说明
- 4.2 方法的访问修饰符
- 4.3 魔术方法介绍
- ① __get 和 __set
- ② __isset 和 __unset
- ③ __toString
- ④ __clone
- ⑤ __call
- ⑥ __callStatic
- 五、类的自动加载
- 5.1 自动加载:__autoload
- 5.2 回调函数:spl_autoload_register
- 六、静态属性
- 6.1 如何访问静态属性
- 七、静态方法
- 7.1 如何访问静态方法
- 7.2 注意事项
- 7.3 静态方法和静态属性的最佳实践
- 八、oop编程的三大特征 -- -- 封装
- 抽象
- 8.1 封装
- 8.2 封装是如何实现
- 九、oop编程的三大特征-- -- 继承
- 9.1 继承细节
- 9.2 重载
- 9.2.1 方法重载
- 9.2.2 属性重载
- 十、oop编程的三大特征-- -- 多态
- 十一、抽象类
- 11.1 抽象方法细节
- 十二、接口
- 十三、final关键字
一、类与对象
1.1 成员属性
定义:
类的变量
属性的声明有:private
>protected
>public
数据类型:1、基本数据类型(整型int
、浮点型float
、字符串string
、布尔bool
);2、复合数据类型(数组array
、对象object
);3、特殊数据类型(null
、资源
)
二、构造函数
2.1 语法
// 访问修饰符:private、protected、public 默认 public
// 构造函数是创建对象时,由系统自动调用
访问修饰符 function __construct(形参列表){// 完成对成员属性的初始化
}
2.2 this说明
系统会给每个对象分配
this
,代表当前对象
this
只能在类内部方法中使用,不能在类定的的外部使用。
三、析构函数
3.1 语法
public function __destruct(){// 释放该对象的资源
}
定义:在到某个对象的
所有引用都被删除
或者当对象被显式销毁
时执行,说白了就是对象调用结束前
场景:析构函数是在对象被销毁前, 给程序员一个机会,去释放该对象分配的相关资源的, 比如数据库链接, 比如你打开的文件,比如绘图的句柄
3.2 垃圾回收机制
1、php中,一个对象没有任何引用指向它时,就会成为一个垃圾对象,php将启用垃圾回收器将对象销毁
2、当程序退出前,php也会启用垃圾回收器,销毁对象
四、魔术方法
4.1 说明
1、程序员不能主动的调用魔术方法, 当满足某个条件时,系统会自动的调用魔术方法
2、魔术方法是系统给我们提供的
3、魔术方法都是以__
开头的,因此我们自定以函数时,就不要使用__
开头
4.2 方法的访问修饰符
public
: 在任何地方被访问
protected
: 可以被其自身
以及其子类
和父类
访问
private
: 只能在该类
里面访问
4.3 魔术方法介绍
① __get 和 __set
1、读取不可访问属性的值时,
__get()
会被调用 // 都是在类的内部定义,外部调用
2、在给不可访问属性赋值时,__set()
会被调用
3、不可访问的属性就是指这样的情况(1. 属性不存在
、2. 属性是protected
或private
)
/** * __get()* @param $get_name [string] [你要获取的属性名,这里是protected、private才被调用]*/public function __get($get_name){# property_exists():检查对象或类是否具有该属性if(property_exists($this, $get_name)){return $this->$get_name;//返回该类的对应属性值} else {return '没有这个属性';}}/*** __set()* @param $set_name [string] [你要设置的属性名,这里是protected、private才被调用]* @param $set_val [string] [你要设置的属性值,这里是protected、private才被调用]*/public function __set($set_name, $set_val){# property_exists():检查对象或类是否具有该属性if(property_exists($this, $set_name)){return $this->$set_name = $set_val;//返回该类的对应属性值} else {return '没有这个属性';}}
② __isset 和 __unset
1、当对不可访问属性调用
isset()
或empty()
时,__isset()
会被调用.变量存在则传回true,否则传回false
2、当对不可访问属性调用unset()
时,__unset()
会被调用
3、不可访问的属性就是指这样的情况(1. 属性不存在
、2. 属性是protected
或private
)
③ __toString
当我们把一个对象当做字符串输出时,就会自动的调用
__toString
④ __clone
当我们去克隆一个对象时,
__clone
方法就会被自动的调用
⑤ __call
1、在对象中调用一个不可访问
方法
时,__call()
会被调用
2、注意这里的__call(
string$method
, array$args)
里面必须有2个参数第一个是要调用类里面的方法名,第二个是实例化该类传进来的参数
3、不可访问的属性就是指这样的情况(1. 属性不存在
、2. 属性是protected
或private
)
⑥ __callStatic
1、当我们调用一个不可以访问的静态方法时,
__callStatic
魔术方法就会被触发
2、不可访问的方法就是指这样的情况(1. 方法不存在
、2. 方法是protected
或private
)
五、类的自动加载
5.1 自动加载:__autoload
创建一个类名和类文件的映射数组
/*** [old]: 以前是分别引入 require() 文件* [now]: 现在创建一个类名和类文件的映射数组*/$map = array('Cat' => './Cat.php','Dog' => './Dog.php','Tiger' => './Tiger.php','Sheep' => './Sheep.php',// ... => ...);/*** 功能:当我们使用一个没有定义的类名时,该函数就会被调用* @param $class_name [string] [被调用的类名]*/public function __autoload($class_name) // 注意:这里使用的是php自带的__autoload()方法{# 动态引入类 $map 就是上面定义的数组,用global引入方法内使用global $map;require $map[$class_name];}
5.2 回调函数:spl_autoload_register
我们可以使用
spl_autoload_register
(回调函数) 来注册自己的自动加载函数,注意前面没有__
/*** [old]: 以前是分别引入 require() 文件* [now]: 现在创建一个类名和类文件的映射数组*/$map = array('Cat' => './Cat.php','Dog' => './Dog.php','Tiger' => './Tiger.php','Sheep' => './Sheep.php',// ... => ...);/*** 功能:当我们使用一个没有定义的类名时,该函数就会被调用* @param $class_name [string] [被调用的类名]*/public function my__autoload($class_name) // 注意:这里使用的自定义的 my__autoload()方法{# 动态引入类 $map 就是上面定义的数组,用global引入方法内使用global $map;require $map[$class_name];}// 使用spl_autoload_register()注册[自定义]的加载函数spl_autoload_register('my__autoload');
六、静态属性
概念:静态属性是该类的所有对象
共享的变量
,任何一个该类的对象去访问它时,取到的都是相同的值;同样修改它时,修改的也是同一个变量。
定义:访问修饰符 static 静态属性名
6.1 如何访问静态属性
1、在类的外部如何访问静态属性 ,必须为
public
类名::$静态属性名
2、在类的内部访问静态属性,可以是
public
、protected
、private
第一种 ==> 类名::$静态属性名;第二种 ==> self::$静态属性名; //常用第二种,灵活
注意:
self
是类的范畴(指向类),$this
是对象实例(指向对象实例)
七、静态方法
概念: 静态方法通常是用来操作
静态属性
的,静态方法又称类方法
定义:访问修饰符,可以是public
、protected
、private
访问修饰符 static function 方法名(形参列表){//函数体}
7.1 如何访问静态方法
1、在类的外部如何访问静态方法 ,必须为
public
类名::静态方法名(参数)
2、在类的内部访问静态属性,可以是
public
、protected
、private
第一种 ==> 类名::静态方法名(参数); // 常用第一种第二种 ==> self::静态方法名(参数); 第三种 ==> $this->静态方法名(参数);
7.2 注意事项
注意:
1、 静态方法中不能访问非静态属性
;普通的成员方法,可以访问静态属性
和非静态属性
2、如果我们的静态方法是protected
或private
则也不能在类的外部使用
7.3 静态方法和静态属性的最佳实践
单例模式
八、oop编程的三大特征 – -- 封装
抽象
定义: (就是将一类事物的共同特征
[属性, 行为(成员方法)]
提取出来,形成一个模板(类), 这种研究问题的方式就是抽象
8.1 封装
定义:是将数据
(成员属性)
和操作(成员方法)
封装在一起,把数据保护起来的目的,如果需要操作数据,需要通过被授权的方法(通过public
的成员方法)才可以实现
8.2 封装是如何实现
在php的面向对象中,是通过
访问控制符
来实现封装的, 具体的说就是通过public
,protected
和private
来实现
九、oop编程的三大特征-- – 继承
概念:
1、把多个类共有的属性和方法
提出来,做成一个A类(父类,基类)
2、让B、C类继承A类(extends
);B、C称为子类,扩展类
3、在父类中定义这些相同的属性和方法,所有的子类不需要重新定义这些属性和方法
定义:
class 类名 extends 父类名{//属性,方法等等.}
9.1 继承细节
1、父类的
private
修饰的属性和方法,在子类中不能使用
2、承不能简单的理解成子类定义时,会把父类的属性声明,方法定义拷贝一份,而是建立了继承查找
的的关系
3、子类最多只能继承一个
父类(指直接继承)
4、在创建某个子类对象时,默认情况下会自动调用其父类的构造函数
5、如果在子类中需要访问其父类的方法(构造方法/成员方法
方法的访问修饰符是public/protected
),可以使用父类::方法名(或者 parent::方法名 )
来完成
6、如果子类(扩展类)中的方法和父类(基类)方法相同,我们称为方法重写
9.2 重载
9.2.1 方法重载
所谓
方法重载
,就是函数或者方法有相同的名称,但是参数列表不相同的情形,这样的同名不同参数的函数或者方法之间,互相称之为重载函数或者重载方法。例如:JAVA,因为JAVA没有参数默认值,用方法重载
public class OverloadDemo {//1. test()方法第一次重载,没有参数void test() {System.out.println("No parameters");}//2. test()方法第二次重载,一个整型参数void test(int a) {System.out.println("a: " + a);}//3. test()方法第三次重载,两个整型参数void test(int a, int b) {System.out.println("a and b: " + a + " " + b);}//4. test()方法第四次重载,一个双精度型参数double test(double a) {System.out.println("double a: " + a);return a * a;//返回a*a的值}
}
在php中,是通过
魔术方法
__call()来实现方法重载。PHP可以参数默认值,所以正常不需要方法重载操作
方法重载优势,开发调用效率相对高一些
/*** [old]以前方法重载,通过参数个数和类型不同来区分*/public function index($foo1, $foo2){// todo...}public function index($foo1, $foo2, $foo3){// todo...}
/*** [now]现在重载,通过参数个数和类型不同来区分*/class A{public function index($foo1, $foo2){// todo...}public function index2($foo1, $foo2, $foo3){// todo...}// 使用模式方法实现 用魔术方法 __call 访问一个不存在或无权限方法时调用public function __call($method, $args){// 实现处理方法,使用__call()判断参数个数if(count($args) == 2){$this->index($args[0], $args[1]); // 调用index()}else if(count($args) == 3){$this->index2($args[0], $args[1], $args[2]); // 调用index2()}}}$a = new A();$a->null_fun($num1, $num2); // 调用一个A类不存在的方法null_fun,会触发A类中的__call方法。
9.2.2 属性重载
/*** 编写一个 public 的 __set()就可以阻止属性重载*/class B{public $color; // 存在属性private $pro_arr = array(); // 存储不存在,外部传入的属性 public function __set($pro_name, $pro_val){if(!property_exists($this, $pro_name)){$this->pro_arr[$pro_name] = $pro_val; // 把调用B类时传入的值赋予传入属性}}public function __get($pro_name){if(isset($this->pro_arr[$pro_name])){ // 查询调用B类时传入的属性有无对应的属性$this->pro_arr[$pro_name]; }else{echo '属性不存在';}}/*** 这里只是为了当外部传入B类的属性后,打印出来看B类的属性*/public function showAllPro(){echo '<br>动态增加的属性有 ==> ';foreach ($this->pro_arr as $k => $v) {echo '<br>属性名:' . $k;echo '<br>属性值:' . $v;}}}$b = new B();$b->name = '不存在名字'; // B类中不存在该属性$b->address = '不存在地址'; // B类中不存在该属性$b->color = '存在颜色红色';// B类中存在该属性// 打印B类看里面属性做对比echo '<pre>';var_dump($b);echo '<hr>';$b->showAllPro();
输出结果如下
object(B)#1 (2) {["color"]=>string(18) "存在颜色红色"["pro_arr":"B":private]=>array(2) {["name"]=>string(15) "不存在名字"["address"]=>string(15) "不存在地址"}
}动态增加的属性有 ==>
属性名:name
属性值:不存在名字
属性名:address
属性值:不存在地址
关于重载,PHP中,有三种方式处理
1、使用默认机制,不去管理
2、组织开发者使用重载,很有必要
3、可以自己管理属性重载
十、oop编程的三大特征-- – 多态
概念: 指的是对象在不同的情况下的多种状态, 根据面向对象时运行的上下文环境来决定
/***************/// 1、动物类/***************/class Animal{public $name;public function __construct($name){$this->name = $name;}}/******** 猫继承动物类 **************/class Cat extends Animal{public function showInfo(){echo '<br> Cat-猫的名字:' .$this->name;}}/******** 狗继承动物类 **************/class Dog extends Animal{public function showInfo(){echo '<br> Dog-狗的名字:' .$this->name;}}/***************/// 2、食物类/***************/class Food{public $name;public function __construct($name){$this->name = $name;}}/******** 鱼继承食物类 **************/class Fish extends Food{public function showInfo(){echo '<br> Fish-鱼的品种:' .$this->name;}}/******** 骨头继承食物类 **************/class Bone extends Food{public function showInfo(){echo '<br> Bone-骨头的品种:' .$this->name;}}/***************/// 3、综合主人类/***************/class Master{public $name;public function __construct($name){$this->name = $name;}/*** 喂食* 这里使用类型约束,当我们的类型约束使用的是类(对象),* 可以使用该类的对象实例和该类的子类对象实例*/public function feed(Animal $animal, Food $food){echo '<br> 主人是:' . $this->name;$animal->showInfo();echo '<br> 喜欢吃';$food->showInfo();}}$cat = new Cat('小黑猫');$dog = new Dog('大花狗');$fish = new Fish('沙丁鱼');$bone = new Bone('脆骨');$master = new Master('贝爷');// 用master对象喂食$master->feed($cat, $fish);echo '<hr>';$master->feed($dog, $bone);
输出结果
主人是:贝爷
Cat-猫的名字:小黑猫
喜欢吃
Fish-鱼的品种:沙丁鱼--------------------------------------------------------------------------------------------
主人是:贝爷
Dog-狗的名字:大花狗
喜欢吃
Bone-骨头的品种:脆骨
十一、抽象类
概念:当程序员定义一个类,
该类的一些方法不能确定
,就可以将该方法做成一个抽象方法,这个类就做成一个抽象类
抽象类是用于设计
的,然后需要其它的类来继承并实现抽象类
定义:1、抽象方法
是在方法前使用关键字abstract
来修饰 2、抽象类
是使用abstract
来修饰
abstract class 类名 {abstract 修饰符 function 函数名(参数列表); //注意这里没有方法体!}
11.1 抽象方法细节
1、抽象类不能被实例化
2、抽象类可以没有abstract
方法, 抽象类可以有非抽象方法(普通的方法), 成员属性和常量
3、一旦类包含了abstract
方法,则这个类必须声明为abstract
4、抽象方法不能有函数体,即不能有{ }
5、如果一个类继承了某个抽象类,则它必须实现该抽象类的所有抽象方法
.(除非它自己也声明为抽象类)[多级继承]
十二、接口
概念: 接口就是给出一些没有实现的方法,封装到一起,到某个类要使用的时候,再根据具体情况把这些方法写出来
定义:
1、interface
是一个关键字,表示后面是接口
2、接口的命名规范,iXxxxYxxx
, 以i
开头,然后使用大驼峰法
3、接口的方法,全部都是抽象方法,但是不能使用abstract
去修饰
4、接口中可以定义常量const
常量名 = 值
5、一个类可以同时实现多个接口
,使用,
号间隔即可
6、接口中可以有属性,但只能是常量 ,默认是public
, 但不能
用public
显式修饰
7、接口和接口直接可以是继承(extends)
的关系,interface A extends B{ }
interface 接口名{//属性//方法}
小结:
1、类和类之间是
继承
2、类和接口之间是实现
3、接口和接口之间可以是继承
总结: 抽象类和接口的区别
最主要:抽象类是定义方法,但是不知道怎么实现;接口时定义方法让继承的来实现
1、对接口的继承使用implements,抽象类使用extends
2、接口中不可以声明变量,但可以声明类常量.抽象类中可以声明各种变量
3、接口没有构造函数,抽象类可以有
4、接口中的方法默认为public,抽象类中的方法可以用public,protected,private修饰
5、一个类可以继承多个接口,但只能继承一个抽象类
十三、final关键字
场景:如果我们
不希望
某个成员方法
被重写
,则可以将这个方法设置成final
方法,如果我们不希望某个类被继承,则可以设置成final
类
定义:
1、final
是一个关键字,不能修改,不能修饰成员属性
2、如果一个方法被修饰成final
则,该方法不能被子类重写
3、如果一个类被修饰成final
,该类不能被继承
4、什么时候可能使用到,出于安全考虑,不希望其它程序员来继承或者重写重要方法,就可以使用final
5、一般来说,final
类中不会出现final
方法,因为final类都不能被继承,也就不会去重写override final
类的方法了, 但是语法不会报错
6、final
类是可以被实例化
的
final 类名{//属性final 访问修饰符 成员方法名(参数列表){//函数体}}
【学习:php面向对象编程】相关推荐
- Python学习之面向对象编程
Python学习目录 在Mac下使用Python3 Python学习之数据类型 Python学习之函数 Python学习之高级特性 Python学习之函数式编程 Python学习之模块 Python学 ...
- 十四、理解nn.module方法——学习python面向对象编程(一)
起因 在(十二)中说到pytorch中创建神经网络的两种方法:一个是Sequential类(这也是一种继承父类属性和方法并可对其方法重构的子类),另一个是自己编写代码,继承nn.module类,对其内 ...
- 【Python】Python语言学习:面向对象编程,类和对象,封装、继承和多态
这一周Python语言学习,记录如下. 01 面向对象编OOP 1.1 为什么学习和应用OOP? 1 OOP适合更加复杂的需求分析和项目开发. 2 OOP具有更强大的封装能力. 3 OOP相比于面向过 ...
- 从零开始学习python编程-从0开始的Python学习014面向对象编程(推荐)
简介 到目前为止,我们的编程都是根据数据的函数和语句块来设计的,面向过程的编程.还有一种我们将数据和功能结合起来使用对象的形式,使用它里面的数据和方法这种方法叫做面向对象的编程. 类和对象是面向对象编 ...
- Python学习之==面向对象编程(一)
一.面向对象与面向过程 面向对象与面向过程是两种不同的编程范式,范式指的是按照什么方式去编程.去实现一个功能.不同的编程范式本质上代表对各种不同类型的任务采取不同的解决问题的思路. 1.面向过程编程 ...
- python面向对象编程项目_Python学习之==面向对象编程(一)
一.面向对象与面向过程 面向对象与面向过程是两种不同的编程范式,范式指的是按照什么方式去编程.去实现一个功能.不同的编程范式本质上代表对各种不同类型的任务采取不同的解决问题的思路. 1.面向过程编程 ...
- 【java学习】 面向对象编程+java购物车系统
文章目录 一.设计对象 二.内存机制 三.购物车系统 四.构造器 构造器 this关键字的作用 一.设计对象 类和对象是什么? 类:是共同特征的描述(设计图); 对象:是真实存在的具体实例; 如何设计 ...
- Java学习:面向对象编程
探索面向对象编程 面向对象 任务1.采用面向对象方式求三角形面积 (一)编程实现 (二)讲解知识点 (三)拓展练习 任务1.创建学生类并测试 任务2.采用面向对象求解一元二次方程 面向对象 面向对象( ...
- JavaScript学习笔记---面向对象编程-JS高级部分(pink老师)
目录 一.面向对象编程介绍 1.1 两大编程思想 1.面向过程编程POP(Process-Oriented Programming) 2.面向对象编程OOP(Object Oriented Progr ...
- python学习之面向对象编程--搬家具
代码展示: class Furniture():def __init__(self, name, area):self.name = nameself.area = areaclass Home(): ...
最新文章
- pythondjango讲解_Django框架全面讲解
- 每日一技|巧用 Telnet 调试 Dubbo 服务
- Solidity合约记录——(三)如何在合约中对操作进行权限控制
- Jquery中正确使用trim方法以及避免遇到坑
- Raspberry Pi, UPNP(二), Scala
- python中的类怎样理解_理解Python数据类:Dataclass fields 的概述(下)
- mybatis学习笔记-03-CRUD操作
- 明尼苏达推荐系统导论(第一课 欢迎来到RS)
- linux安装软件时提示找不到镜像的问题:Couldn't resolve host 'mirrorlist.centos.org'
- C++基础——tricks,让人惊艳的那些代码
- Mac 用快捷键选取文字,省时省力提高工作效率
- redis中集群的故障恢复
- 第八集:魔法阵 NTT求循环卷积
- 【硬件】串口422的DB9接法
- html怎么让图片在左侧文字在右边,网页设计 怎么让图片在左 文字在右
- 服务器备份原理,服务器冗余链路备份的实现原理与过程
- 计算机的内存大小有何作用,电脑内存用处有多大?你可能想不到!
- 微服务不是架构演变的终点!
- 成长型思维——人不成熟的五大特征和高效能人士的七个习惯
- 基于Python的个人足迹地图绘制设计