相同点:
1,抽象类和接口本身都不能实例化
2,都可以指定某个类必须实现哪些方法,而不需要定义这些方法的具体内容
3,可扩展性:抽象类和接口都可以通过继承(extends)实现扩展
不同点:
抽象类:
1,抽象类可以拥有成员属性
abstract class Foo
{
public $name = 'Mike';
}
abstract class Foo
{
//抽象方法,子类必须实现此方法
abstract public function say();
//普通方法,子类可以直接使用此方法
public function hello(){
echo 'hello world';
}
}
3,可扩展,即一个抽象类可以继承另一个抽象类,但是只能单继承,不能继承多个
4,一个子类只能继承一个抽象类
abstract class Foo1
{
abstract public function hello();
}
//抽象类Foo2继承自Foo1
abstract class Foo2 extends Foo1
{
abstract public function word();
}
//MyClass继承抽象类Foo2,因为Foo2继承自Foo1,所以MyClass必须实现hello()方法和word()方法
class MyClass extends Foo2
{
public function hello()
{
//something
}
public function word()
{
// something
}
}
abstract class Foo1
{
abstract public function hello1();
}
abstract class Foo2
{
abstract public function hello2();
}
class MyClass extends Foo1
{
//子类必须实现父类中的所有抽象方法
public function hello1();
}
class ErrorClass extends Foo1,Foo2
{
//错误,一个子类只能继承一个父类,无法多继承
}
接口:
1,接口不能定义成员属性,只能定义接口常量
interface Foo
{
//定义接口常量
const NAME = 'Mike';
//错误,无法在接口中定义成员属性
public $name = 'Mike';
}
2,不能在接口内部定义具体的成员方法
interface Foo
{
public function hello(); //正确
//错误,接口中不能实现具体的成员方法
public function sayHello(){
echo 'hello world';
}
}
3,可扩展,即一个接口可以继承另一个或者多个接口,即可以多继承
//接口1
interface Foo1
{
public function foo1();
}
//接口2
interface Foo2
{
public function foo2();
}
//接口3,继承接口1和接口2
interface foo extends Foo1,Foo2
{
public function say();
}
4,一个类可以实现(implements)多个接口
//定义一个类,实现接口1和接口2
class MyClass implements Foo1,Foo2
{
public function foo1(){
//something
}
public function foo2(){
//something
}
}