看钱币课程:
abstract class Money
{
private $value;
public abstract function getName();
public function show()
{
static::announceOutput();
return 'output: '.$this->value.' ('.$this->getName().')');
}
public function announceOutput() { }
}
和一些实现
class Dollar extends Money
{
public function getName()
{
return '$';
}
}
class Huf extends Money
{
public function getName()
{
return 'HUF';
}
}
class Font extends Money
{
public function getName()
{
return 'L';
}
public function announceOutput()
{
return 'Font is outputted, its name is miswritten';
}
}
我知道它不是一个逼真的例子。我要展示的是:
getName()
在每个valute中都是不同的,因此它必须是抽象的
覆盖100%show()
在每个班级实施都没有意义 - 它是输出的
比如每个值announceOutput()
这里有趣的部分。法礼可能
决定是否覆盖它,所以它不必是抽象的。
不过,如果是这样,在每个班级都会有很多空的
announceOutput()方法。所以它就像一个半抽象的类,但它
不太可能被覆盖。我的问题是,这表明我做的事情不行吗?
答案 0 :(得分:2)
在这种情况下,您应该使用接口而不是抽象类来定义" children"必须使用指定的签名
实现指定的方法interface MoneyName
{
public function getName();
}
abstract class Money
{
private $value;
public function show()
{
static::announceOutput();
return 'output: '.$this->value.' ('.$this->getName().')');
}
public function announceOutput() { }
}
class Dollar extends Money implements MoneyName
{
public function getName()
{
return '$';
}
}
您还可以实现多个接口
答案 1 :(得分:1)
这并不表示你做错了什么。这里发生的事情是,抽象类提供了方法的基本行为,同时仍然允许其任何子代用自己的实现来否决这种默认行为。
您可能被抛弃了,因为示例中announceOutput()
方法的默认行为没有正文,这使得它看起来很奇怪。如果那里有实际的代码,那将是完全正常的。
但是,正如评论中所提到的, 也可以通过接口修复此问题。这是否会更好取决于具体情况。在你的例子中,这似乎是完全可行的。