PHP 抽象类与接口实战

①: __CLASS__返回值是当前类的名称,如果有命名空间命名空间也一起返回

<?php
namespace _0120;
class demo {

	public function getFormName() {

		return __CLASS__;
	}
}
$obj = new demo();
echo $obj->getFormName();
?>

打印如下:
在这里插入图片描述
②:__DIR__查看当前脚本所在目录
③:类名1::class :返回一个类名字符串,这个类名就是 类名1

类的自动加载技术:

要在PHP脚本中引用一个其他脚本的类,可以不用关心这个类是否已经导入,而是实现自动导入。
在PHP标准函数库中提供了一个自动加载文件的注册函数 spl_autoload_register(callback) ,可以实现这个功能.这个函数有一个参数可以设置成一个回调,这个回调就是自定义的加载方法。在当前脚本引用一个未加载的文件时, 会自动调用它的回调方法来加载这个文件,回调函数的参数就是当前要加载的类文件(类名)。

spl_autoload_register(function ($className){
	$path = str_replace('\\', '/', $className);
	$path = __DIR__ . '/'.$path . '.php';
	if (file_exists($path)) {
		require $path;
	}
});

抽象类的原理与实现:

abstract: 定义抽象方法/抽象类
类中只要有一个抽象方法, 该类就应该声明为抽象类
抽象方法: 抽象类中没有具体实现的方法叫抽象方法

  • 1、抽象类只能被继承,不能实例化。
  • 2、抽象类的定义的抽象方法必须在子类中实现。
  • 3、实现抽象方法的子类方法可见性不能低于抽象方法原定义。
    抽象方法是public, 子类方法只能是public
    抽象方法是protected, 子类方法只能是protected/public
一个抽象类必须被扩展为一个特定的类,我们才能创建类实例,使用类中功能
<?php
abstract class person {

	public $product;

	public function __construct($product = '电脑') {
		$this->product = $product;
	}
	// 该方法不需要重写, 可以通过子类对象访问,应该设置为public
	public function get() {
		return $this->product;
	}
	// 修改属性方法,设置为抽象方法,交给子类实现
	// 因为类中有了一个抽象方法, 所以这个类Person也必须设置抽象类, 不允许直接实例化
	abstract public function set($value);
}
// 子类Stu 扩展了父类 Person
class stu extends person {
	// 注意: 构造方法不会自动继承, 必须手动重写
	public function __construct($product) {
		parent::__construct($product);

	}
	// 子类中必须实现抽象父类中的抽象方法
	public function set($value) {
		$this->product = $value;
	}
}
$obj = new stu('笔记本');
echo '产品名字是:' . $obj->get();
echo '<hr>';
// 调用子类的重写的抽象方法setName(),来设置属性
$obj->set('手机');
echo '产品名字是:' . $obj->get();
?>
  • 在实际开发过程中, 通常并不会直接使用一个父类/超类,而是在父类中定义一些方法声明
  • 并且确信这个方法肯定是会被子类重写的, 父类中没必要实现,只要给一个方法编写规范即可。这样就实现了面向对象开发(软件开发)的基本原则:对于增加是开放的,对于更新是封闭的
  • 这个规范包括方法的名称, 参数列表等,具体实现就完全交给子类去完成了
  • 相当于公司的部门主管, 接受到老板的任务, 只把属于自己的部分做了, 其它部分, 设置一个标准交给下属去完成
  • 这个老板就是接口,我们一会会讲到, 这个部门经理,我们用抽象类实现(抽象类必须实现接口的全部方法,且可以有自己方法和属性), 而下属就是子类啦,最终干活的就是子类

接口与实现

接口定义:interface 接口名
类是对象的模板(类是接口的实现),对象是类的实例。
将一些具有共同特征的类进行抽象再往上走一层 接口 是类的模板,接口中的方法全部是抽象方法,类实现(implements)接口必须把方法全部实现,但在类中也可以有自己的属性和方法。
什么时候需要在类里面创建属性(public、protected)?
要被类中的所有方法访问时就应该设置属性,否则如果仅仅只是某个方法使用只需要在方法中定义变量即可。

  • interface: 指定某个类必须实现的方法,但不需要定义方法的具体实现过程
  • 接口中仅允许出现: 方法与类常量
  • 接口的方法可见性必须是: public
  • 接口的方法体必须是空的
  • 接口是类的代码模板, 可以像类一样有父子继承关系,例如父接口, 子接口
  • implements: 类实现接口的关键字, 读音: ['ɪmplɪmɛnts,应波罗曼次]
  • 如果仅是部分实现接口中的方法, 请用一个抽象类来实现它
<?php
namespace admin;
interface iVehicle{
	// 驱动方式: 汽车, 新能源
	public function setFuel($fuel);
	// 用途
	public function setPurpose($purpose);
}
// Car 类 实现了接口:  iVehicle
class Car implements iVehicle{
	public $fuel;
	public $purpose;

	// 必须实现的接口方法
	public function setFuel($fuel){
		$this->fuel = $fuel;
	}
	// 必须实现的接口方法
	public function setPurpose($purpose){
		$this->purpose = $purpose;
	}
	// 类中自定义的对象方法
	public function getInfo(){
		return $this->fuel . $this->purpose . '车 <br>';
	}
}
// Auto 类 实现了接口:  iVehicle
class Auto implements iVehicle{
	public $fuel;
	public $purpose;

	// 必须实现的接口方法
	public function setFuel($fuel){
		$this->fuel = $fuel;
	}
	// 必须实现的接口方法
	public function setPurpose($purpose){
		$this->purpose = $purpose;
	}
	// 类中自定义的对象方法
	public function getInfo(){
		return $this->fuel . $this->purpose . '车 <br>';
	}
}

// Car类的实例化
$car = new Car();
$car->setFuel('新能源');
$car->setPurpose('公交');
echo $car->getInfo();

// Auto类的实例化
$car = new Auto();
$car->setFuel('家用');
$car->setPurpose('燃油');
echo $car->getInfo();

接口实战CRUD封装

<?php
namespace _0122;
interface ICurd {
	//插入
	public function creat($data);
	//更新
	public function update($data, $where);
	//读取
	public function read();
	//删除
	public function delete($where);

}
// 创建Db类, 实现iCurd接口,完成基本的数据库操作
class Db implements ICurd {
	//数据库连接对象
	protected $pdo = null;
	//数据表名称
	protected $table;
	//连接数据库并设置默认数据表名称
	public function __construct($dsn, $username, $password, $table = 'movies') {
		$this->pdo = new \PDO($dsn, $username, $password);
		echo '数据连接成功!';
		echo '<hr>';
	}
	// 新增, 参数是数组: 新记录的键值对
	public function creat($data) {
		// 字段列表   INSERT INTO '数据表' (`字段1`,`字段2`) VALUES('值1','值2')
		$fields = ' (mov_id, name, iamge, detail, cate_id) ';
		// 值列表
		$values = ' (:mov_id, :name, :iamge, :detail, :cate_id) ';
		// 创建SQL语句
		$sql = 'INSERT INTO ' . $this->table . $fields . ' VALUES ' . $values;
		// die($sql);
		// 预处理执行新增操作
		$stmt = $this->pdo->prepare($sql);
		echo '<pre>' . print_r($data, true);
		$stmt->execute($data);
		echo '<hr>';
		// 返回新增数量, 新增记录的ID组成的数组
		return [
			'count' => $stmt->rowCount(),
			'id' => $this->pdo->lastInsertId(),
		];
	}
	//更新
	public function update($data, $where) {
		// UPDATA `数据表` SET `字段1`=`值1`,`字段2`=`值2` WHERE 更新条件
		// 难点在于SET 参数的处理上,利用传入的$data数组,进行拆装

		// 获取数组的键名组成的数组
		$keyArr = array_keys($data);
		$set = '';
		// 遍历键名表示的字段列表,拼装预处理需要的sql语句,注意占符符的表示
		foreach ($keyArr as $value) {
			$set .= $value . '=:' . $value . ', ';
		}
		// 去掉最后一个逗号, 注意每个逗号后有一个空格,去除时也要带上这个空格
		$set = rtrim($set, ',');
		// 预处理执行更新操作
		$sql = 'UPDATE ' . $this->table . ' SET ' . $set . ' WHERE ' . $where;
		$stmt = $this->pdo->prepare($sql);
		$stmt->execute($data);
		// 返回被更新的记录数量
		return $stmt->rowCount();

	}
	//读取
	public function read($fields = '*', $where = '', $limit = '0, 5') {
		// SELECT '字段列表' FROM '数据表名' WHERE 查询条件
		$where = empty($where) ? '' : ' WHERE ' . $where;
		$limit = ' LIMIT ' . $limit;
		// 预处理查询操作
		$sql = 'SELECT ' . $fields . ' FROM ' . $this->table . $where . $limit;
		$stmt = $this->pdo->prepare($sql);
		$stmt->execute();
		// 返回二维数组表示的查询结果集
		return $stmt->fetchAll(\PDO::FETCH_ASSOC);

	}
	// 删除: 与更新一样, 这也是危险的写操作, 不允许无条件删除
	public function delete($where) {
		// DELETE FROM `数据表` WHERE 删除条件
		$sql = 'DELETE FROM ' . $this->table . ' WHERE ' . $where;
		$stmt = $this->pdo->prepare($sql);
		$stmt->execute();
		return $stmt->rowCount();
		echo '删除成功!';
	}

}
$dsn = 'mysql:host=localhost;dbname=sordidez';
$username = 'root';
$password = 'root';
//创建数据库操作对象
$db = new Db($dsn, $username, $password);
//插入数据  mov_id,name,iamge,detail,cate_id
$data = [
	'mov_id' => 10,
	'name' => '长江七号',
	'image' => '10.jpg',
	'detail' => 'hhh',
	'cate_id' => 1,
];
$res = $db->creat($data);
//读取数据
print_r($db->read());
echo '<hr>';
//更新数据
$data = [
	'name' => '长江七号2',
	'detail' => 'xxx',
];
$where = 'mov_id=10';
$db->update($data, $where);
//删除数据
$where = 'mov_id=10';
$db->delete($where);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值