抽象类:

抽象类不能被实例化。抽象类中只定义(或部分实现)子类需要的方法。子类可以继承它并且通过实现其中的抽象方法,使抽象类具体化。

我们可以用一个abstract关键字来定义一个抽象类,示例如下:

<?php

abstract class Animal{
//抽象类中可以定义属性
protected $animal = 'animal';
//抽象类中也可以定义非抽象方法
public function printit($name){
$this->animal = $name;
echo $this->animal;
}
//抽象方法
abstract public function setit();
}

抽象类的特性:

1)、定义为抽象的类不能被实例化。

抽象类和普通类一样,都可以创建方法和属性,那么抽象类可以像普通类那样被实例化吗?

<?php

abstract class Animal{
//抽象类中可以定义属性
protected $animal = 'animal';
//抽象类中也可以定义非抽象方法
public function printit($name){
$this->animal = $name;
echo $this->animal;
}
//抽象方法
abstract public function setit();
} $Animal = new Animal();

运行结果:Fatal error: Cannot instantiate abstract class Animal in D:\phpStudy\WWW\demo\abstract.php on line 15

运行结果显示,不能实例化抽象类Animal,现在知道咯,抽象类不能像普通类那样被实例化的哟。

2)、如果它里面至少有一个方法是被声明为抽象的,那么这个类就必须被声明为抽象的。

抽象方法用abstract关键字声明,其中不能有具体内容。你可以像声明普通类方法那样声明抽象方法,但要以分号而不是方法体结束。而在大多数情况下,抽象类中至少要有一个抽象方法,否则这个抽象类也就没有抽象的意义了,也就是说,这个抽象类内可以没有抽象方法只有普通方法,但是,你也没必要将这个类声明称抽象类了,直接去掉abstract变成普通类就行了。

<?php

class Animal{
//抽象类中可以定义属性
protected $animal = 'animal';
//抽象类中也可以定义非抽象方法
public function printit($name){
$this->animal = $name;
echo $this->animal;
}
//抽象方法
abstract public function setit();
}

运行结果:Fatal error: Class Animal contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (Animal::barking) in D:\phpStudy\WWW\demo\abstract.php on line 13

结果显示了一个致命的错误,说类Animal包含了一个抽象方法,所以这个类必须被声明为抽象类或者实现有抽象方法setit()的类。

3)、被定义为抽象的方法只是声明了其调用方式(参数),不能定义其具体的功能实现。

4)、继承一个抽象类的时候,子类必须定义父类中的所有抽象方法(这些方法的访问控制必须和父类中一样(或者更为宽松)。)

创建抽象方法后,要确保所有子类中都实现可该方法,但实现的细节可以先不确定。

如果创建了一个继承自抽象类Animal的普通类,但是不实现其中的抽象方法,会发生什么呢?

<?php

abstract class Animal{
//抽象类中可以定义属性
protected $animal = 'animal';
//抽象类中也可以定义非抽象方法
public function printit($name){
$this->animal = $name;
echo $this->animal;
}
//抽象方法
abstract public function setit();
} class Fish extends Animal{ }

运行结果:Fatal error: Class Fish contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (Animal::barking) in D:\phpStudy\WWW\demo\abstract.php on line 17

这个和只有抽象方法没有把类定义为抽象类发生的错误一样,所以抽象类的每个子类必须实现抽象类中的所有抽象方法,或者把他们自身也声明为抽象方法。

扩展类不仅仅负责简单实现抽象类中的抽象方法,还必须重新声明方法。新的方法的访问控制不能比抽象方法的访问控制更严格。新的实现方法的参数个数应该和抽象方法的参数个数一样,重新生成对应的类型提示。

1> 验证:新的实现方法的参数个数应该和抽象方法的参数个数一样

<?php

abstract class Animal{
//抽象类中可以定义属性
protected $animal = 'animal';
//抽象类中也可以定义非抽象方法
public function printit($name){
$this->animal = $name;
echo $this->animal;
}
//抽象方法
abstract public function setit();
} class Fish extends Animal{
public function setit($name){
echo $name;
}
}

运行代码:Fatal error: Declaration of Fish::setit() must be compatible with Animal::setit() in D:\phpStudy\WWW\demo\abstract.php on line 19

2> 验证:新的方法的访问控制不能比抽象方法的访问控制更严格

(1) 如果 Animal 中 setit() 声明为 public ,那么 Fish 中 setit() 的声明只能是 public ,不能是 protected 或 private ;
(2) 如果 Animal 中 setit() 声明为 protected ,那么 Fish 中 setit() 的声明可以是 public 或 protected ,但不能是 private ;
(3) 如果 Animal 中 setit() 声明为 private ,嘿嘿,不能定义为 private 哦!

<?php

abstract class Animal{
//抽象类中可以定义属性
protected $animal = 'animal';
//抽象类中也可以定义非抽象方法
public function printit($name){
$this->animal = $name;
echo $this->animal;
}
//抽象方法
abstract public function setit();
} class Fish extends Animal{
private function setit(){ }
}

运行结果:Fatal error: Access level to Fish::setit() must be public (as in class Animal) in D:\phpStudy\WWW\demo\abstract.php on line 19

5)、子类可以定义一个可选参数(也就是必须要有默认值),而父类抽象方法的声明里没有,则两者的声明并无冲突。

<?php

abstract class Animal{
//抽象类中可以定义属性
protected $animal = 'animal';
//抽象类中也可以定义非抽象方法
public function printit($name){
$this->animal = $name;
echo $this->animal;
}
//抽象方法
abstract public function setit($name);
} class Fish extends Animal{
public function setit($name,$separator = ''){ }
}

6)、一个抽象类继承另一个抽象类时,抽象方法不需要声明为抽象的

<?php

abstract class Animal{
//抽象类中可以定义属性
protected $animal = 'animal';
//抽象类中也可以定义非抽象方法
public function printit($name){
$this->animal = $name;
echo $this->animal;
}
//抽象方法
abstract public function setit();
}
//错误代码
abstract class Fish extends Animal{
abstract public function setit();
}
<?php

abstract class Animal{
//抽象类中可以定义属性
protected $animal = 'animal';
//抽象类中也可以定义非抽象方法
public function printit($name){
$this->animal = $name;
echo $this->animal;
}
//抽象方法
abstract public function setit();
}
//继承抽象类时,抽象方法不需要声明抽象
abstract class Fish extends Animal{ }

从PHP 5.2开始,不再允许同时使用abstract static 修饰一个抽象类的抽象方法。也就是说,PHP不再支持抽象静态方法,继续使用,将导致E_STRICT错误。

PHP面向对象程序设计之抽象类和抽象方法的更多相关文章

  1. Python基础(17)_面向对象程序设计(抽象类、继承原理、封装、多态,绑定方法)

    一.抽象类 抽象类是一个特殊的类,它的特殊之处在于只能被继承,不能被实例化 1.在python中实现抽象类 import abc #利用abc模块实现抽象类 class All_file(metacl ...

  2. PHP面向对象(抽象类与抽象方法、接口的实现)

    一.抽象类与抽象方法 1,任何一个类,如果它里面至少有一个方法是被声明为抽象的,那么这个类就必须被声明为抽象的. 2,定义为抽象的类不能被实例化. 3, 被定义为抽象的方法只是声明了其调用方式(参数) ...

  3. PHP面向对象之抽象类,抽象方法

    抽象类,抽象方法 抽象类: 是一个不能实例化的类: 定义形式: abstract  class  类名{} 为什么需要抽象类: 它是为了技术管理而设计! 抽象方法: 是一个只有方法头,没有方法体的方法 ...

  4. Java修炼——面向对象_抽象类和抽象方法

    抽象类和抽象方法 什么是抽象类? 使用 abstract 修饰的类称为抽象类 public abstract class Person { } 抽象类的特征 1) 抽象类不可以创建对象 2) 抽象类可 ...

  5. 实验二 Java面向对象程序设计

    实验二 Java面向对象程序设计 实验内容 1. 初步掌握单元测试和TDD 2. 理解并掌握面向对象三要素:封装.继承.多态 3. 初步掌握UML建模 4. 熟悉S.O.L.I.D原则 5. 了解设计 ...

  6. 20145221 《Java程序设计》实验报告二:Java面向对象程序设计

    20145221 <Java程序设计>实验报告二:Java面向对象程序设计 实验要求 初步掌握单元测试和TDD 理解并掌握面向对象三要素:封装.继承.多态 初步掌握UML建模 熟悉S.O. ...

  7. 201771010126 王燕《面向对象程序设计(java)》第十八周学习总结

    实验十八  总复习 实验时间 2018-12-30 1.实验目的与要求 (1) 综合掌握java基本程序结构: (2) 综合掌握java面向对象程序设计特点: (3) 综合掌握java GUI 程序设 ...

  8. 2018-2019-2 20175224 实验二《Java面向对象程序设计》实验报告

    一.实验报告封面 课程:Java程序设计 班级:1752班 姓名:艾星言 学号:20175224 指导教师:娄嘉鹏 实验日期:2019年4月17日 实验时间:13:45 - 15:25 实验序号:24 ...

  9. 2018-2019-2 20175227张雪莹《Java程序设计》 实验二《Java面向对象程序设计》

    2018-2019-2 20175227张雪莹<Java程序设计> 实验二<Java面向对象程序设计> 实验报告封面 课程:Java程序设计 班级:1752班 姓名:张雪莹 学 ...

随机推荐

  1. CFontDialog学习

    void CMfcFontDlgDlg::OnBtnFont() { // Show the font dialog with all the default settings. CFontDialo ...

  2. 【BZOJ4367】[IOI2014]holiday假期 分治+主席树

    [BZOJ4367][IOI2014]holiday假期 Description 健佳正在制定下个假期去台湾的游玩计划.在这个假期,健佳将会在城市之间奔波,并且参观这些城市的景点.在台湾共有n个城市, ...

  3. IntelliJ中的main函数和System.out.println()快捷输入方式

    转自:https://blog.csdn.net/assassinsshadow/article/details/73557375 main快捷输入 psvm System.out.println() ...

  4. mysql查询某周的起始日期和终止日期

    select subdate(curdate(),date_format(curdate(),'%w')-1) select subdate(curdate(),date_format(curdate ...

  5. 解决scipy安装(pip install scipy)失败,以及其他问题

    解决scipy安装(pip install scipy)失败,以及其他问题 解决: 1.在scipy官方库中并没有适合Windows的python3.6相关版本,故需要在网址http://www.lf ...

  6. FineReport----单元格元素(数据列、公式、斜线)

    一.绑定.插入数据列 数据集字段绑定 二.公式 1.单元 格计算 1.两个单元格(C7,I7)和 2.等于某单元格的值 D7等C7单元格的值 3.C7/8(除) 4.除数被除数为零.空的处理 http ...

  7. sql---字段类型转换,sql获取当前时间

    一.字段类型转换 convert(要转换成的数据类型,字段名称)例如 convert(varchar(100),col_name)Convert(int,Order_no) 二.sql获取当前时间 s ...

  8. FineReport---函数

    1.NUMTO()需要将数字2345转换成二三四五:NUMTO(2345) 2.Toimage函数:Toimage(path)用于在报表中显示某一路径path下的图片 3.row():为获取当前行号 ...

  9. Spoken English Practice(not always estimating your status in other's hearts. you will lose yourself when you live in other's look. do your best and walk on you own way.)

    绿色:连读:                  红色:略读:               蓝色:浊化:               橙色:弱读     下划线_为浊化 口语蜕变(2017/7/8) 英 ...

  10. 当集群为red或者yellow的时候怎么办

    百度Elasticsearch-产品描述-介绍-百度云 https://cloud.baidu.com/doc/BES/FAQ.html#.30.1B.42.A0.26.0A.6E.B7.F1.84. ...