>>>---PHP中的OOP-->面对过程与面对对象基础概念与内容--(封装、继承、多态)
前 言
OOP
学习了好久的PHP,今天来总结一下PHP中的重要成员OOP
1 面向过程&面向对象 |
1、专注于解决一个问题的过程。面向过程的最大特点,是由一个一个的函数去解决处理这个问题的一系列过程。
2、专注于由哪个对象来处理一个问题。面向对象的最大特点,是一个个具有属性和功能的类,从类中拿到对象,进而处理问题。
2 面向对象 |
1、什么是类?
具有相同属性(特征)和方法(行为)的一系列个体的集合,类事一个抽象的概念。
2、什么是对象?
从类中,拿到的具有具体属性值得个体,称为对象。 对象是一个具体的个体。
3、类和对象的关系?
类是对象的抽象化!对象是类的具体化!
类仅仅表明这类对象有哪些属性,但是不能有具体的值,所以类是抽象的。
而对象,是将类的所有属性复制后,产生的具体的个体,所有对象是具体的。
3 类的声明与实例化 |
1.如何声明一个类:
class 类名{
访问修饰符 $属性;
[访问修饰符] function 方法(){}
}
2.声明一个类的注意事项:
①类名只能由字母数字下划线组成,开头不能是数字,必须符合大驼峰法则;
②类名必须使用class修饰,类名后面一定不能有();
③属性必须要带访问修饰符,方法可以不带访问修饰符;
3.实例化对象及对象属性方法的调用
$对象名 =new 类名();//()可以不带
类外部调用属性和方法:
$对象名->属性名;//使用->调用属性时,属性名不能带$
类内部调用属性和方法:
$this->属性名
4 构造函数/析构函数 |
1、什么是构造函数?
构造函数是类中的一个特殊函数,当我们使用new关键字实例化对象时,相当于调用了类的构造函数;
2、构造函数有什么作用?
实例化对象时,自动调用,用于给对象的虎山行赋初值!
3、构造函数的写法?
① 构造函数名,必须与类同名
[public] function Person($name){
$this->name =$name;
}
② 使用魔术方法__construct
[public] function __construct($name){
$this->name =$name; }
4、构造函数的注意事项:
① 第一种写法,构造函数名必须与类同名。
② 如果一个类没有手写构造函数,则系统默认会有一个空参构造,因此可以使用 new Person();
如果我们写了带参的构造函数,则将不会再有空参构造,也就是不能直接使用new Prenson();Person; Person后面的()中的参数列表,必须符合构造函数的要求!!!!!
③ 如果两种构造函数同事存在,将使用__construct。
5、析构函数: __destruct():
① 析构函数在对象被销毁释放之前自动调用!
② 析构函数不能带有任何的参数
③ 析构函数常用于对象使用完以后,释放资源、关闭资源等!
5 魔术方法 |
php,中,给我们提供一系列用__开头的函数,这些函数无需自己手动调用,会在何时的时机自动调用,这类函数称为魔术函数。
例如:function __construct(){} 在类new一个对象时自动调用
function __destruct(){} 在对象被销毁时自动调用
我们要求,除了魔术方法之外,自定义的函数与方法不能使用__开头。
最后,一般对于功能比较复杂的类,我们会单独的写到一个类文件中。
类文件的命名,统一小写,使用“类名小写.class.php”的方式命名。
在其他文件中使用这个类时,可以用include导入这个.class.php文件。
6 重点来了--php中的封装 |
1、什么是封装?
通过访问修饰符,将类中不需要外部访问的属性和方法进行私有化处理,以实现访问控制。
注意:是实现访问控制,而不是拒绝访问。也就是说,我们私有化属性之后,需要提供对应的方法,让用户通过我们提供的方法处理属性。
2、封装的作用?
① 使用者只关心类能够提供的功能,而不必关心功能实现的细节!(封装方法)
② 对用户的数据进行控制,防止设置不合法数据,空置房会给用户的数据(属性封装 set/get 方法)
3、实现封装操作?
① 方法的封装
对于一些只在类内部使用的方法,而不向对外部提供使用。那么,这样的方法我们可以使用private 进行私有化处理。
privatefunction formatName(){}
function showName(){
$this -> formatName();
}
② 属性的封装
为了控制舒心的设置以及读取,可以将属性进行私有化处理,并要求用户通过我们提供的set/get方法进行设置
private $age;
function setAge($age){
$this->age = $age;
}
function getAge($age){
return this->age
}
$对象-> setAge("")
$对象-> getAge("")
③ 属性的封装+set/get 方法
private $age;
function __get($key){
return $this->$ket;
}
function __set($key,$value){
return $this->$key=$value
}
$对象->age; //访问兑现公司有属性是,自动调用__get()魔术方法,并将访问的属性名传给__get()方法。
$对象->age=12; //设置对象私有属性时,自动调用__set()魔术方法,并且将这是的属性名以及属性值传给__set()方法;
注意:在魔术方法中,可以使用分支结构,判断$key的不同,进行不同操作。
4、关于封装的魔术方法:
① __set($key,$value):给类私有属性赋值时自动调用,调用时给方法传递两个参数:需要设置的属性名、属性值
② __get($key):读取类私有属性是自动调用,调用时给方法传递一个参数:需要读取的属性名;
③ __isset($key):外部使用isset()函数检测私有属性是,自动调用。。
>>> 类外部使用 isset();检测私有属性,默认是检测不到的。 false
>>> 所以,我们可以是用__isset();函数,在自动调用时,返回内侧检测结果。
function __isset($key){
return isset($this->$key);
}
当外部使用isset($对象名->私有属性);检测时,将自动调用上述__isset()返回结果!
④ __unset($key):外部使用unset()函数删除私有属性时,自动调用;
function __unset($key){
unset($this->$key);
}
当外部使用unset($对象名->私有属性);删除属性时,自动将属性名传给__unset(),并交由这个魔方方法处理。
1 class Person{ 2 private $name; 3 private $age; 4 private $sex; 5 public function __construct($name,$age,$sex){ 6 $this->name=$name; 7 $this->age=$age; 8 $this->sex=$sex; 9 } 10 function __isset($key){ 11 return isset($this->$key); 12 } 13 function __unset($name){ 14 if($name=="name"){ 15 echo "<span style='color:red;'>删除不掉name</span><br>"; 16 return; 17 } 18 unset($this->$name); 19 return; 20 } 21 function __set($key,$value){ 22 if($key=="name"){ 23 $this->$key=$value."这是set出的。"; 24 return; 25 } 26 $this->$key=$value; 27 } 28 function setAge($age){ 29 if($age<=120&&$age>=0){ 30 $this->age =$age; 31 }else{ 32 error_log("年龄设置有误"); 33 } 34 } 35 function getAge($age){ 36 return "但是我永远18岁,哈哈哈哈哈哈。" ; 37 } 38 function __get($key){ 39 return $this->$key."hahahah"; 40 } 41 private function formateName(){ 42 return "我叫{$this->name},我今年{$this->age}岁了!<br>"; 43 } 44 public function say(){ 45 echo $this->formateName(); 46 } 47 } 48 $zhangsan = new Person("张三丰",14,"男"); 49 //$zhangsan->setAge(99); 50 //$zhangsan->say(); 51 //echo $zhangsan->getAge("88"); 52 //$zhangsan->name="李四"; 53 // $zhangsan->name="李四"; 54 echo $zhangsan->name; 55 echo $zhangsan->age; 56 var_dump(isset($zhangsan->age)); 57 unset($zhangsan->age);
7 重点来了--php中的继承 |
1、如何实现继承?
给子类使用extends关键字,让子类继承父类;
class Stydent extends Person{}
2、实现继承的注意事项?
① 子类只能继承父类的非私有属性;
② 子类继承父类后,相当于将父类的属性和方法copy到子类,可以直接使用$this调用该属性。
③ PHP只能单继承,不支持一个类继承多个类。但是一个类进行多层继承。
class Person{};
class ChengRen extends Person{};
class Student extends ChengRen{};
//Student 类就同事具有了ChengRen类和Person的属性和方法。
3、方法覆盖(方法重写)
① 子类继承父类;
② 子类重写父类已有方法。
符合上述两个条件,称为方法覆盖。覆盖之后,子类调用方法,将调用子类的的方法。
同样,除了方法覆盖,子类也可以具有与父类同名的属性,进行属性覆盖。
如果,子类重写了父类方法,如何在子类中调用父类同名方法?
partent:: 方法名();
所以,当子类继承父类时,需在子类的构造中的第一步,首先调用父类构造进行辅助。
function __construct($name,$sex,$school);
partent::__construct($name,$sex);
$this->school = $school;。
1 class Person{ 2 public $name; 3 public $sex; 4 5 6 7 public function __construct($name,$sex){ 8 $this->name=$name; 9 $this->sex=$sex; 10 } 11 12 public function say(){ 13 echo "我叫{$this->name},我是{$this->sex}生! <br> "; 14 } 15 } 16 17 class Student extends Person{ 18 public $school; 19 public function __construct($school){ 20 $this->school=$school; 21 } 22 23 public function say(){ 24 parent::say(); 25 echo "我叫{$this->name},我是{$this->sex}生! <br> "; 26 } 27 function say1(){ 28 echo "今天下雨了,啦啦啦啦啦。<br>"; 29 } 30 } 31 32 $lalala = new Student("每天学习"); 33 $lalala->name= "lalala"; 34 $lalala->sex="不详"; 35 $lalala->say(); 36 $lalala->say1();
8 重点来了--php中的继承 |
1、一个类,被多个子类继承。
如果,这个类的某个方法,在多个子类中,表现出不同的功能,我们称这种行为为多态。
2、实现多态的必要途径;
① 子类继承父类;
② 子类重写父类方法;
③ 父类引用指向子类对象;
1 abstract class Person{ 2 3 abstract function say(); 4 function say1(){ 5 echo "我是Say1"; 6 } 7 } 8 class Chinese extends Person{ 9 function say(){ 10 echo "我是一个中国人<br>"; 11 } 12 } 13 class English extends Person{ 14 function say(){ 15 echo "I'am a English"; 16 } 17 } 18 19 /*$a = new Chinese(); 20 $a->say(); 21 22 $b = new English(); 23 $b->say(); */ 24 25 function func(Person $p){ 26 $p->say(); 27 }
学习时候的笔记,可能会有一些错误的地方,欢迎各位的批评指点。
反思,复盘,每天收获一点---------------------期待更好的自己