Aquí podría ser tu PUBLICIDAD


¿Por qué se prefieren las interfaces a las clases abstractas?

votos
34

Recientemente asistí a una entrevista y me hicieron la pregunta ¿Por qué las interfaces son preferibles a las clases abstractas?

Traté de dar algunas respuestas como:

  • Solo podemos obtener una funcionalidad Extends
  • son 100% abstractos
  • La implementación no está codificada

Me pidieron que tomara cualquiera de las API de JDBC que usas. ¿Por qué son interfaces?.

¿Puedo obtener una mejor respuesta para esto?

Publicado el 12/03/2009 a las 18:15
fuente por usuario Techmaddy
En otros idiomas...        العربية       

23 respuestas

votos
54

Esa pregunta de entrevista refleja una cierta creencia de la persona que hace la pregunta. Creo que la persona está equivocada, y por lo tanto puede ir en una de dos direcciones.

  1. Dales la respuesta que quieren.
  2. Respetuosamente no estoy de acuerdo.

La respuesta que quieren, bueno, los otros carteles los han destacado increíblemente bien. Herencia de interfaz múltiple, la herencia obliga a la clase a realizar elecciones de implementación, las interfaces se pueden cambiar más fácilmente.

Sin embargo, si crea un argumento convincente (y correcto) en su desacuerdo, entonces el entrevistador puede tomar nota. En primer lugar, resalte las cosas positivas sobre las interfaces, esto es IMPRESCINDIBLE. En segundo lugar, diría que las interfaces son mejores en muchos escenarios, pero también conducen a la duplicación de código, que es algo negativo. Si tiene una amplia gama de subclases que realizarán en gran medida la misma implementación, además de funcionalidades adicionales, es posible que desee una clase abstracta. Le permite tener muchos objetos similares con detalles de grano fino, mientras que con solo interfaces, debe tener muchos objetos distintos con código casi duplicado.

Las interfaces tienen muchos usos, y hay una razón convincente para creer que son "mejores". Sin embargo, siempre debe utilizar la herramienta correcta para el trabajo, y eso significa que no puede cancelar clases abstractas.

Respondida el 12/03/2009 a las 06:30
fuente por usuario DevinB


Aquí podría ser tu PUBLICIDAD


votos
23

En general, y esto de ninguna manera es una "regla" que deba seguirse ciegamente, la disposición más flexible es:

interface
   abstract class
       concrete class 1       
       concrete class 2

La interfaz está ahí por un par de razones:

  • una clase existente que ya se extiende puede implementar la interfaz (suponiendo que tenga control sobre el código de la clase existente)
  • una clase existente puede ser subclases y la subclase puede implementar la interfaz (suponiendo que la clase existente sea subclassable)

Esto significa que puede tomar clases preexistentes (o solo clases que DEBEN extenderse desde otra cosa) y hacer que funcionen con su código.

La clase abstracta está ahí para proporcionar todos los bits comunes para las clases concretas. La clase abstracta se extiende desde cuando está escribiendo nuevas clases o modificando las clases que desea extender (suponiendo que se extiendan desde java.lang.Object).

Siempre debe (a menos que tenga una buena razón para no hacerlo) declarar variables (instancia, clase, local y parámetros de método) como la interfaz.

Respondida el 12/03/2009 a las 06:45
fuente por usuario TofuBeer

votos
23

Solo tienes una oportunidad de herencia. Si crea una clase abstracta en lugar de una interfaz, alguien que hereda su clase tampoco puede heredar una clase abstracta diferente.

Respondida el 12/03/2009 a las 06:17
fuente por usuario Joel Coehoorn

votos
10

Clases abstractas

1.No se pueden crear instancias independientemente de sus clases derivadas. Los constructores de clases abstractas son llamados solo por sus clases derivadas.

2. Definir firmas de miembros abstractas que las clases base deben implementar.

3. Son más extensibles que las interfaces, sin romper ninguna compatibilidad de versión. Con las clases abstractas, es posible agregar miembros adicionales no absolutos que todas las clases derivadas pueden heredar.

4. Puede incluir datos almacenados en campos.

5. Permitir que los miembros (virtuales) tengan implementación y, por lo tanto, proporcionar una implementación predeterminada de un miembro a la clase derivada.

6.Derivar de una clase abstracta consume la única y única opción de clase base de una subclase.

Interfaz

1.No se puede crear una instancia.

2. La implementación de todos los miembros de la interfaz ocurre en la clase base. No es posible implementar solo algunos miembros dentro de la clase implementadora.

3. La ampliación de las interfaces con miembros adicionales rompe la compatibilidad de la versión.

4. No se pueden almacenar datos. Los campos se pueden especificar solo en las clases derivadas. La solución para esto es definir propiedades, pero sin implementación.

5. Todos los miembros son automáticamente virtuales y no pueden incluir ninguna implementación.

6. Aunque no puede aparecer una implementación predeterminada, las clases que implementan las interfaces pueden seguir derivando una de la otra.

Respondida el 12/03/2009 a las 06:25
fuente por usuario Warrior

votos
10

Puede implementar más de una interfaz, pero solo puede heredar de una sola clase

Respondida el 12/03/2009 a las 06:18
fuente por usuario Rowland Shaw

votos
7

Como devinb y otros mencionan, parece que el entrevistador muestra su ignorancia al no aceptar sus respuestas válidas.

Sin embargo, la mención de JDBC podría ser una pista. En ese caso, tal vez están solicitando los beneficios de una codificación de cliente contra una interfaz en lugar de una clase.

Por lo tanto, en lugar de respuestas perfectamente válidas como "solo se obtiene un uso de la herencia" , que están relacionadas con el diseño de clase, es posible que estén buscando una respuesta más parecida a "desacopla a un cliente de una implementación específica" .

Respondida el 12/03/2009 a las 06:46
fuente por usuario toolkit

votos
5

Las clases abstractas tienen varias trampas potenciales. Por ejemplo, si anula un método, super()no se llama al método a menos que lo llame explícitamente. Esto puede causar problemas para las clases anuladas mal implementadas. Además, hay problemas potenciales con el equals()uso de la herencia.

El uso de interfaces puede alentar el uso de la composición cuando desee compartir una implementación. La composición es a menudo una mejor forma de reutilizar otros objetos, ya que es menos frágil. La herencia se usa en exceso fácilmente o se usa para fines incorrectos.

Definir una interfaz es una forma muy segura de definir cómo se supone que debe actuar un objeto, sin arriesgarse a la fragilidad que puede surgir al extender otra clase, abstracta o no.

Además, como mencionas, solo puedes extender una clase a la vez, pero puedes implementar tantas interfaces como desees.

Respondida el 12/03/2009 a las 06:23
fuente por usuario Eddie

votos
4

Las clases abstractas se usan cuando heredas la implementación , las interfaces se usan cuando heredas la especificación . Los estándares JDBC establecen que "Una conexión debe hacer esto ". Esa es la especificación.

Respondida el 15/03/2009 a las 12:25
fuente por usuario paulmurray

votos
3

Respetuosamente no estoy de acuerdo con la mayoría de los carteles anteriores (lo siento, modélame si quieres :-))


Primero, la respuesta de "una sola superclase" es coja. Cualquiera que me diera esa respuesta en una entrevista sería contestado rápidamente con "C ++ existía antes de que Java y C ++ tuvieran múltiples súper clases. ¿Por qué crees que James Gosling solo permitió una superclase para Java?"

Comprenda la filosofía detrás de su respuesta; de lo contrario, usted es un brindis (al menos si lo entrevisto).


En segundo lugar, las interfaces tienen múltiples ventajas sobre las clases abstractas, especialmente cuando se diseñan interfaces. El más grande es no tener una estructura de clase particular impuesta a la persona que llama de un método. No hay nada peor que tratar de usar una llamada de método que exija una estructura de clase particular. Es doloroso y embarazoso. Usando una interfaz cualquier cosa puede pasarse al método con un mínimo de expectativas.

Ejemplo:

public void foo(Hashtable bar);

vs.

public void foo(Map bar);

Para el primero, la persona que llama siempre tomará su estructura de datos existente y la incluirá en un nuevo Hashtable.


En tercer lugar, las interfaces permiten que los métodos públicos en los ejecutores de la clase concreta sean "privados". Si el método no se declara en la interfaz, entonces el método no puede ser utilizado (o mal utilizado) por las clases que no tienen ningún negocio que utilice el método. Lo que me lleva al punto 4 ...


En cuarto lugar, las interfaces representan un contrato mínimo entre la clase implementadora y el que llama. Este contrato mínimo especifica exactamente cómo el implementador de hormigón espera ser utilizado y no más. La clase de llamada no puede usar ningún otro método no especificado por el "contrato" de la interfaz. El nombre de la interfaz en uso también saborea la expectativa del desarrollador de cómo deberían usar el objeto. Si un desarrollador se pasa a

public interface FragmentVisitor {
    public void visit(Node node);
}

El desarrollador sabe que el único método que pueden llamar es el método de visita. No se distraen con los métodos brillantes y brillantes de la clase concreta con los que no deben meterse.


Por último, las clases abstractas tienen muchos métodos que realmente solo están presentes para las subclases que se utilizarán. Por lo tanto, las clases abstractas tienden a parecer un poco desastrosas para el desarrollador externo, no hay una guía sobre qué métodos están destinados a ser utilizados por código externo.

Sí, por supuesto, algunos de esos métodos se pueden proteger. Sin embargo, lamentablemente los métodos protegidos también son visibles para otras clases en el mismo paquete. Y si el método de una clase abstracta implementa una interfaz, el método debe ser público.

Sin embargo, al utilizar las interfaces, todas estas entrañas que están colgando cuando se mira la clase abstracta o la clase concreta se guardan de forma segura.


Sí, sé que, por supuesto, el desarrollador puede usar algún conocimiento "especial" para enviar un objeto a otra interfaz más amplia o a la propia clase concreta. Pero tal elenco viola el contrato esperado, y el desarrollador debe ser abofeteado con un salmón.

Respondida el 15/03/2009 a las 08:34
fuente por usuario Pat

votos
3

"¿Por qué se prefieren las interfaces a las clases abstractas?"

Las otras publicaciones han hecho un excelente trabajo al observar las diferencias entre interfaces y clases abstractas, por lo que no voy a duplicar esos pensamientos.

Pero mirando la pregunta de la entrevista, la mejor pregunta es realmente "¿ Cuándo deberían preferirse las interfaces a las clases abstractas?" (y viceversa).

Al igual que con la mayoría de las construcciones de programación, están disponibles por una razón y las declaraciones absolutas como la de la pregunta de la entrevista tienden a pasar por alto eso. En cierto modo, me recuerda toda la afirmación que solías leer con respecto a la afirmación goto en C. "Nunca deberías usar goto , revela malas habilidades de codificación". Sin embargo, goto siempre tuvo sus usos apropiados.

Respondida el 12/03/2009 a las 07:01
fuente por usuario Neal Stublen

votos
3

Cuando usas clases abstractas, creas un acoplamiento entre la subclase y la clase base. Este acoplamiento a veces puede hacer que el código sea realmente difícil de cambiar, especialmente a medida que aumenta la cantidad de subclases. Las interfaces no tienen este problema.

También solo tiene una herencia, por lo que debe asegurarse de usarla por las razones adecuadas.

Respondida el 12/03/2009 a las 06:18
fuente por usuario krosenvold

votos
2

Esta es la cuestión de la "herencia múltiple". Podemos "se extiende" no más de una clase de abstarct de una sola vez a través de otra clase, pero en las interfaces, podemos "aplicar" múltiples interfaces en una sola clase. Así, a pesar de Java no proporciona la herencia múltiple en general, pero mediante el uso de las interfaces que puede incorporar la propiedad herencia multiplt en ella.

¡¡¡Espero que esto ayude!!!

Respondida el 03/12/2012 a las 06:05
fuente por usuario Marco167

votos
2

Si piensan que X es mejor que YI no estar preocupado por conseguir el trabajo, no me gustaría trabajar para alguien que me obligó a un diseño sobre otro porque se les dijo interfaces son los mejores. Ambos son buenos dependiendo de la situación, de lo contrario ¿por qué el lenguaje de optar por añadir clases abstractas? Sin duda, los diseñadores del lenguaje son más inteligentes que yo.

Respondida el 30/07/2011 a las 05:12
fuente por usuario scott

votos
1

la interfaz no se sustituye la clase abstracta .

Preferir

Interfaz: Implementar un contrato de múltiples objetos no relacionados

clase abstracta: Para poner en práctica el mismo o diferente comportamiento entre varios objetos relacionados


Referirse a esta pregunta SE relacionados para casos de uso tanto de interfaz y clase abstracta

Interface vs Abstract Clase (OO general)

Caso de uso:

Si usted tiene que utilizar Template_method patrón, no se puede lograr con la interfaz. Clase abstracta debe ser elegido para lograrlo.

Si usted tiene que poner en práctica una capacidad para muchos objetos unrleated, clase abstracta no servir al propósito y tienes que elegir la interfaz .

Respondida el 07/11/2016 a las 03:03
fuente por usuario Ravindra babu

votos
1

Hay una razón no mencionada por lo anterior.

Puede decorar cualquier interfaz fácilmente con java.lang.reflect.Proxy, lo que le permite agregar código personalizado en tiempo de ejecución a cualquier método en la interfaz dada. Es muy poderoso

Consulte http://tutorials.jenkov.com/java-reflection/dynamic-proxies.html para obtener un tutorial.

Respondida el 12/03/2009 a las 10:27
fuente por usuario Thorbjørn Ravn Andersen

votos
1

interfaces son una forma más limpia de escribir una clase puramente abstracta. Puede ver que la implementación no se ha infiltrado (por supuesto, es posible que desee hacerlo en ciertas etapas de mantenimiento, lo que hace que las interfaces sean malas). Eso es todo. Casi no hay diferencia discernible para el código del cliente.

JDBC es un mal ejemplo. Pregunte a cualquiera que haya intentado implementar las interfaces y mantenga el código entre las versiones de JDK. JAX-WS es aún peor, al agregar métodos en las versiones de actualización.

Existen diferencias técnicas, como la capacidad de multiplicar la interfaz "heredar". Eso tiende a ser el resultado de un diseño confuso. En casos excepcionales, puede ser útil tener una jerarquía de implementación que sea diferente de la jerarquía de la interfaz.

En el lado negativo de las interfaces, el compilador no puede detectar algunos moldes / instanceofs imposibles .

Respondida el 12/03/2009 a las 06:34
fuente por usuario Tom Hawtin - tackline

votos
0

Depende de su requerimiento y poder de implementación, que es muy importante. Tienes tantas respuestas con respecto a esta pregunta. Lo que pienso sobre esta pregunta es que la clase abstracta es la evolución si API. Puede definir su definición de función futura en clase abstracta, pero no necesita la implementación de todas las funciones en su clase principal, pero con la interfaz no puede hacer esto.

Respondida el 25/11/2009 a las 02:03
fuente por usuario Pankaj

votos
0

Las clases abstractas ofrecen una forma de definir una plantilla de comportamiento, donde los complementos del usuario en los detalles.

Un buen ejemplo es SwingWorker de Java 6 . Define un marco para hacer algo en segundo plano, que requiere que el usuario defina doInBackground () para la tarea real.

Amplié esta clase de modo que creara automáticamente una barra de progreso emergente. Anulé done (), para controlar la eliminación de esta ventana emergente, pero luego proporcioné un nuevo punto de anulación, que permite al usuario definir opcionalmente lo que sucede después de que desaparece la barra de progreso.

public abstract class ProgressiveSwingWorker<T, V> extends SwingWorker<T, V> {

    private JFrame progress;

    public ProgressiveSwingWorker(final String title, final String label) {
        SwingUtilities.invokeLater(new Runnable() {
            @SuppressWarnings("serial")
            @Override
            public void run() {
                progress = new JFrame() {{
                    setLayout(new MigLayout("","[grow]"));
                    setTitle(title);
                    add(new JLabel(label));
                    JProgressBar bar = new JProgressBar();
                    bar.setIndeterminate(true);
                    add(bar);
                    pack();
                    setLocationRelativeTo(null);
                    setVisible(true);
                }};
            }
        });
    }

    /**
     * This method has been marked final to secure disposing of the progress dialog. Any behavior
     * intended for this should be put in afterProgressBarDisposed.
     */
    @Override
    protected final void done() {
        progress.dispose();
        try {
            afterProgressBarDisposed(get());
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }

    protected void afterProgressBarDisposed(T results) {
    }

}

El usuario todavía tiene el requisito de proporcionar la implementación de doInBackground () . Sin embargo, también pueden tener un comportamiento de seguimiento, como abrir otra ventana, mostrar un JOptionPane con resultados o simplemente no hacer nada.

Para usarlo:

new ProgressiveSwingWorker<DataResultType, Object>("Editing some data", "Editing " + data.getSource()) {

    @Override
    protected DataResultType doInBackground() throws Exception {
        return retrieve(data.getSource());
    }

    @Override
    protected void afterProgressBarDisposed(DataResultType results) {
        new DataEditor(results);
    }

}.execute();

Esto muestra cómo una clase abstracta puede proporcionar una operación con plantillas, ortogonal al concepto de interfaces que definen un contrato API.

Respondida el 21/10/2009 a las 02:28
fuente por usuario gregturn

votos
0

Me pidieron que tomara cualquiera de las API de JDBC que usas. "¿Por qué son interfaces?".

Mi respuesta a esta pregunta específica es:

SUN no sabe cómo implementarlos o qué poner en la implementación. Depende de los proveedores de servicios / proveedores de db poner su lógica en la implementación.

El diseño de JDBC tiene relación con el patrón Bridge, que dice "Desacople una abstracción de su implementación para que ambas puedan variar de forma independiente".

Eso significa que la jerarquía de interfaces de api de JDBC puede evolucionar independientemente de la jerarquía de implementación que proporciona o usa un proveedor de jdbc.

Respondida el 13/04/2009 a las 10:47
fuente por usuario Manoj

votos
0

Bueno, sugeriría que la pregunta en sí misma debería ser reformulada. Las interfaces son principalmente contratos que adquiere una clase, la implementación de ese contrato en sí variará. Una clase abstracta generalmente contendrá alguna lógica por defecto y sus clases secundarias agregarán algo más de lógica. Diría que la respuesta a las preguntas se basa en el problema del diamante. Java evita la herencia múltiple para evitarlo. ( http://en.wikipedia.org/wiki/Diamond_problem ).

Respondida el 12/03/2009 a las 10:05
fuente por usuario Yorch

votos
0

Usted define interfaces cuando solo requiere que algún objeto implemente ciertos métodos, pero no le importa su pedigrí. Entonces alguien puede extender una clase existente para implementar una interfaz, sin afectar el comportamiento previamente existente de esa clase.

Es por eso que JDBC es todas las interfaces; realmente no le importa qué clases se usan en una implementación JDBC, solo necesita que cualquier implementación JDBC tenga el mismo comportamiento esperado. Internamente, el controlador Oracle JDBC puede ser muy diferente del controlador PostgreSQL, pero eso es irrelevante para usted. Uno puede tener que heredar de algunas clases internas que los desarrolladores de la base de datos ya tenían, mientras que otra puede estar completamente desarrollada desde cero, pero eso no es importante para usted siempre y cuando ambas implementen las mismas interfaces para que pueda comunicarse con una o otro sin conocer el funcionamiento interno de ninguno.

Respondida el 12/03/2009 a las 06:50
fuente por usuario Chochos

votos
0

Porque las interfaces no lo están forzando a ingresar a una jerarquía de herencia.

Respondida el 12/03/2009 a las 06:27
fuente por usuario Marko

votos
0

Puede implementar múltiples interfaces, pero particularmente con c # no puede tener múltiples herencias

Respondida el 12/03/2009 a las 06:19
fuente por usuario user68610


Aquí podría ser tu PUBLICIDAD