当谈到 OOP 的课程时,我终于有了我的啊哈时刻。我一直在努力思考这个想法。现在我开始明白了,我想知道扩展一个类的目的是什么。将另一个方法添加到类中会不会更简单,还是我只是错过了重点?
3 回答
如果要向类添加功能,请添加方法。但是,在某些情况下,您想要添加功能,但无法在基类中执行此操作。
最好的例子是展示。当向类添加方法Radius
时,只有当类是 a 时才有意义Circle
,aRect
没有半径。向基类添加方法Radius
也没有任何意义,因为Rect
该类也获得了方法Radius
。
例子:
abstract class Shape
{
abstract public function Draw();
}
class Rect extends Shape
{
public function Draw()
{
}
}
class Circle extends Shape
{
public function Draw()
{
}
public function Radius()
{
}
}
有时原始类是您无法更改的库的一部分。
有时您想以多种不同的方式扩展超类。
例如(java 语法而不是 PHP,但想法是一样的):
class Shape {
abstract double getArea();
}
class Square extends Shape {
double getArea() {
return size * size;
}
}
class Circle extends Shape {
double getArea() {
return radius * radius * Math.PI;
}
}
对于接受 Shape 类型参数的方法,您可以传入 Squares 和 Circles。该方法不需要知道它得到哪一个,但仍然可以调用 getArea()。如果您只是将该方法添加到 Shape 类,这将不起作用。
这将是一个简化,但给你一个现实生活中的例子:
假设您要创建一个内容管理系统,即根据用户输入在您的网站上显示不同页面的脚本。
您可能希望每个页面(我们称它们为模块)具有特定功能,例如在该页面/模块上执行的允许命令。然后,这些不同的命令可以是每个模块类中的不同方法。
但是,如果您允许登录命令,无论用户当前在您网站的哪个位置,会怎样?即,这将是所有模块之间共享的命令。
然后,您的解决方案可以通过拥有一个父模块类来解决,登录方法将驻留在其中,并且可由所有模块执行。
// Your parent class
abstract class ParentModule
{
protected function login()
{
// Login stuff
}
}
// One of your modules
final class ArticleModule extends ParentModule
{
public function submit_article()
{
// An example function
}
}
// Another one of your modules that the user could still login from
final class AnotherModule extends ParentModule
{
public function another_command()
{
// Magic
}
}
然后,您的控制器可能如下所示。
$module = new ArticleModule();
$module->login();
$module->submit_article();
最后,当你开始研究接口时——我花了很长时间才理解这些——你将再次看到抽象类的好处。事实上,如果你完全掌握了抽象类的概念,你会更容易理解接口。