继承
运动员 所拥有的的属性和方法:
姓名 身高 体重 所在球队 球员号码 讲话 行走 扣篮 运球
演员 所拥有的的属性和方法:
姓名 身高 体重 艺名 所属公司 讲话 行走 唱歌 演戏
我们可以把公用的成员提取出来,他们拥有部分相同的属性和方法 因为他们都是人类。
继承的好处
父类里面定义的成员可以不用再子类中重复定义,节约了变成的时间和代价
同一父类的子类拥有相同的父类定义类的成员,因此外部调用他们的时候可以一视同仁
子类可以修改和调整父类定义的类成员,我们称之为重写,一旦类修改了,就按照子类修改之后的功能执行
在php中可以用
extends
关键字来标示类的继承,后面跟父类的类名,extends
后面只能跟一个类的类名,这就是php中的单继承原则
访问控制
关键字 | 特点 |
---|---|
public | 公有类成员 可以在任何地方被访问 |
protected | 受保护的类成员,可以被其自身以及子类访问 |
private | 私有的类成员,只能被自身访问 |
静态成员,static
好处
使类的静态成员特性就可以共用属性。
定义
静态属性定义时在访问控制关键字后面添加static
关键字即可
调用
在类定义中使用静态成员的时候,用self
或者static
关键字紧跟着::操作符调用。
self与static的差异
其差异体现在继承时:slef永远绑定的是代码所在类;static调用时确定哪个类。常用static,更加符合常规逻辑。
在定义外部访问静态属性,我们可以用类名加::操作符的方法
来访问类的静态成员;使用parent
关键字技能访问父类的静态成员。
静态方法里面只能访问静态属性
访问 ClassName::method() 或者 ClassName::$property
如何使用静态成员
例如:老师要统计学生的数量,问题是,如果所有的操作,严格按照面向对象的思想去做,意味着会出现无数个对象,其中很多,仅仅为了辅助完成个别功能,也要定义类,实例化对象, 万物万事都是对象,难道真的要定义万事万物?
此时,通过在某些类上增加静态成员的方式,完成某类特定的操作。
总结:当使用静态成员时,认为被所有的当前类对象所共享的数据和操作,应该声明成静态的。被对象所独有的数据和操作,应该声明成为非静态的。
语法细节
无论采用对象还是类,都可以调用静态、非静态方法。但是涉及到语法严谨规范化。
类常量
常量一旦定义,不能修改,选择用常量的原因:之一,语法层面保证,数据不会被修改;之二,将特定的数据语义化,得到计算快,同时表述有逻辑含义。
定义常量
如果需要类,拥有某个不需要变化的数据,则可以通过定义类常量完成。定义通过const
关键字,执行名字和值,不需要访问修饰。
使用常量
通过::
访问
设计相关
设计层面,当需要完成某种约束规范时,怎么去实现?
抽象 abstract
通过关键字abstract
,限制类、方法。称之为抽象类、抽象方法
抽象类
限制之后,该类就不能用于实例化对象。
例如,在设计商品管理系统的时候,认为所有的商品(book,phone)应该都是某种类型的商品的实例,而不是goods对象,goods类仅仅是为了提供所有类型商品的公共属性和操作。如果满足设计需求,语法上可将goods定义为抽象,从而保证不会被实例化。
其作用是:语法层面的限制。
抽象方法
仅仅包含了方法的声明(方法名和形参列表),没有方法的实现(方法体),称之为抽象方法。
使用抽象方法的原因:需要限制子类,一定要存在,但是实现可以是不同的方法。例如任何类型的商品,都有获取商品名称的能力(方法),不同类型的商品获取的方式不一样。
终极 final
final可以用来修饰限制类、方法,也称之为终极类、终极方法。
final类
final修饰类导致类不能被继承使用。一个fianl类仅仅用来被实例化。
为什么要设计为final类呢?
设计层面,类达到某个级别的时候,就不能再继承拓展了。
final方法
final修饰方法导致方法不能被子类重写。
作用在于:为了保证所有的子类中实现完全一致的方法,才会将父类的方法声明为终极方法。
例如:价格是所有商品统一计算的,可以将价格获取定义在good类中,并声明终极方法,此时所有的子类使用的计算价格的方法都是统一的。
接口 interface
封装性:隐藏内部实现,仅仅开放外部接口,语法上,公共的方法就是外部接口。
接口实现技术:用来约束(限制)某个类(对象)应该具有满足公共方法(接口)列表的。
例如:作为一个usb设备厂商,设计程序。要求所有的设备都满足某个操作规范,该规范在面向对象设计时就可以设计成技术结构。
定义
关键字interface
进行定义,接口结构中,仅仅存在公共的抽象方法。接口的目的是定义标准化操作规范,而不去实现,由采用该接口的实体实现。
实现
关键字implements
进行实现接口。一个类可以实现多个接口,用,
连接起来。
接口和抽象类的差异
接口:制作标准化,主要目的是标准化时用接口。
抽象类:在普通类的基础上,增加了抽象方法。为子类提供公共成员的同时,额外的限定子类的某些成员。
语法上:
接口中的抽象方法,仅仅能是公共的。
抽象类中的抽象方法,可以是保护的和公共的。
设计模式
想法先行,语法后行
单例|单例模式
单个实例,单个对象,语法上一个类可以实例化无数个对象。
- 设计思想:如果一个类的一个对象就可以完成所有的功能
例如:通常的项目中,只需要操作一个数据库服务器,完成所有的功能。因此仅仅需要一个数据库操作对象即可。
既然存在一个对象可以完成功能的对象,就需要在语法层面上,限制该类去得到多个对象,只能得到一个对象,目的为了节约对象成本,这种设计,就被成为单例设计。
设计思路
私有化构造方法
限制在类外实例化对象,结果不能实例化对象,如何实例化对象?
如果可以在类内调用该构造方法,就可以完成实例化工作了。静态的公共方法
在没有对象前,可以使用类调用静态方法的方式。静态的私有方法
完善公共静态方法的业务逻辑,保证即使多次调用也只能得到一个对象
核心在于,第一次可以将对象存储起来,第二次调取对。私有化克隆方法
禁止被克隆。
class A{
//三私一公
private static $class;
private function __construct(){
}
private function __clone(){
}
public static function newClass(){
if(!isset(static::$class)){
static::$class = new A();
}
return static::$class;
}
}
单例的另一种体现形式
function getOne(){
static $class = null;
if(!isset($class)){
$class = new A();
}
return $class;
}
劣势:并没有从根本上解决单例问题,仍然可以new出来。
优势:灵活,不需要去更改类本身的结构,可以做到同时适应多个类。
所以实际开发中:
如果要严格限制单例效果,使用三私一公单例模式,如果仅仅想实现单例效果,就使用类外的实现
如果想实现其他类的单例,可以传参数
function getOne($classname){
static $classlist = array();
if(!isset($classlist[$classname])){
$classlist[$classname] = new $classname();
}
return $classlist[$classname];
}
工厂模式
从类的功能上讲,如果某个类的主要功能,用来生产其他类的对象,这样的类,称之为工厂类
工厂模式
class Factory{
//生产线
public static function getClass($class){
static $classList = array();
if(!isset($classList[$class])){
$classList[$class] = new $class();
}
return $classList[$class];
}
}
魔术方法
__tostring()
echo $obj;//需要快速展示某个对象的摘要信息时会使用该方法。__invoke($params)
当对象被当成方法调用时,这个方法会被自动调用
$obj();__call($name,$params)
当对象访问不存在的方法名称时,__call方法会被自动调用
这个方法的参数第一个就是调用的方法名称,第二个参数是方法调用的参数组成的数组__callStatic()
当对象访问不存在的静态方法名称时,__callStatic方法会被自动调用
这两个方法在php里面也被成为方法的重载__get($name)
读取不可访问属性的值时,会被调用__set($name,$value)
在给不可访问属性赋值时,会被调用__isset($name)
当对不可访问属性调用isset()或empty()时,__isset()会被调用__unset($name)
当对不可访问属性调用时,会被调用__clone()
$obj1 = $obj2 址传递 clone实现复制
相关函数
class_exists(类名)
method_exists(对象,方法名)
property_exists(对象,属性名)
interface_exists(接口名)
get_class(对象)
get_called_class()得到调用该方法的类
get_parent_class(类名)得到类的父类
is_object()判断是否是对象
is_a(对象,类名) instanceof判断是否是某个类的实例