Interfaces y herencia de clases abstractas, implementación en clases extendidas


En cada ejemplo que he visto, las clases extendidas implementan las interfaces de sus padres. Para referencia, el siguiente ejemplo:

interface MyInterface{
    public function foo();
    public function bar();
}

abstract class MyAbstract implements MyInterface{
    public function foo(){ /* stuff */ }
    public function bar(){ /* stuff */ }
}

// what i usually see
class MyClass extends MyAbstract implements MyInterface{}

// what i'm curious about
class MyOtherClass extends MyAbstract{}

¿Se considera mala práctica o algo así la falla en implementar una interfaz en un hijo, que es implementada por un padre? ¿Hay algún inconveniente técnico en omitir la implementación en el niño?

Author: Dan Lugg, 2011-06-16

5 answers

Consideraría que estás en el camino correcto. No hay necesidad de declarar que está implementando la interfaz, al extender una clase que ya implements. Para mí es solo otra pieza de código para mantener si se necesita un cambio. ¡Así que sí, tienes razón!

 20
Author: Emil Ivanov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-06-16 08:41:45

Es un fallo en la implementación de una interfaz en un niño, que es implementado por un padre, considerado mala práctica o algo? ¿Hay alguna técnica inconvenientes de omitir el implementación en el niño?

Simplemente no puedo responder a su pregunta mejor de lo que este tipo tiene:

Por su naturaleza, aunque a veces pueden parecer bastante similares, abstractas clases e interfaces de clase sirven propósitos muy distintos.

La interfaz de un clase se entiende como un herramienta para el "usuario" de esa clase. Un interfaz es una presentación pública para la clase, y debe anunciar, a cualquiera que considere usarlo, lo que métodos y constantes disponibles y accesible desde el exterior. Tan, como su nombre indica, siempre se sienta entre el usuario y la clase implementarlo.

Por otro lado, una clase abstracta es una herramienta destinada a ayudar a "implementor" de las clases que extiéndelo. Es un infraestructura que puede imponer restricciones y directrices sobre lo que el concreto las clases deberían parecerse. De una clase perspectiva de diseño, clases abstractas son más arquitectónicamente importante que las interfaces. En este caso, el implementor se encuentra entre el resumen clase y el concreto, edificio el último sobre el primero.

Referencia

Por lo tanto, depende de usted decidir, basado en quién va a usar (instanciar) sus clases, y quién va a escribirlas. Si usted es el único usuario y escritor de sus clases, entonces, tal vez, solo tal vez, no las necesita a las dos. Pero, si desea dar a todos un plano reducido a bits básicos para el escritor(es) de la clase y el usuario(es) de la clase, entonces debe considerar usar tanto la abstracción como la implementación.

 19
Author: Shef,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-06-16 09:02:33

¿Se considera mala práctica o algo así la falla en implementar una interfaz en un hijo, que es implementada por un padre?

El hijo siempre implementa la interfaz, no puede ir por ahí con esto.

No tengo idea si eso es una mala práctica o algo así. Yo diría que es una característica del idioma.

¿Hay algún inconveniente técnico en omitir la implementación en el niño?

No se puede probar el reflejo de la clase abstracta por tener la interfaz, por ejemplo.

Sin embargo, las clases abstractas ya son una interfaz, por lo que técnicamente ellos mismos no necesitan realmente la interfaz, pero puede hacerlo para mantener las cosas fluidas dentro de la herencia.

 0
Author: hakre,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-06-16 08:45:35

Bueno, yo también estaba confundido, pero creo que debería usar el último, Tiene razón, Si implementa la interfaz en la clase abstracta, entonces no hay necesidad de escribir la interfaz, puede escribir el método en la interfaz todo en abstracto como métodos abstractos, porque extenderá la clase abstracta lo que sea, y tendrá que usar la clase abstracta como un tipo param cuando use la clase en otro lugar, eso no es bueno, creo que una clase abstracta no debe usarse como un param tipo, mientras que una interfaz debe ser.

 0
Author: lvpiao,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-02-05 08:43:15

Tal vez un poco tarde para la mesa, pero veo que los comentarios anteriores no aclaran el principal malentendido que subyace a la pregunta del OP.

Así que las preguntas subyacentes son:

  • ¿Por qué usamos tanto una clase Abstracta como una Interfaz en la misma línea?
  • ¿Tanto un método abstracto como una Interfaz deben declarar los mismos métodos?

Pero antes de algunas aclaraciones por qué usar cualquiera de los dos anteriores:

  • Cualquiera de ellos son utilizados por uno programador para definir el contrato (requisitos, obligaciones, limitaciones) los otros programadores tienen que obedecer cuando crean las clases concretas (y eventualmente toda la aplicación de software) basadas en clases / Interfaces abstractas desarrolladas por ese programador.
  • Una clase abstracta, a su vez, se usa para proporcionar a la clase concreta creada más tarde un modelo de métodos y estructuras de datos a través de:

    1. declaraciones de estructuras de datos (optativo),
    2. base realizaciones de métodos (y sus firmas, optativos)
    3. solo declaraciones de métodos (similar a un uso de interfaz, opcional).
  • Una interfaz se utiliza para proporcionar una clase concreta con un modelo de métodos a través de

    1. solo métodos (y sus firmas, opcionales) declaraciones.

Aquí hay un ejemplo de clases abstractas y concretas.

abstract class MyAbstractClass {

    public function foo() {
        // Base implementation of the method here.
    }

    public function bar() {
        // Base implementation of the method here.
    }

    // Effectively similar to baz() declaration within some interface:
    public abstract function baz($value);

}

class MyConcreteClass extends MyAbstractClass {

    // foo() and bar() are inherited here from MyAbstractClass.

    // baz() must be implemented or declared abstract again.
    public function baz($value) {
        // implementation.
    }

}

Entonces vienen las preguntas:

  1. ¿Por qué necesitamos una interfaz aquí?
  2. Do necesitamos una interfaz para duplicar declaraciones del mismo método?

Las respuestas:

  1. Debido al hecho de que PHP solo permite una herencia única para cada subclase (no se puede escribir class MyConcreteClass extends MyAbstractClass, MyAnotherClass {}), cuando necesitamos expandir la funcionalidad de la clase concreta más allá de la clase Abstracta ya utilizada, tenemos que declarar esta funcionalidad adicional a través de una o más Interfaces.

    Así:

    class MyConcreteClass 
        extends MyAbstractClass 
        implements MyInterface, MyAnotherInterface {
        // Methods and data implementations go here.
    }
    
  2. Como resultado de la respuesta 1, una Interfaz mejor no para duplicar una clase Abstracta declaraciones de métodos (esto es básicamente inútil). Una(s) interfaz (es) debe (n) descalificar los métodos que pueden ayudar a mejorar la funcionalidad concreta (u otra clase abstracta, por qué no) para proporcionar al programador que los utilizará con el contrato firme para cada objeto construido sobre estas clases e interfaces.

Finalmente, responda a la pregunta de OP si usar una Interfaz para una clase abstracta o para la clase concreta is:

  • usar para uno o ambos (o según sea necesario) siempre y cuando una Interfaz mejore un contrato de clase con declaraciones de nuevos métodos.
 0
Author: bob-12345,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-02 11:24:35