一、继承
类的继承,也叫类的扩展。继承将会影响到类与类,对象与对象之间的关系。继承有三大功能:继承:父类的二类成员自动成为子类的成员。
重写:覆写与父类/基类同名的成员(属性,方法)。
扩展:子类添加自身的方法来增加/扩展父类的功能。
代码举例:
classUser
{
public$name='apple';
protected$number='078';
private$age='31';
// protected static $nationality: '中国/CHINA';
publicfunctionwrite()
{
return"姓名 : {$this-> name} . 工号 :{$this-> number}";
}
}
classRobextendsUser
{
protected$number='066';
publicfunctionwrite()
{
//在子类中可以引用父类成员
// parent::write()
returnparent::write().' 他的工作能力很强,可重点培养。';
}
protected$profession=' IT大神';//属性扩展
//方法扩展
publicfunctionwrite1()
{
returnparent::write()."职业 : {$this->profession}";
}
}
$User=newUser;
echo $User->write().'
';
$Rob=newRob;
echo $Rob->write().'
';
echo $Rob->write1().'
';
输出效果:
二、抽象类的作用与实现
要理解什么是抽象类,就要先知道什么是抽象方法。我们在类里面定义的没有方法体的方法就是抽象方法。所谓的没有方法体指的是,在声明的时候没有大括号以及其中的内容,而是直接在声明时在方法名后加上分号结束,另外在声明抽象方法时方法还要加一个关键字”abstract”来修饰。
如:
abstractfunctionfav1();
abstractfunctionfav2();
所以,只要一个类里面有一个方法是抽象方法,那么这个类就定义为抽象类,抽象类也要使用“abstract”关键字来修饰;在抽象类里面可以有不是抽象的方法和成员属性,但只要有一个方法是抽象的方法,这个类就必须声明为抽象类,使用“abstract”修饰。
如:
abstractclassUser
{
var$test;
abstractfunctionfav1();
abstractfunctionfav2();
functionfav3(){
...
}
}
注意:
抽象类不能实例化,只能被继承。
任何一个类,如果它里面至少有一个方法是被声明为抽象的,那么这个类就必须被声明为抽象的。
抽象类不一定有抽象方法,有抽象方法的类,一定是抽象类。
抽象方法的可见性不能是private。
抽象方法在子类中,需要重写。
被定义为抽象的方法只是声明了其调用方式(参数),不能定义其具体的功能实现。
继承一个抽象类的时候,子类必须定义父类中的所有抽象方法。另外,这些方法的访问控制必须和父类中一样(或者更为宽松)。例如某个抽象方法被声明为受保护的,那么子类中实现的方法就应该声明为受保护的或者公有的,而不能定义为私有的。
方法的调用方式必须匹配,即类型和所需参数数量必须一致。
代码:
abstractclassUser
{
protected$name='王二小';
protected$age=40;
protectedfunctionwrite1()
{
return"姓名 : {$this-> name} . 工号 :{$this-> age}";
}
//只要一个类中有一个抽象方法,那么这个类就是:抽象类
abstractprotectedfunctionwrite2();
}
//实现类/工作类:是一个可以被实例化的普通类
//工作类不一定是可以被实例化的普通类,也可以是一个抽象类
//抽象类也可以被继承,抽象类也可以用在继承的上下文环境中
classRobextendsUser{
protected$profession=' IT大神';
//必须将抽象类中的抽象方法实现
protectedfunctionwrite2(){
returnparent::write1()."职业 : {$this->profession}";
}
}
//最终工作类:允许实例化
classWorkextendsRob
{
publicfunctionwrite2()
{
returnparent::write2();
}
}
$work=newWork();
echo $work->write2();
输出效果:
三、接口的基本语法
什么是接口?
如果一个类中,所有的方法都是抽象方法,且没有成员属性,则这个类被称为接口(interface)。使用接口,可以指定某个类必须实现哪些方法,但不需要定义这些方法的具体内容。
接口是通过interface关键字来定义的,就像定义一个标准的类一样,但其中定义所有的方法都是空的。
接口中定义的所有方法都必须是公有,这是接口的特性。
要实现一个接口,使用implements操作符。
类中必须实现接口中定义的所有方法,否则会报一个致命错误。
类可以实现多个接口,用逗号来分隔多个接口的名称。
接口也可以继承,通过使用extends操作符。
接口中也可以定义常量。接口常量和类常量的使用完全相同,但是不能被子类或子接口所覆盖。
interfaceiUser
{
//接口常量
constNATION='中国';
//接口方法
publicstaticfunctionwrite();
}
classUserimplementsiUser
{
protectedstatic$name='丁一';
publicstaticfunctionwrite()
{
returnself::$name.' 的国籍是 : '.iUser::NATION;
}
}
echoUser::write();
输出效果:
总结
1.类的继承,类似于a=b,b=c,所以a=c,这个等式被用在函数和类中,大大方便了程序员的工作,因为你只需要修改或者重新定义一个属性即可实现联动效果,而不必逐个修改属性的值。
2.如果不想要类方法被重写,可以在类方法或类前加上”final”一词即可。
3.既然抽象类不能被实例化,为什么还要设置一个抽象类呢。这是因为抽象类往往用来表征对问题领域进行分析、设计而得出的抽象概念,是对一系列看上去不同,但是本质上相同的具体概念的抽象总结。比如,在一个图形编辑软件的分析设计过程中,就会发现问题领域存在着圆、三角形这样一些具体概念,它们是不同的,但是它们又都属于形状这样一个概念,形状这个概念在问题领域并不是直接存在的,它就是一个抽象概念。而正是因为抽象的概念在问题领域没有对应的具体概念,所以用以表征抽象概念的抽象类是不能够实例化的。
4.接口类似于课代表,它是各科老师和同学们的连接桥梁,一个课代表对应一科老师,对应全班的同学。所以抽象类只能单继承,但接口却是多继承,类对接口的实现也是多实现。
5.终于明白程序员多么渴望拥有一个浓密帅炸的发型了。