关于抽象类和接口的初步理解

关于抽象类和接口的初步理解

什么是抽象类

  1. 抽象类是指在 class 前加了 abstract 关键字且存在抽象方法(在类方法 function 关键字前加了 abstract 关键字)的类。php

  2. 抽象类不能被直接实例化。抽象类中只定义(或部分实现)子类须要的方法。子类能够经过继承抽象类并经过实现抽象类中的全部抽象方法,使抽象类具体化。编程

  3. 若是子类须要实例化,前提是它实现了抽象类中的全部抽象方法。若是子类没有所有实现抽象类中的全部抽象方法,那么该子类也是一个抽象类,必须在 class 前面加上 abstract 关键字,而且不能被实例化。
    引用连接函数

  1. 接口(Interface)—— 定义行为this

  2. 抽象类(Abstract Class) —— 实现行为.net

  3. 具体类(class)——执行行为
    引用连接设计

  1. 抽象类就是一个类的服务提供商,拥有众多服务,你不用必须用,当须要的时候你来用就能够,若是你以为不提供服务不满意,你还能够本身来作。code

  2. 抽象方法是必须实现的方法。就象动物都要呼吸。可是鱼用鳃呼吸,猪用肺呼吸。
    动物类要有呼吸方法。怎么呼吸就是子类的事了。对象

引用连接blog

为何要使用抽象类

按照我目前的知识理解:继承

  1. 保持程序的一致性

  2. 抽象类限制了实现的方法,也是为了保持一致性

  3. 增长代码重用性,例如一些公共类不须要实现,只须要调用里面的方法就能够了。

  4. 如今有不少讨论和建议提倡用interface代替abstract类,二者从理论上能够作通常性的混用,可是在实际应用中,他们仍是有必定区别的。抽象类通常做为公共的父类为子类的扩展提供基础,这里的扩展包括了属性上和行为上的。而接口通常来讲不考虑属性,只考虑方法,使得子类能够自由的填补或者扩展接口所定义的方法,就像JAVA王子所说的事件中的适配器就是一个很好的应用。

用一个简单的例子,好比说一个教师,咱们把它做为一个抽象类,有本身的属性,好比说年龄,教育程度,教师编号等等,而教师也是分不少种类的,咱们就能够继承教师类而扩展特有的种类属性,而广泛属性已经直接继承了下来。

而接口呢~仍是拿教师作例子,教师的行为不少,除了和普通人相同的之外,还有职业相关的行为,好比改考卷,讲课等等,咱们把这些行为定义成无body的方 法,做为一个集合,它是一个interface。而教师张三李四的各自行为特色又有不一样,那么他们就能够扩展本身的行为body。从这点意义上来讲,interface偏重于行为。

引用连接

怎样使用抽象类

<?php
    abstract class  Shape{  //这是一个抽象类,不能实例化
        protected  $color;  //抽象类里面通常都是使用protected来保护属性,这是封装的意义
        
        public function __construct($color = 'red') {   //抽象类可使用构造方法,主要是为了方便代码重用,构造方法里面也可使用默认参数,当没有配置参数的时候,就会使用默认的参数,写法如上
            $this->color = $color;
        }
        
        public function getColor() {  //只是为了演示须要的一个方法
            return $this->color;
        }
        
        abstract public function getArea();  //构造方法是为了限制代码,对于继承这个构造类的子类,必须限制拥有这个构造方法,主要为了保持代码一致性。
    }
    
    class Square extends Shape{
        protected  $length = 4;
        public function getArea() {
            return pow($this->$length, 2);
        }
    }
    
    class Circle extends Shape{ //这里由于没有构造方法getArea,因此代码容许会报错的。
        
    }
    
    $shape = new Square();
    var_dump($shape);
?>

接口和抽象类

  1. 抽象类不能被直接实例化,抽象类中只定义子类须要的方法,子类能够继承而且经过实现其中的抽象方法,使抽象类具体化。例如一个名为media的类,他是用于描述各类公开出版的共同性质,由于media不表示真实的实体,而是一些类似实体的泛化表示,因此不实例化,这样就须要声明为抽象类,而后再由各类的派生的Media类继承此抽象类

  2. 抽象类的每一个子类都必须实现抽象类中的全部抽象方法,或者把他们自身也声明为抽象方法。

  3. 扩展类不只仅负责简单实现抽象类的方法,还必须从新声明方法,新的方法不能比抽象方法的访问控制更严格,新的实现方法的参数个数应该和抽象方法的参数个数同样。

  4. 接口定义了实现某种服务的通常规范,声明了必须的函数和常量,可是不指定如何实现。关键是要创建必须实现的一组通常原则,只有知足了这些原则才能说实现了这个接口。

  5. 抽象类提供了具体实现的标准,而接口则是纯粹的模板。接口只能定义功能而不包含实现的内容。

  6. 任何实现接口的类都要实现接口中所定义的全部方法,不然类必须声明为abstract。

  7. 实现接口的类接受他的继承的类以及实现的接口的类型。

何时用接口,何时用抽象类

  • 若是要建立一个模型,这个模型将由一些紧密相关的对象引用,就能够采用抽象类,若是要建立将由一些不想关的对象采用的功能,应该用接口。

  • 若是必须从多个来源继承行为,就是用接口。

  • 若是知道全部类都会共享一个公共的行为实现,就使用抽象类,并在其中实现行为。接口没法实现。

  • 一个类只能extends一个父类,但能够贯彻多个接口。

接口做用一:

接口类就是一个类的领导者,指明方向,子类必须完成它指定方法。

当有不少人一块儿开发一个项目时,可能都会去调用别人写的一些类,那你就会问,我怎么知道他的某个功能的实现方法是怎么命名的呢,这个时候php接口类就起到做用了,当咱们定义了一个接口类时,它里面的方式是下面的子类必须实现的,好比

interface Shop
{
public function buy($gid);
public function sell($gid);
public function view($gid);
}
class BaseShop implements Shop
{
    public function buy($gid)
    {
        echo '你购买了ID为 :' . $gid . '的商品';
    }

    public function sell($gid)
    {
        echo '你购卖ID为 :' . $gid . '的商品';
    }

    public function view($gid)
    {
        echo '你浏览了ID为 :' . $gid . '的商品';
    }
}

接口做用二:

有时候,咱们须要设计一个物品,好比shape,这个shape有不一样的形状,有不一样的颜色,可做不一样的运动,等等。固然咱们能够把这些都放在一个类里面,但这样,如前面说的,只是过程编程,不是OO编程。你会说,像上面例子同样,作一个抽象类,而后在子类里实现全部的功能。好象不错,进步了。这样子类里面要实现形状,颜色,运动等功能,OK吗?记住,OO里面还有一条原则,为了最大程度的作到代码重用,一个类里最好只实现一个功能,也就是说,一个类作形状,一个类作颜色,一个类作运动 。这样若是其余的类要用到颜色的功能时,咱们就能够重用这个颜色类,同理,这样咱们能够很容易的重用运动类,形状类,等等。

但这样问题出来了,如今咱们要用到上面全部的功能,但又分散在三个类里面,怎么办?这时咱们就要用到抽象类和接口了。选定一个跟shape关联最大的一项–形状,把它作成抽象类, 其余两样,把它们作成接口,而后在子类里面extends一个抽象类,再implements两个接口就好了。如:

class Square extends Shape implements 颜色, 运动, ... {
...
}

抽象类做用一:

抽象类就是一个类的服务提供商,拥有众多服务,你不用必须用,当须要的时候你来用就能够,若是你以为不提供服务不满意,你还能够本身来作。

这里是一个例子,想上面同样我定义了一个商店类,抽所了它全部像的部分,买(buy),卖(sell),看(view),而且抽象类里都实现了这些方法,那么继承它的子类就自动得到了这些方法,子类就作它本身独特的东西,减小代码的重复,提升复用性。

abstract class BaseShop
{
    public function buy($gid)
    {
        echo '你购买了ID为 :' . $gid . '的商品';
    }

    public function sell($gid)
    {
        echo '你购卖ID为 :' . $gid . '的商品';
    }

    public function view($gid)
    {
        echo '你浏览了ID为 :' . $gid . '的商品';
    }
}

class BallShop extends BaseShop
{
    var $itme_id = null;

    public function __construct()
    {
        $this->itme_id = 2314;
    }

    public function open()
    {
        $this->sell($this->itme_id);
    }
}

抽象类做用二:

在抽象类里面设置抽象方法

在oo设计时,会把一些通用的方法放在一个类里,但考虑到子类继承时的差别性,又不能把它事先实现,就只好用到这个抽象类或接口了。这里很清楚的显示了在抽象类里,咱们贯彻了设原用到点setCenter()的方法,这样,当子类继承它时,就不用再重复写这个设原点的方法了。那么为何draw的方法要设定成抽象方法呢?这是由于不一样的子类要用不一样的实现方法。

abstract class Shape
{
    function setCenter($x, $y)
    {
        $this->x = $x;
        $this->y = $y;
    }

    abstract function draw();

    protected $x, $y;
}

参考:http://chengxudaren.com/index.php?act=article&op=detail&a_id=152

相关文章
相关标签/搜索