抽象类与接口实战
一、抽象类
什么是抽象类
- 通过abstract关键字定义的类为抽象类,抽象类:部分分离了“设计与实现”。
<?php
//父类通过abstract关键字设置为抽象类后不能被实例化
//抽象类:分离了“设计与实现”
abstract class user
{
protected $name = '张起灵';
public function write()
{
return '姓名:' .$this -> name;
}
//抽象方法:,没有实现,只有声明,子类中必须实现它
abstract protected function write2();
}
//子类,实现类,工作类,真正干活的是子类
class Work extends user
{
protected $profession = '守护者';
public function write2()
{
return parent::write().'职业:'.$this->profession;
}
}
//必须通过子类来调用抽象方法
$user = new Work();
//echo $user->write();
echo $user->write2();
二、接口
1.单接口
<?php
//接口:完全分离了“设计与实现”
//1.接口使用场景:单接口
interface iUser
{
//在接口中所有成员都是抽象的
//接口成员的访问控制必须是public
public function write();
//不允许有属性,只允许定义接口常量
const NAME = 'ADMIN';
//接口还可以有构造方法(后面讲)
}
//接口的实现类
class user implements iUser
{
protected $profession = '警察';
//接口中的抽象方法必须在实现类中实现
public function write()
{
return '职业:'.$this->profession;
}
}
//调用接口
$user = new user();
echo $user->write();
2.接口之间的继承
<?php
//接口之间的继承
//php中禁止多重继承:单继承
//接口1
interface iUser1
{
const AGE = 2000;
}
//接口2
interface iUser2 extends iUser1
{
const USER_NAME = '观音菩萨';
}
//接口3
interface iUser3 extends iUser2
{
public function write();
}
//实现类
class User implements iUser3
{
//必须实现接口中的抽象方法
public function write()
{
return '姓名:'.iUser2::USER_NAME.' 年龄:'.iUser1::AGE;
}
}
$user = new User;
echo $user->write();
3. 用抽象类来实现接口
<?php
//接口应用场景3:用抽象类来实现接口
//定义一个数据库的CURD
interface iDbBase
{
//新增
public static function insert($db,$data);
//查询
public static function select($db,$options=[]);
//更新
public static function update($db,$options);
//删除
public static function delete($dbm,$where);
}
//实现类:使用抽象类来充当
abstract class aDb implements iDbBase
{
//使用单例模式连接:创建类的唯一实例,唯一对象
protected static $db =null;
//抽象类充当接口实现类时,不用必须实现接口中的抽象方法
//当实现类中的方法中有一些公共操作时,可以将这些操作放在中间的抽象类中实现它
public static function connect($dsn,$username,$password)
{
if(is_null(self::$db)){
//如果当前连接对象时null,表示未连接数据库
self::$db = new PDO($dsn,$username,$password);
}
return self::$db;
}
}
//类的正真实现类
class DB extends aDb
{
//新增
public static function insert($db,$data)
{
}
//查询
public static function select($db,$options=[])
{
return $db->query('SELECT * FROM `user` LIMIT 3')->fetchAll(PDO::FETCH_ASSOC);
}
//更新
public static function update($db,$data)
{
}
//删除
public static function delete($db,$data)
{
}
}
//连接数据库
//连接参数
$config = [
//类型
'type' => $type ?? 'mysql',
//默认数据库主机名(IP)
'host' => $host ?? 'localhost',
//默认数据库名
'dbname' => $type ?? 'tp5',
//默认字符编码集
'charset' => $type ?? 'utf8',
//默认端口号
'port' => $username ?? '3306',
//默认用户名
'username' => $username ?? 'root',
//默认用户的密码
'password' => $password ?? 'wang1111'
];
$dsn = sprintf('%s:host=%s;dbname=%s;',$config['type'],$config['host'],$config['dbname']);
$username = $config['username'];
$password = $config['password'];
$db = DB::connect($dsn,$username,$password);
//调用实现类DB中的select()进行查询
foreach (DB::select($db) as $user){
print_r($user);
}
三、Trait
<?php
//Trait:特性
//trait:临时类,类中类,可以嵌入到宿主类
//trait实现了一个类的横向扩展,继承实现了类的垂直功能扩展
//可以使用类的语句,但不是类
//不能被直接实例化
trait tDemo
{
//1.常规成员
protected $name = '胡歌';
public function getName()
{
return $this->name;
}
//2.静态成员
protected static $sex = '男';
public static function getSex()
{
return self::$sex;
}
//3.抽象成员
public static $age;
abstract static function getAge();
}
//在一个宿主类/工作类/实现类中使用
class User
{
//类中使用use关键字引用trait成员
use tDemo;
//在宿主类中必须将trait中的抽象方法实现了
static function getAge()
{
return self::$age;
}
}
$user = new User;
User::$age = 20;
echo $user->getName().':'.$user->getSex().'|'.$user->getAge();
四、学习总结
1.抽象类
通过
abstract
关键字定义的类为抽象类,抽象类:部分分离了“设计与实现”抽象类不能被实例化
通过子类来调用抽象方法
任何一个类,如果它里面至少有一个方法是被声明为抽象的,那么这个类就必须被声明为抽象的
继承一个抽象类的时候,子类必须实现父类中的所有抽象方法
2.接口
通过
interface
关键字来定义接口对接口的使用是通过关键字
implements
接口不能定义成员变量(包括类静态变量),能定义常量
子类必须实现接口定义的所有方法
接口只能定义不能实现该方法
接口中的方法和实现它的类默认都是public类型的
3.Static类/方法
可以不实例化类而直接访问
静态属性不可以由对象通过->操作符来访问,用::方式调用
4.Trait
Trait字面意思是”特征,特点”,我们可以理解为使用trait关键字,可以给php的类添加新的特性
用
trait
关键字来定义trait类trait实现了一个类的横向扩展,继承实现了类的垂直功能扩展
用
use
关键字来引用trait成员可以使用类的语句,但不是类
不能被实例化