【PHP面试题01】抽象类、接口 的区别和使用场景

文章目录


一、抽象类和接口的区别

本文已收录于PHP全栈系列专栏:PHP面试专区。-
计划将全覆盖PHP开发领域所有的面试题,对标资深工程师/架构师序列,欢迎大家提前关注锁定。

抽象类和接口基本上是面试必问的一个问题,因为用的实在是太普遍了,用好抽象类和接口是开发者必备的技能。但是真正用好二者确实不太容易。抽象类和接口是面向对象编程中的两个核心概念,它们旨在帮助开发者更好地组织和管理代码,并提高代码的可维护性和可扩展性。在本文中,我们将详细介绍抽象类和接口的区别和使用场景,并通过PHP语言给出代码演示。

1.1 定义方式不同

抽象类是使用关键字abstract来定义的,而接口是使用关键字interface来定义的。

1.2.成员方法不同

抽象类可以包含普通方法和抽象方法,而接口只能包含抽象方法。

1.3 实现方式不同

抽象类可以被继承,子类可以继承父类的属性和方法,并且必须实现父类中的抽象方法。而接口则不能被继承,它只能被实现,实现了接口的类必须实现接口中所有的抽象方法。

1.4 构造方法不同

抽象类可以包含构造方法,而接口不可以。

1.5 访问修饰符不同

抽象类中的成员方法可以包含public、protected和private三种访问修饰符,而接口中的成员方法只能包含public访问修饰符。

1.6 关注点不同

抽象类强调“是不是”,主要用于定义一些基础类,而接口强调“能否”,主要用于定义一些可替换的类或行为。

在这里插入图片描述

二、抽象类和接口的使用场景

2.1 抽象类的使用场景

抽象类通常用于定义一些基础类,它们的主要作用是为派生类提供公共的基础方法和属性。抽象类可以包含普通方法和抽象方法,其中普通方法可以提供默认实现,而抽象方法则需要子类去实现。除此之外,抽象类还可以包含protected和private成员变量和方法,以及构造方法。下面是一个用抽象类定义的基础类的例子:

abstract class Shape{
    protected $color;
    
    public function setColor($color){
        $this->color = $color;
    }
    
    abstract public function getArea();
}

class Circle extends Shape{
    protected $radius;
    
    public function __construct($radius){
        $this->radius = $radius;
    }
    
    public function getArea(){
        return pi()*pow($this->radius,2);
    }
}

class Rectangle extends Shape{
    protected $width;
    protected $height;
    
    public function __construct($width,$height){
        $this->width = $width;
        $this->height = $height;
    }
    
    public function getArea(){
        return $this->width*$this->height;
    }
}

在上面的例子中,我们用抽象类Shape定义了一个基础图形类,其中包含了protected属性$color和abstract方法getArea()。然后我们用Circle和Rectangle来继承Shape,并实现了getArea()方法。

2.2 接口的使用场景

接口通常用于定义一些行为规范,它们的主要作用是约束各个实现类的行为,从而提高程序的可扩展性和可替换性。接口只包含抽象方法,没有属性和方法的实现。下面是一个用接口定义的日志记录器的例子:

interface Logger{
    public function log($msg);
}

class FileLogger implements Logger{
    public function log($msg){
        //将日志写入文件
    }
}

class DatabaseLogger implements Logger{
    public function log($msg){
        //将日志写入数据库
    }
}

在上面的例子中,我们用接口Logger定义了一个日志记录器的规范,其中只包含一个抽象方法log()。然后我们用FileLogger和DatabaseLogger来实现Logger,并实现了log()方法。

三、PHP代码演示

下面是一个通过抽象类Shape和接口Logger来实现一个图形绘制和日志记录的例子:

abstract class Shape{
    protected $color;
    
    public function setColor($color){
        $this->color = $color;
    }
    
    abstract public function getArea();
}

interface Logger{
    public function log($msg);
}

class Circle extends Shape{
    protected $radius;
    
    public function __construct($radius){
        $this->radius = $radius;
    }
    
    public function getArea(){
        return pi()*pow($this->radius,2);
    }
}

class Rectangle extends Shape{
    protected $width;
    protected $height;
    
    public function __construct($width,$height){
        $this->width = $width;
        $this->height = $height;
    }
    
    public function getArea(){
        return $this->width*$this->height;
    }
}

class Canvas{
    private $shapes = [];
    
    public function addShape(Shape $shape){
        $this->shapes[] = $shape;
    }
    
    public function draw(Logger $logger){
        foreach($this->shapes as $shape){
            $area = $shape->getArea();
            $logger->log("The area of shape is ".$area);
        }
    }
}

class FileLogger implements Logger{
    
    private $filename;
    
    public function __construct($filename){
        $this->filename = $filename;
    }
    
    public function log($msg){
        file_put_contents($this->filename,$msg."\n",FILE_APPEND);
    }
}

$circle = new Circle(5);
$circle->setColor('red');

$rectangle = new Rectangle(10,20);
$rectangle->setColor('blue');

$canvas = new Canvas();
$canvas->addShape($circle);
$canvas->addShape($rectangle);

$logger = new FileLogger('log.txt');

$canvas->draw($logger);

在上面的例子中,我们定义了一个抽象类Shape和一个接口Logger,并用Circle和Rectangle来继承Shape,FileLogger来实现Logger。然后我们通过Canvas类来实现图形绘制,并且记录日志。在最后,我们创建了一个FileLogger对象来将日志写入到文件中。

总结

通过以上的例子,我们可以看出抽象类和接口在代码中的作用和使用场景。抽象类用于定义一些基础类,而接口用于定义一些行为规范。它们都是为了让代码更加模块化、可维护和可扩展。因此,在实际开发中,我们应该根据业务需求合理地使用抽象类和接口,以提高代码质量和可维护性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值