PHP的抽象类和接口

抽象类与接口相似,都是一种比较特殊的类。抽象类是一种特殊的类,而接口也是一种特殊的抽象类。它们通常配合面向对象的多态性一起使用。虽然声明和使用都比较容易,但它们的作用在理解上会困难一点。

①抽象类

在OOP语言中,一个类可以有一个或多个子类,而每个类都有至少一个公有方法作为外部代码访问它的接口。而抽象方法就是为了方便继承而引入的。本节中先来介绍一下抽象类和抽象方法的声明,然后再说明其用途。在声明抽象类之前,我们先了解一下什么是抽象方法。抽象方法就是没有方法体的方法,所谓没有方法体是指在方法声明时没有花括号及其中的内容,而是在声明方法时直接在方法名后加上分号结束。另外在声明抽象方法时,还要使用关键字abstract来修饰。声明抽象方法的格式如下所示:

abstract function fun1(); //不能有花括号,就更不能有方法体中的内容了
abstract function fun2(); //直接在方法名的括号后面加上分号结束,还要使用abstract修饰

只要在声明类时有一个方法时抽象方法,那么这个类就是抽象类,抽象类也要使用abstract关键字来修饰。在抽象类中可以有不是抽象的成员方法和成员属性,但访问权限不能使用private关键字修饰为私有的。下面的例子在Person类中声明了两个抽象方法say()和eat(),则Person类就是一个抽象类,需要使用abstract标识。代码如下所示:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

<?php

    abstract class Person{

        protected $name;

        protected $country;

        function __construct($name="",$country="china"){

            $this ->name = $name;

            $this ->country = $country;

        }

        abstract function say();

        abstract function eat();

        function run(){

            echo "使用两条腿走路<br>";

        }

    }

?>

在上例中声明了一个抽象类Person,在这个类中定义了两个成员属性、一个构造方法和两个抽象方法,还有一个是非抽象的方法。抽象类就像是一个“半成品”的类,在抽象类中有没有被实现的抽象方法,所以抽象类是不能被实例化的,即创建不了对象,也就不能直接使用它。既然抽象类是一个“半成品”的类,那么使用抽象类有什么作用呢?使用抽象类就包含了继承关系,它是为它的子类定义公共接口,将它的操作(可能是部分,也可能是全部)交给子类去实现。就是将抽象类作为子类重载的模板使用,定义抽象类就相当于定义了一种规范,这种规范要求子类去遵守。当子类继承抽象类以后,就必须把抽象类中的抽象方法按照子类自己的需要去实现。子类必须把父类中的抽象方法全部都实现,否则子类中还存在抽象方法,所以还是抽象类,也不能实例化对象。在下例中声明了两个类,分别实现上例中声明的抽象类Person。代码如下所示:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

<?php

    class ChineseMan extends Person{

        function say(){

            echo $this ->name."是".$this->country."人,讲汉语<br>";   

        }

        function eat(){

            echo $this ->name."使用筷子吃饭<br>";

        }

    }

        class Americans extends Person{

        function say(){

            echo $this ->name."是".$this->country."人,讲英语<br>";   

        }

        function eat(){

            echo $this ->name."使用刀子和叉子吃饭<br>";

        }

    }

    $chianeseMan = new ChineseMan("高洛峰""中国");

    $americans = new Americans ("alex","美国");

    $chineseMan ->say();

    $chineseMan ->eat();

    $americans ->say();

    $americans ->eat();

?>

在上例中声明了两个类去继承抽象类Person,并将Person类中的抽象方法按各自的需求分别实现,这样两个子类就都可以创建对象了。抽象类Person就可以看成是一个模板,类中的抽象方法自己不去实现,只是规范了子类中必须要有父类中声明的抽象方法,而且要按照自己的特点实现抽象方法的内容。

②接口技术

因为PHP只支持单继承,也就是说每个类只能继承一个父类。当声明的新类继承抽象类实现模板以后,它就不能再有其他父类了。为了解决这个问题,PHP引入了接口。接口是一种特殊的抽象类,而抽象类又是一种特殊的类。如果抽象类中的所有方法都是抽象方法,我们就可以换另外一种声明方式,使用“接口”技术。接口中声明的方法必须都是抽象方法,另外不能再接口中声明变量,只能使用const关键字声明为常量的成员属性,而且接口中所有成员都必须有public的访问权限。类的声明是使用“class”关键字标识的,而接口的声明则是使用“interface”关键字标识的。声明接口的格式如下所示:


1

2

3

4

5

6

<?php

interface 接口名称{ //使用interface关键字声明接口

常量成员 //接口中的成员属性只能是常量,不能是变量

抽象方法 //接口中的所有方法必须是抽象方法,不能有非抽象的方法存在

}

?>

接口中的所有方法都要求是抽象方法,所以就不需要在方法前使用abstract关键字标识了。而且在接口中也不需要显式地使用public访问权限进行修饰,因为默认权限就是public的,也只能是公有的。另外接口和抽象类一样也不能实例化对象,它是一种更严格的规范,也需要通过子类来实现。但可以直接使用接口名称在接口外面去获取常量成员的值。一个接口的声明例子,代码如下所示:


1

2

3

4

5

6

7

<?php

interface one{

const CONSTANT = ‘CONSTANT value‘;

function fun1();

function fun2();

}

?>

也可以使用extends关键字让一个接口去继承另一个接口,实现接口之间的扩展。在下面的例子中声明一个Two接口继承了上例中的One接口。代码如下所示:


1

2

3

4

5

6

<?php

interface Two extends one{

function fun3();

function fun4();

}

?>

如果需要使用接口中的成员,则需要通过子类去实现接口中的全部抽象方法,然后创建子类的对象去调用在子类中实现后的方法。但通过类去继承接口时需要使用implements关键字来实现,而并不是使用extends关键字完成。如果需要使用抽象类去实现接口中的部分方法,也需要使用implements关键字实现。在下面的例子中声明一个抽象类Three去实现One接口中的部分方法,但要想实例化对象,这个抽象类还需要有子类把它所有的抽象方法都实现才行。声明一个Four类去实现One接口中全部方法。代码如下所示:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

<?php

interface one{

const CONSTANT = ‘CONSTANT value‘;

function fun1();

function fun2();

}

//声明一个抽象类去实现接口One中的第二个方法

abstract class Three implements One{ //只实现接口中的一个抽象方法

function fun2(){

//具体的实现内容由子类自己决定

}

}

//声明一个类实现接口One中的全部抽象方法

class Four implements One{

function fun1(){

//具体的实现内容由子类自己决定

}

function fun2(){

//具体的实现内容由子类自己决定

}

}

?>

PHP是单继承的,一个类只能有一个父类,但是一个类可以实现多个接口。将要实现的多个接口之间使用逗号分隔开,而且在子类中药将所有接口中的抽象方法全部实现才可以创建对象。就相当于一个类要遵守多个规范,就像我们不仅要遵守国家的法律,如果是在学校,还需要遵守学校的校规一样。实现多个接口的格式如下所示:

class 类名 implements 接口一,接口二,……接口n{
实现所有接口中的抽象方法
}

实现多个接口是使用“implements”关键字,同时还可以使用“extends”关键字继承一个类。即在继承类的同时实现多个接口,但一定更要先使用extends继承一个类,再去使用inplements实现多个接口。使用格式如下所示:

class 类名 extends 父类名 implements 接口一,接口二,……接口n{
实现所有接口中的抽象方法
}

除了上述的一些应用外,还有很多地方可以使用使用接口,例如对于一些已经开发好的系统,在结构上进行较大的调整已经不太现实,这时可以通过自定义一些接口并追加相应的实现来完成功能结构的扩展。

>> 本文固定链接: http://php.ncong.com/php_course/oop/abstract.html

>> 转载请注明: 恩聪php 2014年07月25日 于 恩聪PHP学习教程 发表

PHP的抽象类和接口

时间: 2024-09-29 22:15:14

PHP的抽象类和接口的相关文章

2.35 Java基础总结①抽象②接口③设计抽象类和接口的原则④接口和抽象类的区别

java基础总结①抽象②接口③设计抽象类和接口的原则④接口和抽象类的区别 一.抽象 abstract作用:不能产生对象,充当父类,强制子类正确实现重写方法和类相比仅有的改变是不能产生对象,其他的都有,包括构造.属性等等任何一个类只要有一个抽象的方法就成了抽象类 抽象方法 public abstract A();①方法是抽象的,这个类也是抽象的:②子类必须重写抽象方法,除非子类也是抽象类 抽象类可以没有抽象方法,但一般不这么设计 二.接口 interface 接口也是Java的一种引用数据类型(J

抽象类和接口的区别

含有abstract修饰符的class即为抽象类,abstract 类不能创建的实例对象.含有abstract方法的类必须定义为abstract class,abstract class类中的方法不必是抽象的.abstract class类中定义抽象方法必须在具体(Concrete)子类中实现,所以,不能有抽象构造方法或抽象静态方法.如果的子类没有实现抽象父类中的所有抽象方法,那么子类也必须定义为abstract类型. 接口(interface)可以说成是抽象类的一种特例,接口中的所有方法都必须

Java抽象类与接口的区别

很多常见的面试题都会出诸如抽象类和接口有什么区别,什么情况下会使用抽象类和什么情况你会使用接口这样的问题.本文我们将仔细讨论这些话题. 在讨论它们之间的不同点之前,我们先看看抽象类.接口各自的特性. 抽象类 抽象类是用来捕捉子类的通用特性的 .它不能被实例化,只能被用作子类的超类.抽象类是被用来创建继承层级里子类的模板.以JDK中的GenericServlet为例: public abstract class GenericServlet implements Servlet, ServletC

【翻译】JAVA中抽象类和接口的区别

不知道有没有人翻译过了,这篇是挺简单的,权当复习一遍内容吧. 很多常见的面试问题如"抽象类和接口有什么区别","你在什么时候用抽象类什么时候用接口".所以在这篇文章里面,我们会讨论一下这个话题. 在开始讨论它们的区别之前,我们先看看它们的介绍. Abstract class 抽象类 抽象类被用来抽象出子类的共同特征.它是不能被实例化的,它只能被子类继承作为超类使用.抽象类被用作它的子类下的层次结构创建模板(Abstract classes are used to c

Java重载、覆写、this、super、抽象类、接口

第一.重载和覆写 1) 重载:方法名相同,参数类型和个数不同,典型的是构造方法的重载  覆写:方法名.参数类型.返回值类型全部相同,典型的是接口的实现: 2)重载对权限没有要求:覆写要求  被覆写的方法不能拥有更严格的权限: 3)重载发生再一个类中:覆写发生在继承类中. 第二.this和super 1)this访问本类中的属性(方法),如果本类中没有此属性(方法),则从父类中 继续寻找:super询问父类中的属性(方法): 2)调用本类构造,必须放在构造方法的首行:调用父类构造,必须放在子类构造

关于抽象类和接口

抽象类:含有abstract修饰符的类即为抽象类,它是不能创建实例对象的,含有abstract的方法必须定义在抽象类中,但抽象类中的方法不一定必须是抽象的,抽象类中的抽象方法再其子类中必须被实现,所以不能有抽象的静态方法(静态方法是不能被继承的). 接口:是一个特殊的抽象类,接口中定义的方法都必须是抽象的,接口中的方法都是public abstract类型,接口中的成员变量默认为public abstract final类型. 语法区别:① 抽象类中可以拥有普通的成员变量,接口中没有. ②抽象类

抽象类与接口

接口和内部类为我们提供了一种将接口与实现分离的更加结构化的方法. 抽象类与接口是java语言中对抽象概念进行定义的两种机制,正是由于他们的存在才赋予java强大的面向对象的能力.他们两者之间对抽象概念的支持有很大的相似,甚至可以互换,但是也有区别. 一.抽象类 我们都知道在面向对象的领域一切都是对象,同时所有的对象都是通过类来描述的,但是并不是所有的类都是来描述对象的.如果一个类没有足够的信息来描述一个具体的对象,而需要其他具体的类来支撑它,那么这样的类我们称它为抽象类.比如new Animal

关于抽象类和接口一些简单的概念

做一下笔记: 1.抽象类可以有构造方法,接口中不能有构造方法.  2.抽象类中可以有普通成员变量,接口中没有普通成员变量  3.抽象类中可以包含非抽象的普通方法,接口中的所有方法必须都是抽象的,不能有非抽象的普通方法.  4. 抽象类中的抽象方法的访问类型可以是public,protected和(默认类型,虽然  eclipse下不报错,但应该也不行),但接口中的抽象方法只能是public类型的,并且默认即为public abstract类型.  5. 抽象类中可以包含静态方法,接口中不能包含静

三、抽象类和接口的对比-----《大话设计模式》

一.抽象类 c#允许把类和方法声明为abstract,即抽象类和抽象方法.抽象类不能实例化,抽象方法必须被子类重写,如果类中包含抽象方法,那么类就必须定义为抽象类,不论是否还包含其他一般方法. 抽象类拥有尽可能多的共同代码,尽可能少的数据. abstract class Animal //加abstract关键字,表明是抽象类 { -- protected abstract string getShoutSound(); //在方法返回值前加abstract表明此方法是抽象方法. -- //抽象

oop_day06_抽象类、接口_20150814

oop_day06_抽象类.接口_20150814 1.static final常量: 1)必须声明同时初始化,不能修改,类名点来访问 2)常量名建议所有字母都大写 3)编译器编译时会直接替换为具体的值---效率高 代码示例: package oo.day06; //static final常量 public class StaticFinalDemo { public static void main(String[] args) { //Aoo.NUM = 250; //编译错误,常量不能修