JS++ 抽象类和方法
我们已经探索了虚拟方法和 “覆盖”(早期绑定)和 “覆盖”(晚期绑定),它们允许我们为一个方法定义基础实现,并在子类中对该方法进行更具体的实现。然而,如果没有相关的基础实现是有意义的,我们该怎么办呢?考虑一个 “说话 “方法。虽然 “狗 “会 “汪汪”,”猫 “会 “喵喵”,但 “动物 “基类会怎么做?抽象类和方法使我们能够解决这个问题。
当一个类用 “抽象 “修饰符声明时,它不能被实例化。此外,它允许该类拥有 “抽象方法”。抽象方法是没有定义实现的方法,而实现是留给派生类的。从抽象类继承时,派生类必须实现所有的抽象方法;否则,我们会得到一个编译错误。
让我们先把Animal.jspp中的’动物’类变成抽象的,并声明一个抽象的’说话’方法。
external ;
module Animals
{
abstract class Animal
{
protected varelement;
private static unsigned int count = 0;
protected Animal(string iconClassName) {
string elementHTML = makeElementHTML(iconClassName);
element =(elementHTML);
Animal.count++;
}
public static unsigned int getCount() {
return Animal.count;
}
public virtual void render() {
("#content").append(element);
}
public abstract void talk();
private string makeElementHTML(string iconClassName) {
string result = '<div class="animal">';
result += '<i class="icofont ' + iconClassName + '"></i>';
result += "</div>";
return result;
}
}
}
如果我们现在尝试编译,我们会得到编译器错误,要求 “动物 “的子类实现 “谈话 “抽象方法。
让我们从Cat.jspp开始。
import Externals.DOM;
external ;
module Animals
{
class Cat : Animal
{
string _name;
Cat(string name) {
super("icofont-animal-cat");
_name = name;
}
final void render() {element.attr("title", _name);
super.render();
}
final void talk() {
alert("Meow!");
}
}
}
我们导入’Externals.DOM’,因为这个模块为浏览器提供了DOM(文档对象模型)API的所有’外部’声明。这使得我们可以使用’alert’函数,它将弹出一个消息框,显示我们希望猫说的话(”Meow!”)。我们也可以直接将’alert’声明为’外部’。注意,我们用’final’修饰符来覆盖’talk’,但我们也可以用’override’。
我们将以类似的方式实现Dog.jspp,但狗发出的声音不同。
import Externals.DOM;
external ;
module Animals
{
class Dog : Animal
{
string _name;
Dog(string name) {
super("icofont-animal-dog");
_name = name;
}
final void render() {element.attr("title", _name);
super.render();
}
final void talk() {
alert("Woof!");
}
}
}
现在让我们来实现Panda.jspp。 熊猫会叫,所以让我们让它叫起来。
import Externals.DOM;
external $;
module Animals
{
class Panda : Animal
{
Panda() {
super("icofont-animal-panda");
}
final void talk() {
alert("Bark!");
}
}
}
最后一个要实现的类:’犀牛’。让我们假设犀牛不发声。我们完全可以重写抽象方法,让它什么都不做。
external $;
module Animals
{
class Rhino : Animal
{
Rhino() {
super("icofont-animal-rhino");
}
final void talk() {
}
}
}
注意,我们也没有导入’Externals.DOM’。我们不需要它。我们的犀牛不说话,所以我们不需要’alert’函数来显示一个消息框。
在这一点上,你的项目应该能够在没有错误的情况下进行编译。然而,我们的动物实际上还不会说话。我们需要某种事件来触发动物说话。例如,我们可能希望动物在我们点击它时说话。为了实现这一点,我们需要事件处理程序,这就是下一节的主题。