JS++ | Clases abstractas y métodos

Hemos explorado métodos virtuales y ‘sobrescribir’ (enlace temprano) y ‘anular’ (enlace tardío) que nos permiten definir implementaciones base para un método e implementaciones más específicas del método en subclases. Sin embargo, ¿qué hacemos si no hay una implementación base relevante que tenga sentido? Considere un método de ‘hablar’. Mientras que un ‘Perro’ hará «guau» y un ‘Gato’ «maullará», ¿qué hará la clase base ‘Animal’? Las clases y métodos abstractos nos permiten resolver este problema.

Cuando una clase se declara con el modificador ‘abstracto’, no se puede instanciar. Además, permite que la clase tenga «métodos abstractos». Los métodos abstractos son métodos que no definen una implementación, y la implementación se deja a las clases derivadas. Las clases derivadas deben implementar todos los métodos abstractos al heredar de una clase abstracta; de lo contrario, obtendremos un error de compilación.

Comencemos por hacer que nuestra clase ‘Animal’ en Animal.jspp sea abstracta y declarar un método abstracto de ‘hablar’:

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 = '<div class="animal">';
            result += '<i class="icofont ' + iconClassName + '"></i>';
            result += "</div>";
            return result;
        }
    }
}

Si intentamos compilar ahora mismo, obtendremos errores de compilación que exigen que las subclases de ‘Animal’ implementen el método abstracto ‘hablar’.

Comencemos con 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!");
        }
    }
}

Importamos ‘Externals.DOM’ porque este módulo proporciona todas las declaraciones ‘externas’ para la API DOM (Document Object Model) para navegadores. Esto nos permite usar la función de ‘alerta’ que abrirá un cuadro de mensaje con lo que queremos que diga el gato («¡Miau!»). También podríamos haber declarado ‘alerta’ como ‘externo’. Tenga en cuenta que usamos el modificador ‘final’ para anular ‘hablar’, pero también podríamos haber usado ‘anular’.

Vamos a implementar Dog.jspp de manera similar, pero los perros hacen un sonido diferente:

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!");
        }
    }
}

Ahora implementemos Panda.jspp. Los pandas pueden ladrar, así que hagamos que ladre:

import Externals.DOM;

external $;

module Animals
{
    class Panda : Animal
    {
        Panda() {
            super("icofont-animal-panda");
        }

        final void talk() {
            alert("Bark!");
        }
    }
}

Una última clase para implementar: ‘Rhino’. Supongamos que los rinocerontes no emiten ningún sonido. Está perfectamente bien anular el método abstracto y hacer que no haga nada:

external $;

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

        final void talk() {
        }
    }
}

Tenga en cuenta que tampoco importamos ‘Externals.DOM’. No lo necesitábamos. Nuestro rinoceronte no habla, por lo que no necesitamos la función de ‘alerta’ para mostrar un cuadro de mensaje.

En este punto, su proyecto debería poder compilarse sin errores. Sin embargo, nuestros animales en realidad no hablan todavía. Necesitamos algún tipo de evento para que el animal hable. Por ejemplo, podríamos querer que un animal hable cuando hagamos clic sobre él. Para lograr esto, necesitamos controladores de eventos, y este es el tema de la siguiente sección.

Publicación traducida automáticamente

Artículo escrito por RogerPoon y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *