一.面向对象的概述
数组和对象,都属于PHP中的复合类型(一个变量可以存储多个单元)
对象比数组更强大,不仅可以存储多个数据,还可以将函数存在对象中
对象的三大特性:封装,继承,多态
面向对象编程(oop)
面向对象和面向过程之间的区别
面向过程:
最小的单位:函数
面向对象:
最小的单位:对象
什么是对象
对象是系统中描述客观事件的一个实体,他是构成系统的一个基本单位。*数据与代码都被捆绑在一个实体当中*,一个对象由一组属性和对这组属性进行操作的一组行为组成。
从抽象的角度来说,对象是问题域或实现域中某些事物的一个抽象。他反映该事物在系统中保存的信息和发挥的作用:它是一组属性和有权对这些属性进行操作的一个封装体。客观世界是由对象和对象之间的联系组成的。
对象就是东西,一个实体
对象中有什么?
对象:成员
变量 == 成员属性 == 定义队形的外观和状态
函数 == 成员方法 == 定义对象的功能
什么是类
类是具有相同属性和服务的一组对象的集合比如说人,书,轮船,车都属于类,他为属于该类的对象做了一个统一的抽象描述,在编程的语言中类是一个单独的程序,它应该有一个类名包括属性的说明和服务两个部分。
类和对象之间的关系
类与对象的关系就如模具和铸件的关系,类的实力化的结果就是对象,而对对象的抽象就是类,类描述了一组有相同特性(属性)和相同行为的对象。
声明类-->实例化对象(创建对象)-->用对象
二.类的声明与对象的实例化
1.类的声明
类的声明,只需要使用一个关键字class后面加上一个自定义的类别名称,以及加上一对花括号就可以了。有时候也需要在class关键字的前面加一些修饰了的关键字,例如abstract或final等
声明格式:
[一些修饰类的关键字] class 类名{
类中成员;
}
在类中声明成员属性时,前面必须有修饰词,当不知道使用哪个词时,就使用var或public,如果知道使用哪一个修饰词,就去掉var
private protected public static const var
类中的成员属性,如果创建多个对象时,每个对象有不同的属性值时,不要直接给初值
在创建好对象后再给初值
一个文件只包含一个类,文件名中最好包含类名,(例:文件:类名.clas.php)
自动加载
2.通过类来实例化对象
只有对象在内存中才有存储空间
(1)使用的是new 新建一个对象,加上类名,就是创建那个类的对象
$对象引用=new 类名
(2)只要有一个new关键字就是创建一个对象就在内存中分配了一个空间
3.对象在内存中的分配
4.对象的使用
对象中的成员必须通过对象的引用来访问
对象->成员属性
对象->成员方法
三.面向对象的构造和析构方法
1.对象中成员的访问(就是在一个对象的内部方法中,去访问本对象中的其他方法和属性)
2.在对象中的方法中都默认有一个$this关键字,这个关键字代表调用这个方法的对象
3.构造方法
(1)对象创建完成以后,第一个自动调用的方法
(2)定义,方法名是固定的
在PHP4中和类名相同的方法就是构造方法
在PHP5中构造方法使用了魔术方法__construct()所有类中的声明构造方法都使用这个名称(也可以使用PHP4的方法)
优点:在改变类名时,构造方法不用改变
|作用:为成员属性初始化;
(3)魔术方法:
在类中写出了某个魔术方法,这个方法对象的功能就会添加上
方法名称都固定的(都是系统给我们提供好的),没有自己定义的
每一个魔术方法,都是在不同时刻为了完成某一功能自动调用的方法
不同的魔术方法有不同的调用时机
都是以__开头的方法
__construct();
__destruct();
__set();
__get();
<?php class Person{ //成员属性 private $name; //封装姓名属性 private $sex; //封装性别属性 private $age; //封装年龄属性 //PHP4构造方法 function Person($name="",$age=0,$sex="男"){ $this->name=$name; $this->age=$age; $this->sex=$sex; } //PHP5的构造方法(可以与PHP4的构造方法共存) function __construct($name="",$age=0,$sex="男"){ $this->name=$name; $this->age=$age; $this->sex=$sex; } //析构方法 function __destruct(){ echo $this->name."再见!<br>"; } private function __get($proName){ //$proName属性名 if($proName=="age"){ if($this->$proName>40) return $this->$proName-10; } return $this->$proName; } private function __set($proName,$proValue){ //$proName属性名 $proValue属性值 if($proValue>100||$proValue<0){ return; } $this->$proName=$proValue; } //成员方法 function say(){ echo "我的名字:{$this->name},我的年龄:{$this->age},我的性别:{$this->sex}。<br>"; $this->eat(); $this->run(); } function eat(){ } private function run(){ } } $p1=new Person("张三",80,"女"); $p2=new Person("李四",18,"男"); $p3=new Person("王五"); echo $p1->name."<br>"; echo $p1->sex."<br>"; echo $p1->age."<br>"; $p1->name="张小三"; $p1->age=300; $p1->sex="女"; $p1->say(); ?>
__isset();
__unset();
__clone();
__call();
__sleep();
__weakup();
__toString();
....
__autoload();
4.析构方法
(1)当对象被释放之前最后一个“自动”调用的方法
使用垃圾回收器(Java、php)而c++手动的释放
作用:关闭一些资源,作一些清理的工作
(2)定义:
function __destruct(){
}
<?php class Person{ //成员属性 private $name; //封装姓名属性 private $sex; //封装性别属性 private $age; //封装年龄属性 //PHP4构造方法 function Person($name="",$age=0,$sex="男"){ $this->name=$name; $this->age=$age; $this->sex=$sex; } //PHP5的构造方法(可以与PHP4的构造方法共存) function __construct($name="",$age=0,$sex="男"){ $this->name=$name; $this->age=$age; $this->sex=$sex; } //析构方法 function __destruct(){ echo $this->name."再见!<br>"; } private function __get($proName){ //$proName属性名 if($proName=="age"){ if($this->$proName>40) return $this->$proName-10; } return $this->$proName; } private function __set($proName,$proValue){ //$proName属性名 $proValue属性值 if($proValue>100||$proValue<0){ return; } $this->$proName=$proValue; } //成员方法 function say(){ echo "我的名字:{$this->name},我的年龄:{$this->age},我的性别:{$this->sex}。<br>"; $this->eat(); $this->run(); } function eat(){ } private function run(){ } } $p1=new Person("张三",80,"女"); $p2=new Person("李四",18,"男"); $p3=new Person("王五"); echo $p1->name."<br>"; echo $p1->sex."<br>"; echo $p1->age."<br>"; $p1->name="张小三"; $p1->age=300; $p1->sex="女"; $p1->say(); ?>
四.面向对象的三大特征
1.封装性:
(1)就是对象的成员结合成一个独立的相同单位,并尽可能隐藏对象的内部细节
public protected
private 私有的,用这个关键字修饰的成员,只能在对象内部访问(只有用$this访问),不能在对象的外部访问
(2) 属性封装
只要一个变量需要在多个方法中使用,就将这个方法声明为成员属性,可以直接在这个对象中的所有方法中使用
成员属性,就相当于这个对象中的全局变量
成员属性都会在方法中使用,成员属性值的变化其实就是在改变方法的执行行为 ,也就改变了对象的功能
成员属性的值如果不正常,方法执行的功能也就可能不正常了
作用:不需要再对象外部改变或读取它的值
方法封装
作用:
a.使用private修饰使用其只能在内部使用
b.比如:一个类中有100个方法,封装了95个(为另外的5个服务的方法),只有5个方法可以使用
100个成员属性,都让取值,值都不可以更改,有个别的还不想让人知道真实的值。
和封装有关的魔术方法:
__set() 是直接设置私有成员属性值时,自动调用的方法
__get() 是直接获取私有成员属性时,自动调用的方法
__isset() 是直接isset查看对象中私有属性是否存在时,自动调用的方法
__unset() 是直接unset删除对象中私有属性时,自动调用方法
<?php class Person{ //成员属性 private $name; //封装姓名属性 private $sex; //封装性别属性 private $age; //封装年龄属性 //PHP4构造方法 function Person($name="",$age=0,$sex="男"){ $this->name=$name; $this->age=$age; $this->sex=$sex; } //PHP5的构造方法(可以与PHP4的构造方法共存) function __construct($name="",$age=0,$sex="男"){ $this->name=$name; $this->age=$age; $this->sex=$sex; } //析构方法 function __destruct(){ echo $this->name."再见!<br>"; } private function __get($proName){ //$proName属性名 if($proName=="age"){ if($this->$proName>40) return $this->$proName-10; } return $this->$proName; } private function __set($proName,$proValue){ //$proName属性名 $proValue属性值 if($proValue>100||$proValue<0){ return; } $this->$proName=$proValue; } private function __isset($proName){ return isset($this->$proName); } private function __unset($proName){ unset($this->$proName); } //成员方法 function say(){ echo "我的名字:{$this->name},我的年龄:{$this->age},我的性别:{$this->sex}。<br>"; $this->eat(); $this->run(); } function eat(){ } private function run(){ } } $p1=new Person("张三",80,"女"); $p2=new Person("李四",18,"男"); $p3=new Person("王五"); if(isset($p1->name)){ echo "存在name这个成员<br>"; }else{ echo "不存在name这个成员<br>"; } unset($p1->name); ?>
2.继承性
a.面向对象的三大特性之一
b.开放性可扩充性
c.增加代码的重用性
d.提高软件的可维护性
e.继承就是子类去“扩展”父类
父类--基类
子类--派生类
作用:
(1)类继承的应用
a.声明一个子类,使用extends关键字去继承一个父类
b.子类可以从父类继承所有的属性,包括成员属性、成员方法,构造方法、析构方法,在子类中都可以直接使用
c.类之间的层次关系设计好
(2)访问类型控制
虽然子类可以从父类中继承所有的内容,但private的成员只能在本类中使用,子类中也不可以使用。
封装时,既可以让自己类的内部可以使用,也让子类可以使用,但类的外部不可以使用,把private换成protected
(3)子类中重载父类的方法
子类可以声明和父类相同的方法名,即子类覆盖父类中同名的方法
在子类中调用父类中被覆盖的方法
方法一:父类名::方法名
方法二:parent::方法名
在子类中编写构造方法,如果父类中也有构造方法一定要去调用一次父类中被覆盖的方法。
注意:子类的构造方法,不能低于父类中的访问权限(子类可以放大权限,但不能缩小权限)
<?php //定义一个类“人们” class Person{ protected $name; protected $age; protected $sex; function __construct($name,$age,$sex){ $this->name=$name; $this->age=$age; $this->sex=$sex; } protected function say(){ echo "我的名字:{$this->name},我的年龄:{$this->age},我的性别:{$this->sex}。<br>"; } protected function eat(){ echo "吃饭!<br>"; } protected function run(){ } } //学生类继承类“人们” class Student extends Person{ protected $school; function __construct($name,$age,$sex,$school){ parent::__construct($name,$age,$sex); //调用父类的构造方法 $this->school=$school; } //子类中重载父类的方法 function say(){ //Person::say(); //在子类中调用父类中被覆盖的方法 方法一:父类名::方法名 parent::say(); //在子类中调用父类中被覆盖的方法 方法二:parent::方法名 echo "我所在的学校{$this->school}<br>"; } function study(){ echo $this->name."在学习!<br>"; $this->eat(); } } $p1 =new Student("李四",20,"男","清华"); $p1->say(); $p1->study(); ?>
3.多态:三大特性之一
多态是指在面向对象中能够根据使用类的上下文来重新定义或改变类的性质和行为。
<?php interface Test{ function aaa(); function bbb(); } class One implements Test{ function aaa(){ echo "AAAAAAAAAAA<br>"; } function bbb(){ echo "BBBBBBBBBBBB<br>"; } } class Two implements Test{ function aaa(){ echo "1111111111111<br>"; } function bbb(){ echo "2222222222222<br>"; } } $a=new One; $a->aaa(); $a->bbb(); $a=new Two; $a->aaa(); $a->bbb(); ?>