陈力:传智播客古代 珍宝币 泡泡龙游戏开发第35讲:PHP 抽象类与接口

陈力:传智播客古代 珍宝币 泡泡龙游戏开发第35讲:PHP 抽象类与接口

  如果一个类使用abstract 来修饰,则该类就是抽象类。抽象方法是声明为abstract的,是不需要实现的,供子类继承且实现的。接口体现了程序设计的多态和高内聚低偶合的设计思想。贵阳网站建设的朋友必须要掌握抽象类和接口的知识。陈力:传智播客古代 珍宝币 泡泡龙游戏开发第35讲:PHP 抽象类与接口


一、PHP程序设计语言的抽象类
    当父类的一些方法不能确定时,可以用abstract关键字来修饰该方法[抽象方法],用abstract 来修饰该类 [抽象类]。
为什么设计抽象类这个技术?
    在实际开发中,我们可能有这样一种类,是其它类的父类,但是它本身并不需要实例化,主要用途是用于让子类来继承,这样可以到达代码复用。同时利于项目设计者,设计类。
    基本用法:
abstract class 类名{
 //方法
 //属性
}

    如果一个类使用abstract 来修饰,则该类就是抽象类,如果一个方法被abstract修饰,则该方法就是抽象方法(抽象方法就不能有方法体)。
abstract class 类名{
 abstract 修饰符 function 函数名(参数列表);

abstract class Animal{
  public $name;
  abstract public function cry();//抽象函数不能有函数体。
}
    抽象类可以没有抽象方法,同时还可以有实现了的方法。
<?php
 abstract class Animal{
  public $name="abc";
  protected $age;
  //这个方法没有方法体,这个方法主要是为了让子类去实现。
  abstract public function cry();
  public function getName(){//这个方法是实现了的
   return $this->name;
  }
 }
 class Cat extends Animal{//实现了方法
  public  function cry(){
   echo "猫猫叫唤..";
  }
 }
 $cat1=new Cat();//创建一个子类实例
 $cat1->cry();
 echo $cat1->getName();
?>
如果一个类中,只要有抽象方法,则该类必须声明为abstract类。
abstract class A{
  abstract function test();
 }
 echo "ok";

    如果A类继承了一个抽象类B,则要求A类实现从B类继承的所有抽象方法。案例:
//这是一个抽象类
 abstract class A{
  abstract function test();
 }
 //B类要么自己抽象,或者实现从A类继承的抽象方法。
 class B extends A{
  function test(){
   echo "我实现A:test()";
  }
 }
 echo "hello";
    抽象类注意事项:
①抽象类不能被实例化。
②抽象类不一定要包含abstract方法。也就是说,抽象类可以没有abstract方法。
③一旦类包含了abstract方法,则这个类必须声明为abstract。
④抽象方法不能有函数体。
⑤如果一个类继承了某个抽象类,则它必须实现该抽象类的所有抽象方法。(除非它自己也声明为抽象类)。

二、PHP程序设计语言的接口
    一个程序就是一个世界,在现实世界存在的情况,在程序中也会出现。接口就是给出一些没有实现的方法,封装到一起,到某个类要使用的时候,在根据具体情况把这些方法写出来。语法:
class 类名 implements 接口{
}
    接口是更加抽象的抽象类,抽象类里的方法可以有方法体,接口里的所有方法都没有方法体。接口体现了程序设计的多态和高内聚低偶合的设计思想。
入门例子:
<?php
 //使用程序模拟现实情况
 //定义规范(方法/属性)
 interface iUsb{
  public function start();
  public function stop();
 }
 //编写相机类,让它去实现接口
 //1.当一个类实现了某个接口,则要求该类必须实现这个接口的所有方法。
 class Camera implements  iUsb{
  public function start(){
   echo "相机开始工作";
  }
  public function stop(){
   echo "相机停止工作...";
  }
 }
 //编写手机类
 class Phone implements iUsb{
  public function start(){
   echo "手机开始工作";
  }
  public function stop(){
   echo "手机停止工作...";
  }
 }
 $camera1=new Camera();//使用
 $camera1->start();
 $camera1->stop();
 echo "<br/>";
 $phone1=new Phone();//手机对象
 $phone1->start();
 $phone1->stop();
?>

接口的使用基本语法:
interface 接口名{
 //属性
 //方法
}
接口的方法都不能有方法体。
如何去实现接口:
class 类名 implements 接口名1,接口2.{
}
    接口作用就是声明一些方法,供其它类来实现。接口还体现编程中我们希望的效果高内聚低耦合的特点:
    什么情况下可以考虑使用接口?软件设计人员在定规范、定下规范让别的程序员来实现。或者在多个类中,这些类是平级的关系,这些类都会去实现某个功能,只是实现的方式不一样。这种情况下也可以考虑使用接口。
比如:
 //学生管理系统 (students)
 //定义接口
 interface StuManageInterface{
  public function addStudent($stu);
  public function delStudent($id);
  public function updStudent($stu);
 }
 //三张在程序设计时
 class StuManage {
  public function tianjiaxuesheng(){
  }
 }

    在程序设计时,张三使用了拼音的函数名。李四又使用了其它函数名。这样就不统一了,软件设计师此时可以定义接口,固定为addStudent函数名。其它人员只需要实现即可。
    接口的细节说明:
(1)不能去实例化一个接口。
interface iUsb{}
$a=new iUsb(); (这种是错误的!)
(2)接口中的所有方法,都不能有方法体。
(3)一个类可以去实现多个接口,逗号隔开。
语法如下:
class 类名 implements 接口1,接口2{
}
(4)接口中可以有属性,但是必须是常量(并且是public)。
interface iUsb{
  const A=90;
 }
 echo "ok".iUsb::A;
(5)接口的方法是public(默认就是public ),不能是protected 和private。
举例:
interface iUsb{
  const A=90;
  function test();
 }
 echo "ok".iUsb::A;

    类和接口之间关系:
<?php
 interface iUsb2{
  public function a();
 }
 interface iUsb3{
  public function b();
 }
 interface iUsb extends iUsb2,iUsb3{
  const A=90;
  function test();
 }
 class Class1 implements iUsb{
  public function a(){
  }
  public function b(){
  }
  public function test(){
  }
 }
 echo "ok".iUsb::A;
?>
    从上面我们看出:一个接口不能继承其它的类,但是可以继承别的接口。一个接口可以继承多个其它的接口。当一个类去实现了某些接口,则必须实现所有接口的方法。

    继承和实现接口的比较:
<?php
 class Monkey{
  public $age;
  public $name;
  public function climbing(){
   echo "猴子会爬树..";
  }
 }
 interface iBirdable{
  public function fly();
 }
 interface iFishable{
  public function swimming();
 }
 class LittleMonkey extends Monkey implements iBirdable,iFishable {
  public function fly(){
   echo "猴子会飞...";
  }
  public function swimming(){
   echo "猴子会游泳..";
  }
 }
 $littleMonkey=new LittleMonkey();
 $littleMonkey->climbing();
 $littleMonkey->fly();
 $littleMonkey->swimming();
?>
   可以认为实现接口是对单一继承的补充,可以在不破坏类层级关系的前提下,对某个类功能扩展。
   php的继承是单继承,也就是一个类最多只能有一个父类,这种单继承的机制可保证类的纯洁性,比c++中的多继承机制简洁。
   但是不可否认,对子类功能的扩展有一定影响,所以我们认为:
   (1)实现接口可以看作是对继承的一种补充,还有一点,继承是层级式的,不太灵活。这种结构修改某个类就会打破这种继承的平衡,而接口就没有这样的麻烦,因为它只针对实现接口的类才起作用。
   (2)实现接口可在不打破继承关系的前提下,对某个类功能扩展,非常灵活。

三、final关键字
    final 中文意思:最后的,最终的。final可以修饰类或者方法。
    ①不希望父类的某个方法被子类重载(override)时,可以用final关键字修饰。
    ②不希望类被继承时,可以用final修饰。
    如果贵阳网站建设中,希望某个类不被其它的类来继承(可能因为安全考虑...),可以使用final
<?php
 final class A{
 }
 class B extends A{
 }
 echo "ok";
?>
    如果我们希望某个方法,比如计算个人所得税的方法,不能子类改写,可以使用fianl 来修饰方法。
class A{
  final public function getRate($salary){
   return $salary*0.08;
  }
 }
 class B extends A{
  //不能去覆盖父类的getRate方法.
  /*public function getRate($sal){
   return $sal*0.01;
  }*/
 }
 $b=new B();
 echo $b->getRate(100);
注:final关键字不能去修饰属性。


四、const 关键字
   const(constant) 中文意思:常量在某些情况下,程序员可能有这样的需求:
   ①当不希望一个成员变量被修改,希望该变量的值是固定不变的。这时可以用const 去修饰该成员变量,这样这个变量就自动成为常量。

基本用法是:
class A{
 const 常量名=赋初值;
}
interface 接口名{
 const 常量名=赋初值;
}
常量默认是public。
常量在使用时,通过类名::常量名; 接口名::常量
<?php
 class A{
  //常量在定义的时候,必须给初值.
  //const 关键字前面不要带修饰符号.
  const TAX_RATE=0.08;
  public function payTax($val){
   //常量不能修改.
   //A::TAX_RATE=0.01;
   //return $val*self::TAX_RATE; 【ok】
   return $val*A::TAX_RATE; //【ok】
  }
 }
 $a=new A();
 echo $a->payTax(200);
?>
const使用注意事项:
   ①常量名一般字母全部大写 : TAXRATE
   ②在定义常量的同时,必须赋初值 const TAXRATE=1.1
   ③const关键字前不能用public/protected/private修饰。
   ④访问常量
   在类的外部 类名::常量名
   在类的内部,可以使用   类名::常量名,或者 self::常量名
   ⑤常量的值在定义的时候就初始化,以后就不能修改。
   ⑥常量可以被子类继承。
   ⑦一个常量是属于一个类的,而不是某个对象的。 
const什么时候用?某些值是固定不变的,比如圆周率 3.1415926。

五、面向对象编程的综合案例
    现在我们一起来完成php版本的计算器,从而加深对php的认识,为下一步学习做准备。先用两个页面来完该计算器: myCal.php(界面) myResult.php(计算)
知识点: 
 1.  如何接收php页面提交的数据,并处理。
 2.  php中如何使用javascript完成对数据合法性的校验。

软件设计,PHP抽象类与接口,PHP教程


MyCalView.php代码如下:
<html>
</head>
<title>我的计算器</title>
<script language="javascript">
 
 function check(){
  //js的内容 。。。。
  var num1val=document.getElementById("num1").value;
  var num2val=document.getElementById("num2").value;
  
  if(isNaN(num1val)||isNaN(num2val)){
   window.alert("num1和num2必须是数");
   //如果返回false就不提交.
   return false;
  }
 }
</script>
</head>
<h1>我的计算器</h1>
<form action="CalProcess.php" method="post" οnsubmit="return check()">
num1:<input type="text" id="num1" name="num1"><br/>
num2:<input type="text" id="num2" name="num2"><br/>
oper:
<select name="oper">
<option value="+">+</option>
<option value="-">-</option>
<option value="*">*</option>
<option value="/">/</option>
</select>
<input type="submit" value="提交">
</form>
</html>
CalProcess.php源代码如下:
<?php
require_once "OperService.class.php";
 //接收三个数
 //isset
 if(isset($_REQUEST['num1'])){
  $num1=$_REQUEST['num1'];
 }
 if(isset($_REQUEST['num2'])){
  $num2=$_REQUEST['num2'];
 }
 if(isset($_REQUEST['oper'])){
  $oper=$_REQUEST['oper'];
 }
 //创建对象
 $operService=new OperService();
 echo $operService->getResult($num1,$num2,$oper);
?>
OperService.class.php源代码如下:
<?php
 //定义了一个专门提供计算的类.
 class OperService{
  public function getResult($num1,$num2,$oper){
      switch($oper){
     case "+":
        return $num1+$num2;
        break;
     case "-":
        return $num1-$num2;
        break;
      case "*":
        return $num1*$num2;
        break;
      case "/":
        return $num1/$num2;
       default:
        echo "操作符错误";
      }
  }
 }
?>

【推荐阅读】

一、PHP程序设计语言的抽象类
    当父类的一些方法不能确定时,可以用abstract关键字来修饰该方法[抽象方法],用abstract 来修饰该类 [抽象类]。
为什么设计抽象类这个技术?
    在实际开发中,我们可能有这样一种类,是其它类的父类,但是它本身并不需要实例化,主要用途是用于让子类来继承,这样可以到达代码复用。同时利于项目设计者,设计类。
    基本用法:
abstract class 类名{
 //方法
 //属性
}

    如果一个类使用abstract 来修饰,则该类就是抽象类,如果一个方法被abstract修饰,则该方法就是抽象方法(抽象方法就不能有方法体)。
abstract class 类名{
 abstract 修饰符 function 函数名(参数列表);

abstract class Animal{
  public $name;
  abstract public function cry();//抽象函数不能有函数体。
}
    抽象类可以没有抽象方法,同时还可以有实现了的方法。
<?php
 abstract class Animal{
  public $name="abc";
  protected $age;
  //这个方法没有方法体,这个方法主要是为了让子类去实现。
  abstract public function cry();
  public function getName(){//这个方法是实现了的
   return $this->name;
  }
 }
 class Cat extends Animal{//实现了方法
  public  function cry(){
   echo "猫猫叫唤..";
  }
 }
 $cat1=new Cat();//创建一个子类实例
 $cat1->cry();
 echo $cat1->getName();
?>
如果一个类中,只要有抽象方法,则该类必须声明为abstract类。
abstract class A{
  abstract function test();
 }
 echo "ok";

    如果A类继承了一个抽象类B,则要求A类实现从B类继承的所有抽象方法。案例:
//这是一个抽象类
 abstract class A{
  abstract function test();
 }
 //B类要么自己抽象,或者实现从A类继承的抽象方法。
 class B extends A{
  function test(){
   echo "我实现A:test()";
  }
 }
 echo "hello";
    抽象类注意事项:
①抽象类不能被实例化。
②抽象类不一定要包含abstract方法。也就是说,抽象类可以没有abstract方法。
③一旦类包含了abstract方法,则这个类必须声明为abstract。
④抽象方法不能有函数体。
⑤如果一个类继承了某个抽象类,则它必须实现该抽象类的所有抽象方法。(除非它自己也声明为抽象类)。

二、PHP程序设计语言的接口
    一个程序就是一个世界,在现实世界存在的情况,在程序中也会出现。接口就是给出一些没有实现的方法,封装到一起,到某个类要使用的时候,在根据具体情况把这些方法写出来。语法:
class 类名 implements 接口{
}
    接口是更加抽象的抽象类,抽象类里的方法可以有方法体,接口里的所有方法都没有方法体。接口体现了程序设计的多态和高内聚低偶合的设计思想。
入门例子:
<?php
 //使用程序模拟现实情况
 //定义规范(方法/属性)
 interface iUsb{
  public function start();
  public function stop();
 }
 //编写相机类,让它去实现接口
 //1.当一个类实现了某个接口,则要求该类必须实现这个接口的所有方法。
 class Camera implements  iUsb{
  public function start(){
   echo "相机开始工作";
  }
  public function stop(){
   echo "相机停止工作...";
  }
 }
 //编写手机类
 class Phone implements iUsb{
  public function start(){
   echo "手机开始工作";
  }
  public function stop(){
   echo "手机停止工作...";
  }
 }
 $camera1=new Camera();//使用
 $camera1->start();
 $camera1->stop();
 echo "<br/>";
 $phone1=new Phone();//手机对象
 $phone1->start();
 $phone1->stop();
?>

接口的使用基本语法:
interface 接口名{
 //属性
 //方法
}
接口的方法都不能有方法体。
如何去实现接口:
class 类名 implements 接口名1,接口2.{
}
    接口作用就是声明一些方法,供其它类来实现。接口还体现编程中我们希望的效果高内聚低耦合的特点:
    什么情况下可以考虑使用接口?软件设计人员在定规范、定下规范让别的程序员来实现。或者在多个类中,这些类是平级的关系,这些类都会去实现某个功能,只是实现的方式不一样。这种情况下也可以考虑使用接口。
比如:
 //学生管理系统 (students)
 //定义接口
 interface StuManageInterface{
  public function addStudent($stu);
  public function delStudent($id);
  public function updStudent($stu);
 }
 //三张在程序设计时
 class StuManage {
  public function tianjiaxuesheng(){
  }
 }

    在程序设计时,张三使用了拼音的函数名。李四又使用了其它函数名。这样就不统一了,软件设计师此时可以定义接口,固定为addStudent函数名。其它人员只需要实现即可。
    接口的细节说明:
(1)不能去实例化一个接口。
interface iUsb{}
$a=new iUsb(); (这种是错误的!)
(2)接口中的所有方法,都不能有方法体。
(3)一个类可以去实现多个接口,逗号隔开。
语法如下:
class 类名 implements 接口1,接口2{
}
(4)接口中可以有属性,但是必须是常量(并且是public)。
interface iUsb{
  const A=90;
 }
 echo "ok".iUsb::A;
(5)接口的方法是public(默认就是public ),不能是protected 和private。
举例:
interface iUsb{
  const A=90;
  function test();
 }
 echo "ok".iUsb::A;

    类和接口之间关系:
<?php
 interface iUsb2{
  public function a();
 }
 interface iUsb3{
  public function b();
 }
 interface iUsb extends iUsb2,iUsb3{
  const A=90;
  function test();
 }
 class Class1 implements iUsb{
  public function a(){
  }
  public function b(){
  }
  public function test(){
  }
 }
 echo "ok".iUsb::A;
?>
    从上面我们看出:一个接口不能继承其它的类,但是可以继承别的接口。一个接口可以继承多个其它的接口。当一个类去实现了某些接口,则必须实现所有接口的方法。

    继承和实现接口的比较:
<?php
 class Monkey{
  public $age;
  public $name;
  public function climbing(){
   echo "猴子会爬树..";
  }
 }
 interface iBirdable{
  public function fly();
 }
 interface iFishable{
  public function swimming();
 }
 class LittleMonkey extends Monkey implements iBirdable,iFishable {
  public function fly(){
   echo "猴子会飞...";
  }
  public function swimming(){
   echo "猴子会游泳..";
  }
 }
 $littleMonkey=new LittleMonkey();
 $littleMonkey->climbing();
 $littleMonkey->fly();
 $littleMonkey->swimming();
?>
   可以认为实现接口是对单一继承的补充,可以在不破坏类层级关系的前提下,对某个类功能扩展。
   php的继承是单继承,也就是一个类最多只能有一个父类,这种单继承的机制可保证类的纯洁性,比c++中的多继承机制简洁。
   但是不可否认,对子类功能的扩展有一定影响,所以我们认为:
   (1)实现接口可以看作是对继承的一种补充,还有一点,继承是层级式的,不太灵活。这种结构修改某个类就会打破这种继承的平衡,而接口就没有这样的麻烦,因为它只针对实现接口的类才起作用。
   (2)实现接口可在不打破继承关系的前提下,对某个类功能扩展,非常灵活。

三、final关键字
    final 中文意思:最后的,最终的。final可以修饰类或者方法。
    ①不希望父类的某个方法被子类重载(override)时,可以用final关键字修饰。
    ②不希望类被继承时,可以用final修饰。
    如果贵阳网站建设中,希望某个类不被其它的类来继承(可能因为安全考虑...),可以使用final
<?php
 final class A{
 }
 class B extends A{
 }
 echo "ok";
?>
    如果我们希望某个方法,比如计算个人所得税的方法,不能子类改写,可以使用fianl 来修饰方法。
class A{
  final public function getRate($salary){
   return $salary*0.08;
  }
 }
 class B extends A{
  //不能去覆盖父类的getRate方法.
  /*public function getRate($sal){
   return $sal*0.01;
  }*/
 }
 $b=new B();
 echo $b->getRate(100);
注:final关键字不能去修饰属性。


四、const 关键字
   const(constant) 中文意思:常量在某些情况下,程序员可能有这样的需求:
   ①当不希望一个成员变量被修改,希望该变量的值是固定不变的。这时可以用const 去修饰该成员变量,这样这个变量就自动成为常量。

基本用法是:
class A{
 const 常量名=赋初值;
}
interface 接口名{
 const 常量名=赋初值;
}
常量默认是public。
常量在使用时,通过类名::常量名; 接口名::常量
<?php
 class A{
  //常量在定义的时候,必须给初值.
  //const 关键字前面不要带修饰符号.
  const TAX_RATE=0.08;
  public function payTax($val){
   //常量不能修改.
   //A::TAX_RATE=0.01;
   //return $val*self::TAX_RATE; 【ok】
   return $val*A::TAX_RATE; //【ok】
  }
 }
 $a=new A();
 echo $a->payTax(200);
?>
const使用注意事项:
   ①常量名一般字母全部大写 : TAXRATE
   ②在定义常量的同时,必须赋初值 const TAXRATE=1.1
   ③const关键字前不能用public/protected/private修饰。
   ④访问常量
   在类的外部 类名::常量名
   在类的内部,可以使用   类名::常量名,或者 self::常量名
   ⑤常量的值在定义的时候就初始化,以后就不能修改。
   ⑥常量可以被子类继承。
   ⑦一个常量是属于一个类的,而不是某个对象的。 
const什么时候用?某些值是固定不变的,比如圆周率 3.1415926。

五、面向对象编程的综合案例
    现在我们一起来完成php版本的计算器,从而加深对php的认识,为下一步学习做准备。先用两个页面来完该计算器: myCal.php(界面) myResult.php(计算)
知识点: 
 1.  如何接收php页面提交的数据,并处理。
 2.  php中如何使用javascript完成对数据合法性的校验。

软件设计,PHP抽象类与接口,PHP教程


MyCalView.php代码如下:
<html>
</head>
<title>我的计算器</title>
<script language="javascript">
 
 function check(){
  //js的内容 。。。。
  var num1val=document.getElementById("num1").value;
  var num2val=document.getElementById("num2").value;
  
  if(isNaN(num1val)||isNaN(num2val)){
   window.alert("num1和num2必须是数");
   //如果返回false就不提交.
   return false;
  }
 }
</script>
</head>
<h1>我的计算器</h1>
<form action="CalProcess.php" method="post" οnsubmit="return check()">
num1:<input type="text" id="num1" name="num1"><br/>
num2:<input type="text" id="num2" name="num2"><br/>
oper:
<select name="oper">
<option value="+">+</option>
<option value="-">-</option>
<option value="*">*</option>
<option value="/">/</option>
</select>
<input type="submit" value="提交">
</form>
</html>
CalProcess.php源代码如下:
<?php
require_once "OperService.class.php";
 //接收三个数
 //isset
 if(isset($_REQUEST['num1'])){
  $num1=$_REQUEST['num1'];
 }
 if(isset($_REQUEST['num2'])){
  $num2=$_REQUEST['num2'];
 }
 if(isset($_REQUEST['oper'])){
  $oper=$_REQUEST['oper'];
 }
 //创建对象
 $operService=new OperService();
 echo $operService->getResult($num1,$num2,$oper);
?>
OperService.class.php源代码如下:
<?php
 //定义了一个专门提供计算的类.
 class OperService{
  public function getResult($num1,$num2,$oper){
      switch($oper){
     case "+":
        return $num1+$num2;
        break;
     case "-":
        return $num1-$num2;
        break;
      case "*":
        return $num1*$num2;
        break;
      case "/":
        return $num1/$num2;
       default:
        echo "操作符错误";
      }
  }
 }
?>

【推荐阅读】陈力:传智播客古代 珍宝币 泡泡龙游戏开发第35讲:PHP 抽象类与接口

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值