第十节--抽象方法和抽象类 -- Classes and Objects in PHP5 [10]

第十节--抽象方法和抽象类 -- Classes and Objects in PHP5 [10]

作者:Leon Atkinson 翻译:Haohappy 来源:超越PHP
 
/*
+-------------------------------------------------------------------------------+
| = 本文为Haohappy读<<Core PHP Programming>>
| = 中Classes and Objects一章的笔记
| = 翻译为主+个人心得
| = 为避免可能发生的不必要的麻烦请勿转载,谢谢
| = 欢迎批评指正,希望和所有PHP爱好者共同进步!
+-------------------------------------------------------------------------------+
*/

第十节--抽象方法和抽象类

面向对象程序通过类的分层结构构建起来. 在单重继承语言如PHP中, 类的继承是树状的. 一个根类有一个或更多的子类,再从每个子类继承出一个或更多下一级子类. 当然,可能存在多个根类,用来实现不同的功能. 在一个良好设计的体系中,每个根类都应该有一个有用的接口, 可以被应用代码所使用. 如果我们的应用代码被设计成与根类一起工作,那么它也可以和任何一个从根类继承出来的子类合作.

抽象方法是就像子类中一般的方法的占位符(占个地方但不起作用),它与一般方法不同—没有任何代码. 如果类中存在一个或更多抽象方法, 那么这个类就成了抽象类. 你不能实例化抽象类. 你必须继承它们,然后实例化子类. 你也可以把抽象类看成是子类的一个模板.

如果你覆写所有的抽象方法, 子类就变成一个普通的类. 如果没有覆写所有方法, 子类仍是抽象的. 如果一个类中中包含有抽象方法(哪怕只有一个), 你必须声明这个类是抽象的, 在class关键字前加上abstract.

声明抽象方法的语法与声明一般方法不同. 抽象方法的没有像一般方法那样包含在大括号{}中的主体部份,并用分号;来结束.

在例子6.13中, 我们定义了一个含有getArea方法的类Shape. 但由于不知道形状不可能确定图形的面积,确良我们声明了getArea方法为抽象方法. 你不能实例化一个Shape对象,但你可以继承它或在一个表达式中使用它, 就像例6.13中那样.

如果你建立了一个只有抽象方法的类,你就定义了一个接口(interface). 为了说明这种情况, PHP中有interface 和implements关键字. 你可以用interface来代替抽象类, 用implements来代替extends来说明你的类定义或使用一个接口. 例如, 你可以写一个myClass implements myIterface. 这两种方法可以依个人偏爱来选择.

/*注:
两种方法即指:
1. abstract class aaa{} (注意aaa中只有抽象方法,没有一般方法)
class bbb extends aaa{} (在bbb中覆写aaa中的抽象方法)
2. interface aaa{}
class bbb implements aaa{} (在bbb中覆写aaa中的抽象方法)
*/

Listing 6.13 Abstract classes

<?php
//abstract root class 抽象根类
abstract class Shape
{
abstract function getArea(); //定义一个抽象方法
}

//abstract child class 抽象子类
abstract class Polygon extends Shape //多边形
{
abstract function getNumberOfSides();
}

//concrete class 实体类 三角形类
class Triangle extends Polygon
{
public $base;
public $height;

public function getArea() //覆写计算面积方法
{
return(($this->base * $this->height)/2);
}

public function getNumberOfSides() //覆写边数统计方法
{
return(3);
}
}

//concrete class 实体类四边形
class Rectangle extends Polygon
{
public $width;
public $height;

public function getArea()
{
return($this->width * $this->height);
}

public function getNumberOfSides()
{
return(4);
}
}

//concrete class 实体类 圆形
class Circle extends Shape
{
public $radius;

public function getArea()
{
return(pi() * $this->radius * $this->radius);
}
}

//concrete root class 定义一个颜色类
class Color
{
public $name;
}

$myCollection = array(); //建立形状的集合,放入数组

//make a rectangle
$r = new Rectangle;
$r->width = 5;
$r->height = 7;
$myCollection[] = $r;
unset($r);

//make a triangle
$t = new Triangle;
$t->base = 4;
$t->height = 5;
$myCollection[] = $t;
unset($t);

//make a circle
$c = new Circle;
$c->radius = 3;
$myCollection[] = $c;
unset($c);

//make a color
$c = new Color;
$c->name = "blue";
$myCollection[] = $c;
unset($c);

foreach($myCollection as $s)
{
if($s instanceof Shape) //如果$s是Shape类的实例
{
print("Area: " . $s->getArea() .
"<br>n");
}

if($s instanceof Polygon)
{
print("Sides: " .
$s->getNumberOfSides() .
"<br>n");
}

if($s instanceof Color)
{
print("Color: $s->name<br>n");
}

print("<br>n");
}

?>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 可以从抽象类Shape类扩展出一个圆形类Circle。Circle类需要实现Shape类中定义的抽象方法,并且需要添加圆形特有的属性和方法,比如圆的半径、面积、周长等。在Circle类中可以使用数学库中的π常量来计算圆的相关属性。 ### 回答2: 抽象类Shape是一个用来表示几何形状的抽象类,我们可以将它作为一个基类,从中扩展出各种具体的形状类。在这里,我们可以扩展出圆形类Circle。 为了继承Shape类,我们可以定义类Circle并继承Shape类。Circle类可以通过复写Shape类中的一些方法来给出自己的实现。例如,我们可以在Circle中定义一个求面积的方法,以及一个求周长的方法。此外,Circle类还需要拥有独特的属性来描述它自己,例如半径(r)。 在定义Circle类时,我们需要注意其继承了Shape类的方法和属性,因此圆形类Circle应该包含以下特征: 1.拥有Shape类的抽象方法或者实现的方法,例如getPerimeter()和getArea()方法; 2.定义自己特有的属性,例如半径r; 3.提供构造方法; 4.必要时也可以定义自己特有的方法。 下面是一份Circle类的伪代码: abstract class Shape { public abstract double getPerimeter(); public abstract double getArea(); } class Circle extends Shape { private double r; public Circle(double r) { this.r = r; } @Override public double getPerimeter() { return 2 * Math.PI * r; } @Override public double getArea() { return Math.PI * r * r; } public double getR() { return r; } public void setR(double r) { this.r = r; } } 在这份伪代码中,Circle类中包含了Shape类中的两个抽象方法,分别是计算周长和面积的方法。而在Circle类中,我们为其定义了半径r,以及构造函数和一些公共的get和set方法,以便其他程序可以进行访问。当我们需要创建一个圆形时,只需要实例化一个Circle类,并在构造函数中传入半径作为参数,即可创建出一个圆形对象。 通过扩展Shape类,我们可以定义各种具体的形状类,比如正方形、长方形、三角形等等。这样,我们的代码会更加简洁、易于维护和扩展。实现具体类的时候,我们只需要根据该类的特点来实现其独特的属性和方法即可。 ### 回答3: 抽象类是一种不能够直接被实例化的类,其存在的最主要目的是为了让子类继承它并实现它的抽象方法。在这个题目中,我们需要从抽象类Shape类扩展出一个圆形类Circle。 因为Shape类是一个抽象类,所以我们需要实现它的抽象方法来使得Circle类可以正常使用。在这个题目中,我们可以为Shape类增加一个抽象的getArea方法,这个方法的作用是返回这个形状的面积。之后,我们为Circle类实现这个方法,使得Circle类可以被实例化并且能够返回正确的面积值。 除此之外,Circle类还需要一个属性——半径,因为我们知道圆形的面积和半径之间有一个确定的对应关系。因此,我们在Circle类中增加一个radius属性,使得每个Circle对象都可以访问并修改自己的半径值。为了确保半径的有效性,我们可以在Circle类中增加一些限制条件,例如半径必须大于等于零,这样就可以有效地避免出现不合理的半径值。 最后,我们需要在Circle类的构造函数中初始化这个半径值,并且为Circle类增加一个toString方法,使得我们可以方便地将Circle对象转换为字符串。这个toString方法可以返回一个包含Circle对象属性值的字符串,这样就方便了我们对Circle对象进行调试和输出。 总之,从Shape类扩展出一个Circle类需要我们实现Shape类的getArea方法、Circle类的radius属性、限制条件、构造函数和toString方法。通过这些操作,我们可以轻松地构建一个Circle类,方便我们进行相关的计算和操作。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值