Php抽象类和抽象方法

抽象类定义概述

抽象类不能被实例化。抽象类中只定义(或部分实现)子类需要的方法。子类可以继承它并且通过实现其中的抽象方法,使抽象类具体化。

我们可以用一个abstract关键字来定义一个抽象类,示例如下:

abstract class Animal {
 //抽象类中可以定义属性
  protected $animal = 'animal';
  //抽象类中也可以定义非抽象方法
  public function printit($name) {
      $this->animal = $name;
      echo $animal;
  } 
}

由上可见,抽象类和普通类一样,都可以创建方法和属性,那么抽象类可以像普通类那样被实例化吗?我们试一下,实践出真知:

<?php
abstract class Animal {
  protected $animal = 'animal';
  public function printit($name) {
      $this->animal = $name;
      echo $animal;
  } 
}

$Animal = new Animal();

运行结果:Fatal error: Cannot instantiate abstract class Animal in D:\Program Files\wamp\www\a.php on line 10

运行结果显示,不能实例化抽象类Animal,现在知道咯,抽象类不能像普通类那样被实例化的哟。

下面来讨论一下抽象类内的抽象方法

抽象方法用abstract关键字声明,其中不能有具体内容。你可以像声明普通类方法那样声明抽象方法,但要以分号而不是方法体结束。

而在大多数情况下,抽象类中至少要有一个抽象方法,否则这个抽象类也就没有抽象的意义了,也就是说,这个抽象类内可以没有抽象方法只有普通方法,但是,你也没必要将这个类声明称抽象类了,直接去掉abstract变成普通类就行了。
像下面这段代码,就创建了一个抽象类和内部抽象方法:

abstract class Animal {
 //属性
  protected $animal = 'animal';

 //普通方法
  public function printit($name) {
      $this->animal = $name;
      echo $animal;
  }
  //抽象方法,以分号结束,无方法体;抽象类中至少要有一个抽象方法
  abstract public function setit(); 
}

那么,一个类中只有抽象方法而这个类不是抽象类可以吗?试验一下:

<?php
class Animal {
  protected $animal = 'animal';
  public function printit($name) {
      $this->animal = $name;
      echo $animal;
  }
  abstract public function setit();
}

运行结果:Fatal error: Class Animal contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (Animal::setit) in D:\Program Files\wamp\www\a.php on line 9

结果显示了一个致命的错误,说类Animal包含了一个抽象方法,所以这个类必须被声明为抽象类或者实现有抽象方法setit()的类。

继承抽象类并实现抽象方法

创建抽象方法后,要确保所有子类中都实现可该方法,但实现的细节可以先不确定。

如果创建了一个继承自抽象类Animal的普通类,但是不实现其中的抽象方法,会发生什么呢?看下面的这段代码:

<?php
abstract class Animal {
  protected $animal = 'animal';
  public function printit($name) {
      $this->animal = $name;
      echo $animal;
  }
  abstract public function setit();
}

class Fish extends Animal {

}

运行结果:Fatal error: Class Fish contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (Animal::setit) in D:\Program Files\wamp\ w\a.php online 13

这个和只有抽象方法没有把类定义为抽象类发生的错误一样,所以抽象类的每个子类必须实现抽象类中的所有抽象方法,或者把他们自身也声明为抽象方法。

扩展类不仅仅负责简单实现抽象类中的抽象方法,还必须重新声明方法。新的方法的访问控制不能比抽象方法的访问控制更严格。新的实现方法的参数个数应该和抽象方法的参数个数一样,重新生成对应的类型提示。

我们先来定义一个继承自抽象类Animal的子类:
1>
场景:Fish子类中的setit()方法中包含参数;
验证:新的实现方法的参数个数应该和抽象方法的参数个数一样;

<?php
abstract class Animal {
  protected $animal = 'animal';
  public function printit($name) {
      $this->animal = $name;
      echo $animal;
  }
  abstract public function setit();
}

class Fish extends Animal {
   //子类中实现抽象方法的函数和抽象类中方法的参数不一致
   public function setit($name) {
       echo $name;
   }
}

运行结果:Fatal error: Declaration of Fish::setit() must be compatible with Animal::setit() in D:\Program Files\wamp\www\a.php on line 15

2>
场景:Fish子类中的setit()方法被声明为private;
验证:新的方法的访问控制不能比抽象方法的访问控制更严格。
(1) 如果 Animal 中 setit() 声明为 public ,那么 Fish 中 setit() 的声明只能是 public ,不能是 protected 或 private ;
(2) 如果 Animal 中 setit() 声明为 protected ,那么 Fish 中 setit() 的声明可以是 public 或 protected ,但不能是 private ;
(3) 如果 Animal 中 setit() 声明为 private ,嘿嘿,不能定义为 private 哦!( Fatal error : Abstract function Animal ::setit() cannot be declared private ) —–引自http://blog.csdn.net/sunlylorn/article/details/6124319

<?php
abstract class Animal {
  protected $animal = 'animal';
  public function printit($name) {
      $this->animal = $name;
      echo $animal;
  }
  abstract public function setit();
}

class Fish extends Animal {
   //子类中的实现方法被声明为private和抽象类中的方法声明不一致
   private function setit($name) {
       echo $name;
   }
}

运行结果:Fatal error: Access level to Fish::setit() must be public (as in class Animal) in D:\Program Files\wamp\www\a.php on line 15

推荐书籍:《深入PHP面向对象、模式与实践》

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值