PHP中抽象类与接口的区别

1.抽象类与接口的区别

在学习PHP面向对象时,都会在抽象类与接口上迷惑,作用差不多为什么还那么容易混淆,何不留一去一?但是事实上两者的区别还是很大的,如果能够很好地运用PHP的两个方法,面向对象的程序设计将会更加合理、清晰高效。

a.接口是通过 interface 关键字来定义的, 抽象类是通过abstract关键字来定义的。
b.对接口的使用方式是通过关键字implements来实现的,而对于抽象类的操作是使用类继承的关键字extends实现的,使用时要特别注意。
c.接口没有数据成员,但是抽象类有数据成员,抽象类可以实现数据的封装。
d.接口没有构造函数,抽象类可以有构造函数。
e.接口中的方法都是public类型,而抽象类中的方法可以使用private、protected或public来修饰。
f.一个类可以同时实现多个接口,但是只能实现一个抽象类。

相同点:抽象方法与接口的函数体内不能写任何东西,连两个大括号都不能写!!!如:function getName();这样就行了

2.接口

使用接口(interface),可以指定某个类必须实现哪些方法,但不需要定义这些方法的具体内容。

接口是通过 interface 关键字来定义的,就像定义一个标准的类一样,但其中定义所有的方法都是空的。

接口中定义的所有方法都必须是公有,这是接口的特性。

实现(implements)

要实现一个接口,使用 implements 操作符。类中必须实现接口中定义的所有方法,否则会报一个致命错误。类可以实现多个接口,用逗号来分隔多个接口的名称。

Note:
实现多个接口时,接口中的方法不能有重名。
Note:
接口也可以继承,通过使用 extends 操作符。
Note:
类要实现接口,必须使用和接口中所定义的方法完全一致的方式。否则会导致致命错误。

常量

接口中也可以定义常量。接口常量和类常量的使用完全相同,但是不能被子类或子接口所覆盖。

  1 <?php
  2
  3 // 声明一个‘iTemplate‘接口
  4 interface iTemplate
  5 {
  6     public function setVariable($name, $var);
  7     public function getHtml($template);
  8 }
  9
 10
 11 // 实现接口
 12 // 下面的写法是正确的
 13 class Template implements iTemplate
 14 {
 15     private $vars = array();
 16
 17     public function setVariable($name, $var)
 18     {
 19         $this->vars[$name] = $var;
 20     }
 21
 22     public function getHtml($template)
 23     {
 24         foreach($this->vars as $name => $value) {
 25             $template = str_replace(‘{‘ . $name . ‘}‘, $value, $template);
 26         }
 27
 28         return $template;
 29     }
 30 }
 31
 32 // 下面的写法是错误的,会报错,因为没有实现 getHtml():
 33 // Fatal error: Class BadTemplate contains 1 abstract methods
 34 // and must therefore be declared abstract (iTemplate::getHtml)
 35 class BadTemplate implements iTemplate
 36 {
 37     private $vars = array();
 38
 39     public function setVariable($name, $var)
 40     {
 41         $this->vars[$name] = $var;
 42     }
 43 }
 44 ?>
 45 Example #2 可扩充的接口
 46
 47 <?php
 48 interface a
 49 {
 50     public function foo();
 51 }
 52
 53 interface b extends a
 54 {
 55     public function baz(Baz $baz);
 56 }
 57
 58 // 正确写法
 59 class c implements b
 60 {
 61     public function foo()
 62     {
 63     }
 64
 65     public function baz(Baz $baz)
 66     {
 67     }
 68 }
 69
 70 // 错误写法会导致一个致命错误
 71 class d implements b
 72 {
 73     public function foo()
 74     {
 75     }
 76
 77     public function baz(Foo $foo)
 78     {
 79     }
 80 }
 81 ?>
 82 Example #3 继承多个接口
 83
 84 <?php
 85 interface a
 86 {
 87     public function foo();
 88 }
 89
 90 interface b
 91 {
 92     public function bar();
 93 }
 94
 95 interface c extends a, b
 96 {
 97     public function baz();
 98 }
 99
100 class d implements c
101 {
102     public function foo()
103     {
104     }
105
106     public function bar()
107     {
108     }
109
110     public function baz()
111     {
112     }
113 }
114 ?>
115 Example #4 使用接口常量
116
117 <?php
118 interface a
119 {
120     const b = ‘Interface constant‘;
121 }
122
123 // 输出接口常量
124 echo a::b;
125
126 // 错误写法,因为常量不能被覆盖。接口常量的概念和类常量是一样的。
127 class b implements a
128 {
129     const b = ‘Class constant‘;
130 }
131 ?>

http://php.net/manual/zh/language.oop5.interfaces.php

3.抽象类
PHP 5 支持抽象类和抽象方法。定义为抽象的类不能被实例化。任何一个类,如果它里面至少有一个方法是被声明为抽象的,那么这个类就必须被声明为抽象的。被定义为抽象的方法只是声明了其调用方式(参数),不能定义其具体的功能实现。

继承一个抽象类的时候,子类必须定义父类中的所有抽象方法;另外,这些方法的访问控制必须和父类中一样(或者更为宽松)。例如某个抽象方法被声明为受保护的,那么子类中实现的方法就应该声明为受保护的或者公有的,而不能定义为私有的。此外方法的调用方式必须匹配,即类型和所需参数数量必须一致。例如,子类定义了一个可选参数,而父类抽象方法的声明里没有,则两者的声明并无冲突。 这也适用于 PHP 5.4 起的构造函数。在 PHP 5.4 之前的构造函数声明可以不一样的。

 1 <?php
 2 abstract class AbstractClass
 3 {
 4  // 强制要求子类定义这些方法
 5     abstract protected function getValue();
 6     abstract protected function prefixValue($prefix);
 7
 8     // 普通方法(非抽象方法)
 9     public function printOut() {
10         print $this->getValue() . "\n";
11     }
12 }
13
14 class ConcreteClass1 extends AbstractClass
15 {
16     protected function getValue() {
17         return "ConcreteClass1";
18     }
19
20     public function prefixValue($prefix) {
21         return "{$prefix}ConcreteClass1";
22     }
23 }
24
25 class ConcreteClass2 extends AbstractClass
26 {
27     public function getValue() {
28         return "ConcreteClass2";
29     }
30
31     public function prefixValue($prefix) {
32         return "{$prefix}ConcreteClass2";
33     }
34 }
35
36 $class1 = new ConcreteClass1;
37 $class1->printOut();
38 echo $class1->prefixValue(‘FOO_‘) ."\n";
39
40 $class2 = new ConcreteClass2;
41 $class2->printOut();
42 echo $class2->prefixValue(‘FOO_‘) ."\n";
43 ?>
44 以上例程会输出:
45
46 ConcreteClass1
47 FOO_ConcreteClass1
48 ConcreteClass2
49 FOO_ConcreteClass2
50 Example #2 抽象类示例
51
52 <?php
53 abstract class AbstractClass
54 {
55     // 我们的抽象方法仅需要定义需要的参数
56     abstract protected function prefixName($name);
57
58 }
59
60 class ConcreteClass extends AbstractClass
61 {
62
63     // 我们的子类可以定义父类签名中不存在的可选参数
64     public function prefixName($name, $separator = ".") {
65         if ($name == "Pacman") {
66             $prefix = "Mr";
67         } elseif ($name == "Pacwoman") {
68             $prefix = "Mrs";
69         } else {
70             $prefix = "";
71         }
72         return "{$prefix}{$separator} {$name}";
73     }
74 }
75
76 $class = new ConcreteClass;
77 echo $class->prefixName("Pacman"), "\n";
78 echo $class->prefixName("Pacwoman"), "\n";
79 ?>
80 以上例程会输出:
81
82 Mr. Pacman
83 Mrs. Pacwoman
84 老代码中如果没有自定义类或函数被命名为“abstract”,则应该能不加修改地正常运行。

http://php.net/manual/zh/language.oop5.abstract.php

延伸阅读:
http://www.baidu.com/s?wd=php%20接口%20抽象类%20区别
http://www.sogou.com/web?query=php%20接口%20抽象类%20区别
https://www.so.com/s?q=php%20接口%20抽象类%20区别

http://www.baidu.com/s?wd=php%20抽象类%20实例化

抽象类:http://php.net/manual/zh/language.oop5.abstract.php
接口:http://php.net/manual/zh/language.oop5.interfaces.php

PHP高级——抽象类与接口的区别: http://www.cnblogs.com/picaso/archive/2012/10/05/2711865.html
php抽象类和接口: http://www.cnblogs.com/hylaz/archive/2012/11/11/2765397.html

时间: 2024-10-14 08:07:48

PHP中抽象类与接口的区别的相关文章

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

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

java中抽象类与接口的区别

转自: http://blog.csdn.net/tp7309/article/details/10452445 二者的区别快忘得差不多了,从别处看到这文章感觉写的不错,正好复习复习,也给大家分享一下. 抽象类 abstract class 包含抽象方法的类,叫抽象类.而抽象的概念就是抽象出共同属性:成员变量和方法.所以抽象类可以有private等多种权限的成员变量和非abstract的成员方法.当然抽象方法是一定要有的. 抽象类是用于单一继承的,不能实例化.而继承类一定要实现抽象方法,因为抽象

C#中抽象类和接口的区别

原文:C#中抽象类和接口的区别 大家在编程时都容易把抽象类和接口搞混,下面为大家从概念上讲解抽象类和接口的区别: 一.抽象类: 含有abstract修饰符的class即为抽象类,抽象类是特殊的类,只是不能被实例化,可以创建一个变量,其类型是一个抽象类,并让它指向具体子类的一个实例:除此以外,具有类的其他特性:重要的是抽象类可以包括抽象方法,这是普通类所不能的.抽象方法只能声明于抽象类中,且不包含任何实现,派生类必须覆盖它们.另外,抽象类可以派生自一个抽象类,可以覆盖基类的抽象方法也可以不覆盖.

C#中抽象类和接口的区别与使用

一.抽象类: 抽象类是特殊的类,只是不能被实例化:除此以外,具有类的其他特性:重要的是抽象类可以包括抽象方法,这是普通类所不能的.抽象方法只能声明于抽象类中,且不包含任何实现,派生类必须覆盖它们.另外,抽象类可以派生自一个抽象类,可以覆盖基类的抽象方法也可以不覆盖,如果不覆盖,则其派生类必须覆盖它们. 二.接口: 接口是引用类型的,类似于类,和抽象类的相似之处有三点: 1.不能实例化: 2.包含未实现的方法声明: 3.派生类必须实现未实现的方法,抽象类是抽象方法,接口则是所有成员(不仅是方法包括

Java中抽象类和接口的区别(读书笔记)

Java的抽象类和接口 抽象类和接口是两个容易混淆的概念,但有一句话能很好地将这两者区分开来,即抽象类是事物的抽象,而接口是行为的抽象.抽象类抽象出来的是一类事物,事物中包含了一些固有的属性和行为,而接口更多的是提供固有属性行为之外的延伸行为.打个比方,可以把动物看成为抽象类,类中有一些固有属性,如身高体重,还有一些共有行为,如吃饭和睡觉,所有的动物都遵循着这些属性和行为.除此之外,有些动物还能飞,但并不是所有的动物都具有飞行这种能力,此时飞行只是事物的延伸功能,相当于一个接口. 一.抽象类 抽

C#中抽象类与接口的区别

1.面向接口编程和面向对象编程是什么关系 首先,面向接口编程和面向对象编程并不是平级的,它并不是比面向对象编程更先进的一种独立的编程思想,而是附属于面向对象思想体系,属于其一部分.或者说,它是面向对象编程体系中的思想精髓之一. 2.接口的本质 接口,在表面上是由几个没有主体代码的方法定义组成的集合体,有唯一的名称,可以被类或其他接口所实现(或者也可以说继承).它在形式上可能是如下的样子: interface InterfaceName{    void Method1();    void Me

面向对象设计中抽象类与接口的区别

在OOD(面向对象设计)中,经常会用到抽象类或接口,[注:在C++中,没有接口的概念,只有抽象类:而在Java中两者都存在].而在使用过程中,也许会有不少人认为接口和抽象类差不多,然后就想当然地觉得可以相互完全替换.事实上,虽然他们有很多相似点,但也有很大差异. 1.抽象类与接口的出现条件 在面向对象的概念中,我们知道所有的对象都是通过类来描绘的,但是反过来却不是这样.并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类.抽象类往往用来表征我们

Java中抽象类和接口的区别(abstract class VS interface)

前言:本文解决的问题 什么是抽象类 抽象类的应用场景 接口可以有方法实现吗 接口和抽象类的区别 1 什么是抽象类 在声明时含有关键字abstract就是抽象类,抽象类它可以看作具体类的一个模板,继承它的子类可以从抽象类中共享一些方法(可能是不完整的)和属性. A class which is declared with the abstract keyword is known as an abstract class in Java. It can have abstract and non-

详细解析Java中抽象类和接口的区别

在Java语言中, abstract class 和interface 是支持抽象类定义的两种机制.正是由于这两种机制的存在,才赋予了Java强大的 面向对象能力.abstract class和interface之间在对于抽象类定义的支持方面具有很大的相似性,甚至可以相互替换,因此很多开发者在进行抽象类定义时对于abstract class和interface的选择显得比较随意. 其实,两者之间还是有很大的区别的,对于它们的选择甚至反映出对于问题领域本质的理解.对于设计意图的理解是否正确.合理.