面向对象(五)抽象类与接口

抽象类是一种特殊的类,而接口是一种特殊的抽象类。他们通常配合面向对象的多态性一起使用

一、抽象类

1、抽象方法就是没有方法体的方法,是为了方便继承而引入的。不能使用private修饰为私有的

2、只要在声明类时有一个方法是抽象方法,那么这个类就是抽象类,抽象类也要使用abstract关键字修饰。抽象类中可以有不是抽象的成员方法。

3、由于抽象类中有没有被实现的抽象方法,所以抽象类是不能被实例化的,即创建不了对象,也就不能直接使用它。那使用抽象类有什么作用呢?

使用抽象类就包含了继承关系,它是为它的子类定义公共接口,将它的操作交给子类去实现。就是将抽象类作为子类重载的模板使用,定义抽象类就相当于定义了一种规范,这种规范要求子类去遵守。当子类继承抽象类之后,就必须把抽象类中的抽象方法按照子类自己的需要去实现。子类必须把父类中的抽象方法全部实现,否则子类中还存在抽象方法,所以还是抽象类,不能实例化对象

<?php
abstract class AbstractClass
{
 // 强制要求子类定义这些方法
    abstract protected function getValue();
    abstract protected function prefixValue($prefix);

    // 普通方法(非抽象方法)
    public function printOut() {
        print $this->getValue() . "\n";
    }
}

class ConcreteClass1 extends AbstractClass
{
    protected function getValue() {
        return "ConcreteClass1";
    }

    public function prefixValue($prefix) {
        return "{$prefix}ConcreteClass1";
    }
}


$class1 = new ConcreteClass1;
$class1->printOut();
echo $class1->prefixValue('FOO_') ."\n";
/*
ConcreteClass1
FOO_ConcreteClass1
*/

4、子类定义了一个可选参数,而父类抽象方法的声明里没有,则两者的声明并无冲突。

abstract class AbstractClass
{
    // 我们的抽象方法仅需要定义需要的参数
    abstract protected function prefixName($name);

}

class ConcreteClass extends AbstractClass
{

    // 我们的子类可以定义父类签名中不存在的可选参数
    public function prefixName($name, $separator = ".") {
        if ($name == "Pacman") {
            $prefix = "Mr";
        } elseif ($name == "Pacwoman") {
            $prefix = "Mrs";
        } else {
            $prefix = "";
        }
        return "{$prefix}{$separator} {$name}";
    }
}

$class = new ConcreteClass;
echo $class->prefixName("Pacman"), "\n";
echo $class->prefixName("Pacwoman"), "\n";

猜你喜欢

转载自blog.csdn.net/hrbsfdxzhq01/article/details/88928081