📜  JS++ |抽象类和方法

📅  最后修改于: 2022-05-13 01:54:35.687000             🧑  作者: Mango

JS++ |抽象类和方法

我们已经探索了虚拟方法和“覆盖”(早期绑定)和“覆盖”(后期绑定),它们允许我们定义方法的基本实现以及子类中方法的更具体的实现。但是,如果没有有意义的相关基础实现,我们该怎么办?考虑一种“谈话”方法。虽然“狗”会“汪汪”,“猫”会“喵喵叫”,但“动物”基类会做什么?抽象类和方法允许我们解决这个问题。

当一个类用'abstract'修饰符声明时,它不能被实例化。此外,它允许类具有“抽象方法”。抽象方法是不定义实现的方法,实现留给派生类。从抽象类继承时,派生类必须实现所有抽象方法;否则,我们会得到一个编译错误。

让我们首先将 Animal.jspp 中的“Animal”类抽象化并声明一个抽象的“talk”方法:

external $;

module Animals
{
    abstract class Animal
    {
        protected var $element;
        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 = '
'; result += ''; result += "
"; return result; } } }

如果我们现在尝试编译,我们会得到编译器错误,要求 'Animal' 的子类实现 'talk' 抽象方法。

让我们从 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 提供了所有“外部”声明。这使我们可以使用“警报”函数,该功能将弹出一个消息框,其中包含我们希望猫说的话(“喵!”)。我们也可以将“警报”声明为“外部”。请注意,我们使用了“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!");
        }
    }
}

最后一个要实施的课程:'Rhino'。让我们假设犀牛不会发出声音。只覆盖抽象方法并让它什么都不做是完全可以的:

external $;

module Animals
{
    class Rhino : Animal
    {
        Rhino() {
            super("icofont-animal-rhino");
        }

        final void talk() {
        }
    }
}

请注意,我们也没有导入“Externals.DOM”。我们不需要它。我们的犀牛不会说话,所以我们不需要“警报”函数来显示消息框。

此时,您的项目应该能够无错误地编译。然而,我们的动物实际上还不会说话。我们需要某种事件来触发动物说话。例如,当我们点击动物时,我们可能希望它说话。为此,我们需要事件处理程序,这是下一节的主题。