类的继承、抽象、和接口的实例
1 类的继承示例
类继承的三大特性 1继承 2重写 3扩展
<?php
//类继承的三大特性 继承 重写 扩展
//父类 猫科动物
class CatType
{
private $eat='我们都是吃肉的';
protected $eat1='我们经常吃肉';
private $eat2='我们经常吃肉';
protected $test='测试';
function eat() //食物方法
{
echo '食物: ',$this->eat,'<br>';
echo '经常吃: ',$this->eat1,'<br>';
echo '经常不吃: ',$this->eat2,'<br>';
}
public function info() //信息方法
{
echo '动物类型: 猫科动物 ','<br>';
}
}
//子类 老虎
class Tiger extends CatType
{
/*属性扩展
*
* */
private $name='老虎';
private $sex='母';
private $age='2';
public $eat='我们吃素的'; //因为是私有的无法重写
public $eat1='我们经常不吃素的'; //重写属性 重写属性必须大于等于 父类访问修饰的范围
public function info() //重写信息方法
{
parent::info(); //调用父类信息方法
echo '动物名:',$this ->name,'<br>';
echo '性别: ',$this ->sex,'<br>';
echo '年龄: ',$this ->age,'<br>';
$this ->eat(); //调用继承下来的父类食物方法
echo '测试 private: ',$this ->eat2,'<br>'; //报错父类private修饰的属性无法被访问
echo '测试 protected: ',$this ->test,'<br>';//测试能否访问 protected修饰的属性
}
}
$cat = new Tiger(); //实例化
$cat->info();
2 类的抽象示例
<?php
//抽象类
abstract class Father {
public abstract function setInfo($data); //抽象方法
public function getInfo($data) {
echo '获取信息<br>';
foreach ($data as $value):
echo $value,'<br>';
endforeach;
}
}
//继承
class Sons extends Father
{
//重写实现父类的抽象方法
public function setInfo($data) {
echo '重新实现父类的抽象方法<br>';
foreach ($data as $key=>$value):
echo $key.' '.$value,'<br>';
endforeach;
}
}
$data=['id'=>1,'name'=>'张三','age'=>20,'hobby'=>'编程'];
//测试
$stu=new Sons();
$stu->setInfo($data); //重新实现父类的抽象方法
echo '<hr>';
$stu->getInfo($data); //获取信息
3 类的接口示例
<?php
//声明接口
interface IFather
{
const MAP = '地球';
function fun1();
function fun2();
}
//接口实现
class Sons implements IFather
{
private $nation = '中国';
private $city = '贵州';
public function fun1()
{
echo $this->nation, '<br>';
}
public function fun2()
{
echo $this->city, '<br>';
}
}
//访问接口中的常量
echo IFather::MAP,'<br>';
(new Sons)->fun1();
(new Sons)->fun2();
效果图:
3.1 接口的多重实现
类不允许多重继承,但是接口允许多重实现。
<?php
//声明接口
interface IFather
{
const MAP = '地球';
function fun1();
}
interface IFather2
{
function fun2();
}
//接口实现
class Sons implements IFather,IFather2
{
private $nation = '中国';
private $city = '贵州';
public function fun1()
{
echo $this->nation, '<br>';
}
public function fun2()
{
echo $this->city, '<br>';
}
}
//访问接口中的常量
echo IFather::MAP,'<br>';
(new Sons)->fun1();
(new Sons)->fun2();
效果图和上面一个一样
4 总结:
4.1 继承
类的继承:子类可以继承所有父类中的属性和方法,但是父类中的private属性在子类中是不能被访问的
类的扩展:子类中除了使用父类的属性和方法,还可以添加自己的属性和方法
类的重写:父类中的属性和方法可以在子类中被重新定义
只有方法的声明没有方法的实现称为抽象方法
- 一个类中只要有一个方法是抽象方法,这个类必须是抽象类。
- 抽象类的特点是不能被实例化
- 子类继承了抽象类,就必须重新实现父类的所有的抽象方法,否则不允许实例化
- 类中没有抽象方法也可以声明成抽象类,用来阻止类的实例化
4.2 抽象(abstract)
abstract修饰的方法是抽象方法,修饰的类是抽象类
只有方法的声明没有方法的实现称为抽象方法
一个类中只要有一个方法是抽象方法,这个类必须是抽象类。
抽象类的特点是不能被实例化
子类继承了抽象类,就必须重新实现父类的所有的抽象方法,否则不允许实例化
类中没有抽象方法也可以声明成抽象类,用来阻止类的实例化
4.3 接口(interface)
- 如果一个类中所有的方法是都是抽象方法,那么这个抽象类可以声明成接口
- 接口是一个特殊的抽象类,接口中只能有抽象方法和常量
- 接口中的抽象方法只能是public,可以省略,默认也是public的
- 通过implements关键字来实现接口
不能使用abstract和final来修饰接口中的抽象方法。
在接口的多重实现中,如果有同名的方法,只要实现一次即可
类可以继承的同时实现接口