php学习16-----抽象类,重载,接口技术
昨天学习了关于对象的继承,今天我们更进一步的学习一下面向对象的相关知识。
一、抽象类,抽象方法
1.抽象类
什么是抽象类?就是一个不能实例化的类;
定义形式:
abstract class 类名{};
主要作用:为了技术管理而设计的类;
2.抽象方法
什么是抽象方法?是一个只有方法头,没有具体方法体的方法定义形式;
定义形式:
abstract function 方法名(形参1,形参2...);
注意:上面的方法末尾一定有分号;
主要作用:为了技术管理而设计:要去下级类需要去实现这个方法的“具体做法”;
3.抽象类和抽象方法的细节
1.一个抽象方法必须在一个抽象类中;
2.反过来,一个抽象类中可以没有抽象方法---虽然不常见;
3.抽象方法是为了规定下级类中“必须”要具体去完整某个工作;
4.下级类中继承了上级的抽象方法,则要么去“实现该方法的具体内容”,要么自己也作为抽象类(即其继承的抽象方法仍然是抽象的);
5.子类实现父类的抽象方法,其形参也应该跟父类保持一致,其访问权限也不能更小;
二、重载技术overloading
1.重载的基本基础
重载在其他语言中的含义:
是指在一个类的对象中,有多个名字相同但形参不同的方法的现象;
类似这样:
class C{
function(){};
function($p){};
function($p,$p1,$p2){};
}
重载在php中的含义与上面不同
在php中是指,在对一个对象或类使用其未定义的属性或者方法的时候,其中一些处理机制;
比如:
class A{
public $p1 = 1;
}
$a = new A();
echo $a->p1; //1
echo $a->p2; //因为没有这属性,所以会出错。
而php中的重载技术就是来应对上述出错的情况的,是代码不出差,还能进行优雅处理;
2.属性重载
就是一个对象的不存在属性进行使用的时候,这个类中预设定好的应对办法(处理机制):
属性,本质就是变量,只有四个操作:
取值:当一个对象的不存在属性取值时,就会调用内部的方法__get();
赋值:当一个对象的不存在的属性进行赋值,就会自动调用内部方法__set();
判断:当一个对象的不存在属性进行isset()判断时,就会自动调用内部方法:__isset();
销毁:当一个对象的不存在的属性进行unset()销毁时,就会自动调用内部方法:__unset();
以上 的四个方法被称作魔术方法
__get():
在对一个对象不存在的属性进行取值的时候,会自动调用该方法。
我们其实可以使用该方法来对这种意外情况进行某种特别处理。
其中该方法可以带一个形参,表示这个要对之取值的不存在的属性名;
__set($p1,$p2):
当一个对象 的不存在属性进行赋值的时候,就会自动调用这个内部的魔术方法;它有两个形参,分别代表要对不存在的属性进行赋值时候的“属性名”和“属性值”;
这个方法和__get()方法一同使用可以是我们的类有一种可扩展性的特性:
__isset();
当对一个对象的不存在的属性进行isset()判断的时候,就会自动调用内部的方法:__isset();
__unset()
当一个对象的不存在属性进行unset()销毁操作时,,就会自动调用该内部方法。
3.方法重载
当对一个对象的不存在的实例方法进行“调用”的时候,会自动调用类中的__call()这个魔术方法;
当一个对象的不存在的静态方法时,进行“调用”的时候,会自动调用类中__callstatic()这个静态魔术方法;
三、接口(interface)技术
1.什么是接口
当一个抽象类中没有任何实质的成员,那么这个抽象类中只有抽象方法,接口就是类似于这种抽象类。
接口,就是规定,里面只能放“抽象方法”和“常量”的一种类似类的语法结构。
2.接口(interface)定义形式
interface 接口名{
常量1;
常量2;
抽象方法1;
抽象方法2;
}
说明:
接口中,只有常量和抽象方法两种成员;
接口常量的是由形式为:接口名称::常量名称;
接口中的抽象方法,不要使用abstract修饰,也不需要使用访问控制修饰符,因为其天然就是public;
3.为什么需要接口
面向对象编程思想是对“现实世界”的描述;
现实世界往往都是多继承的,但出于降低类跟类之间复杂关系的复杂度可考虑,就将语言设计为单继承,但这样,就无法表达出现实世界的多继承性;接口就是对没有多继承的类之间关系的一个补充;
因为:接口可以实现“多继承”---但此时不称为继承,而是称为实现;类1实现了接口1,其本质就是类1中,有了接口1的特征信息。
4.使用形式
形式为:
class 类名 implements 接口名1,接口名2....{}
其实接口跟接口也可以继承:
interface 接口1 extends 接口2{}
5.类和接口的大总结
四、进一步完善msqldb
1.现有已经完成的功能,做优化处理;
2.添加更多的功能,要求继续实现如下功能:
1.用该类的对象可以执行任意的增删改语句,并返回布尔值;
2.用该类的对象可以执行返回一行数据的“查询语句”:结果是一个一维数组;
3.用该类的对对象可以执行返回多行数据的“查询语句”:结果是一个二维数组;
4.用该类的对象可以执行返回一个数据的“查询语句”:结果是一个数据值;
class MySQLDB{
//设置私有属性,用来存储连接标识符;
private $link = null;
//这里设置私有属性,可以存储信息
private $host;
private $port;
private $user;
private $pass;
private $charset;
private $dbname;
function __construct($config){
//将这些基本连接信息保存起来;
//这里给输入信息为空的情况下设置默认值
$this->host = !empty($config['host'])? $config['host']:"localhost";
$this->port = !empty($config['port'])? $config['port']:"3306";
$this->user = !empty($config['user'])? $config['user']:"root";
$this->pass = !empty($config['pass'])? $config['pass']:"123456";
$this->charset = !empty($config['charset'])? $config['charset']:"utf8";
$this->dbname = !empty($config['dbname'])? $config['dbname']:"diyigedb";
//这里开始连接数据库
$this->link = @mysql_connect("{$this->host}","{$this->user}","{$this->pass}") or die("连接失败");
//内部执行设置字符编码
$this->setCharset($this->charset);
//内部执行选择数据库
$this->selectDB($this->dbname);
}
//设置字符编码
function setCharset($charset){
mysql_query("set names $charset");
}
//选择数据库名称
function selectDB($dbname){
mysql_query("use $dbname");
}
//关闭数据库
function closeDB(){
mysql_close($this->link);
}
//这里是执行增删改语句,可以返回布尔值
function exec($sql){
$result = mysql_query($sql);
if($result ===false){
echo "<p>sql语句执行失败,请参考如下信息:";
echo "<br>错误代号:".mysql_errno();
echo "<br>错误信息:".mysql_error();
echo "<br>错误语句:".$sql;
die();
}
return true;
}
//这里执行了一个返回一行数据语句,可以返回一行数据
function GetOneRow($sql){
$result = mysql_query($sql);
//这里判断有没错误,有错误就输出错误信息
if($result ===false){
echo "<p>sql语句执行失败,请参考如下信息:";
echo "<br>错误代号:".mysql_errno();
echo "<br>错误信息:".mysql_error();
echo "<br>错误语句:".$sql;
die();//这里会中断
}
//如果没有错误,则从结果集中抓取一行数据
$rec = mysql_fetch_assoc($result);
return $rec;
}
//这里执行了一个返回多行数据的语句,可以返回二维数组
function GetRows($sql){
}
//这里执行了一个返回一个数据的语句,直接返回一个值
function GetOneData($sql){
}
}