什么是面向对象?
面向对象编程,也就是我们常说的OOP,其实是面向对象的一部分。面向对象一共有3个部分:面向对象分析(OOA)、面向对象设计(OOD)、面向对象编程(OOP)。我们现在将要学习的就是面向对象的编程,而面向对象编程中两个首要了解的也是很重要的概念就是类和对象。
类与对象
对象:具有某种属性和行为的实体,例如人有姓名和年龄等属性,具有工作、吃饭、睡觉等行为。
类:具有相同特征和功能的对象的抽象
面象对向的三大特点
封装性、继承性、多态性
首先简单理解一下抽象:我们在前面定义一个类的时候,实际上就是把一类事物共有的属性和行为提取出来,形成一个物理模型(模版),这种研究问题的方法称为抽象
一、封装性
封装就是把抽取出来的数据和对数据的操作封装在一起,数据被保护在操作的内部,程序的其他部分只有被授权的操作(方法)才能对数据进行操作。
php提供了三种访问控制修饰符
public 表示全局,本类内部,类外部,子类都可以访问
protected 表示受保护的,只有本类或子类可以访问
private 表示私有的,只有本类内部可以访问
以上三种修饰符既可以修饰方法也可以修饰属性(变量),方法如果没有访问修饰符则默认是public,成员属性必须指定访问修饰符。
<?php
class Person{
public $name;
protected $age;
private $salary;
function __construct($name,$age,$salary){
$this->name=$name;
$this->age=$age;
$this->salary=$salary;
}
public function showinfo(){
echo $this->name."||".$this->age."||".$this->salary;
}
}
二、继承性
子类自动继承一个或多个父类中的属性与方法,并可以重写或者添加新的属性或方法。这个特性简化了类和对象的创建,提高了代码的可重用性。
继承就是一个子类(Subclass)通过 extends 父类 把父类(BaseClass)中的public 和 protected 的属性和方法继续下来,不能继承private属性和方法
语法结构:
class 父类名{}
class 子类名 extends 父类名{}
细节:
1、一个子类只能继承一个父类(这里指直接继承);但是一个接口可以继承多个接口
2、在创建某个子类对象时,默认情况下不会自动调用其父类的构造函数,除非子类中没有构造函数
3、在子类中如果需要访问父类的方法(构造方法、成员方法 方法的修饰符为protected或private),那么可以使用 父类::方法名 或者 parent::方法名 来完成【这里parent和以前提到的self都均为小写,大写报错】
4、如果一个子类(派生类)的方法名与父类的方法名完全一样时(public,protected),我们称为方法覆盖或方法重写(override)
三、多态性
多态(Polymorphism)按字面上意思理解就是“多种形状”。可以理解为多种表现形式,也即“一个对外接口,多个内部实现方法”。在面向对象的理论中,多态性的一般定义为:同一个操作作用于不同的类的实例,将产生不同的执行结果。也即不同类的对象收到相同的消息时,将得到不同的结果。
PHP是一种弱类型语言(例如$i可以是任何类型的变量),不支持通过重载实现多态,但是PHP可以变向的实现多态效果
在实际的应用开发中,采用面向对象中的多态主要在于可以将不同的子类对象都当作一个父类来处理,并且可以屏蔽不同子类对象之间所存在的差异,写出通用的代码,做出通用的编程,以适应需求的不断变化。
在实际的应用开发中,通常为了使项目能够在以后的时间里的轻松实现扩展与升级,需要通过继承实现可复用模块进行轻松升级。在进行可复用模块设计时,就需要尽可能的减少使用流程控制语句。此时就可以采用多态实现该类设计。
多态的好处:大大提高程序的扩展,增强系统的灵活性,降低模块间的耦合。
多态的应用:父类对象的引用指向子类对象,其实本质上就是一个向上转型。
举个模型例子,一家公司有员工类(Employee),还有其子类:销售(Sales)、市场(Market)、工程师(Engineer)等。某一天老板招待所有的员工开了个短会,完了之后对所有的员工(Employee)说,大家回去工作吧。在这里我们可以认为老板调用了所有员工对象的continueToWork()方法,而不是对一个个员工细说做什么工作,比如对销售部说你去制定销售计划(调用makeSalePlan();),对市场部说你去制定产品的价格(调用makeProductPrice();)…这种逐个细说的方式并不是面向对象,而是面向个体。可以确定的是,员工类应该有一个方法continueToWork()。而员工如何实现他们工作的方法却只有精确到子类才能确定,因为不同的员工的工作方式是不一样的。因此,我们很多时候只需要关心对象的父类型,而忽略更精确的子类型,比如上面老板叫大家回去工作时,他对全体员工说的,主要指的是全体员工类型
实现实例:
<?php
abstract class Employee{
abstract function continueToWork();
}
class Sales extends Employee{
private function makeSalePlan(){
echo "make sale plan";
}
public function continueToWork(){
$this->makeSalePlan();
}
}
class Market extends Employee{
private function makeProductPrice(){
echo "make product price";
}
public function continueToWork(){
$this->makeProductPrice();
}
}
class Engineer extends Employee{
private function makeNewProduct(){
echo "make new product";
}
public function continueToWork(){
$this->makeNewProduct();
}
}
class Demo{
//添加父类类型限制传参类型,使其满足多态第三点要求,父类指向子类
public function Work(Employee $employeeObj){
$employeeObj->continueToWork();
}
}
//调用
$obj = new Demo();
$obj->Work(new Sales());//make sale plan
$obj->Work(new Market());//make product price
$obj->Work(new Engineer());make new product
参考:
https://blog.csdn.net/whd526/article/details/70242918
https://www.jb51.net/article/30248.htm