En una de mis entrevistas, me pidieron que explicara la diferencia entre una interfaz y una clase abstracta .
Aquí está mi respuesta:
Los métodos de una interfaz Java son implícitamente abstractos y no pueden tener implementaciones. Una clase abstracta de Java puede tener métodos de instancia que implementen un comportamiento predeterminado.
Las variables declaradas en una interfaz Java son por defecto finales. Una clase abstracta puede contener variables no finales.
Los miembros de una interfaz Java son públicos de forma predeterminada. Una clase abstracta de Java puede tener los sabores habituales de los miembros de la clase como privados, protegidos, etc.
Se debe implementar una interfaz Java utilizando la palabra clave "implementos"; Una clase abstracta de Java debe ampliarse con la palabra clave "extiende".
Una interfaz solo puede extender otra interfaz Java, una clase abstracta puede extender otra clase Java e implementar múltiples interfaces Java.
Una clase Java puede implementar múltiples interfaces pero solo puede extender una clase abstracta.
Sin embargo, el entrevistador no estaba satisfecho y me dijo que esta descripción representaba " conocimiento de libros ".
Me pidió una respuesta más práctica, explicando cuándo elegiría una clase abstracta sobre una interfaz, usando ejemplos prácticos .
¿Qué hice mal?
fuente
Respuestas:
Primero te daré un ejemplo:
Supongamos que tiene 3 bases de datos en su aplicación. Luego, todas y cada una de las implementaciones de esa base de datos deben definir los 2 métodos anteriores:
Pero, ¿qué
encryptPassword()
pasa si no depende de la base de datos y es lo mismo para cada clase? Entonces lo anterior no sería un buen enfoque.En cambio, considere este enfoque:
Ahora, en cada clase secundaria, solo necesitamos implementar un método: el método que depende de la base de datos.
fuente
Nada es perfecto en este mundo. Es posible que hayan estado esperando un enfoque más práctico.
Pero después de su explicación, puede agregar estas líneas con un enfoque ligeramente diferente.
Las interfaces son reglas (reglas porque debes darles una implementación que no puedes ignorar o evitar, para que se impongan como reglas) que funciona como un documento de entendimiento común entre varios equipos en el desarrollo de software.
Las interfaces dan la idea de lo que se debe hacer, pero no de cómo se hará. Entonces, la implementación depende completamente del desarrollador siguiendo las reglas dadas (significa la firma de los métodos).
Las clases abstractas pueden contener declaraciones abstractas, implementaciones concretas o ambas.
Las declaraciones abstractas son como reglas a seguir y las implementaciones concretas son como pautas (puede usarlo tal como está o puede ignorarlo anulando y dándole su propia implementación).
Además, qué métodos con la misma firma pueden cambiar el comportamiento en un contexto diferente se proporcionan como declaraciones de interfaz como reglas para implementar en consecuencia en diferentes contextos.
Editar: Java 8 facilita la definición de métodos predeterminados y estáticos en la interfaz.
Ahora, cuando una clase implementará SomeInterface, no es obligatorio proporcionar implementación para los métodos predeterminados de interfaz.
Si tenemos otra interfaz con los siguientes métodos:
Java no permite extender varias clases porque da como resultado el "problema del diamante", donde el compilador no puede decidir qué método de superclase usar. Con los métodos predeterminados, también surgirá el problema del diamante para las interfaces. Porque si una clase está implementando ambos
y no implementa el método predeterminado común, el compilador no puede decidir cuál elegir. Para evitar este problema, en Java 8 es obligatorio implementar métodos predeterminados comunes de diferentes interfaces. Si alguna clase está implementando ambas interfaces anteriores, debe proporcionar la implementación del método defaultMethod (), de lo contrario, el compilador arrojará un error de tiempo de compilación.
fuente
Hiciste un buen resumen de las diferencias prácticas en el uso y la implementación, pero no dijiste nada sobre la diferencia de significado.
Una interfaz es una descripción del comportamiento que tendrá una clase implementadora. La clase implementadora asegura que tendrá estos métodos que se pueden usar. Básicamente es un contrato o una promesa que la clase tiene que hacer.
Una clase abstracta es una base para diferentes subclases que comparten un comportamiento que no necesita ser creado repetidamente. Las subclases deben completar el comportamiento y tener la opción de anular el comportamiento predefinido (siempre que no esté definido como
final
oprivate
).Encontrará buenos ejemplos en el
java.util
paquete que incluye interfaces comoList
y clases abstractas como lasAbstractList
que ya implementan la interfaz. La documentación oficial describe loAbstractList
siguiente:fuente
abstract
palabra clave, es decir, cuando un compilador ve esto, saben, la siguiente información está incompleta y necesita implementación . Las interfaces siempre están incompletas, pero las clases abstractas son abstractas porque tenían que tenerincomplete (abstract)
métodos.Una interfaz consta de variables singleton (final estático público) y métodos abstractos públicos. Normalmente preferimos usar una interfaz en tiempo real cuando sabemos qué hacer pero no sabemos cómo hacerlo .
Este concepto se puede entender mejor con un ejemplo:
Considere una clase de pago. El pago puede hacerse de muchas maneras, como PayPal, tarjeta de crédito, etc. Por lo tanto, normalmente tomamos el pago como nuestra interfaz que contiene un
makePayment()
método y CreditCard y PayPal son las dos clases de implementación.En el ejemplo anterior, CreditCard y PayPal son dos clases / estrategias de implementación. Una interfaz también nos permite el concepto de herencia múltiple en Java que no puede ser realizado por una clase abstracta.
Elegimos una clase abstracta cuando hay algunas características para las que sabemos qué hacer y otras características que sabemos cómo realizar .
Considere el siguiente ejemplo:
Si agregamos métodos (concretos / abstractos) en el futuro a una clase abstracta dada, entonces la clase de implementación no necesitará cambiar su código. Sin embargo, si agregamos métodos en una interfaz en el futuro, debemos agregar implementaciones a todas las clases que implementaron esa interfaz, de lo contrario se producen errores de tiempo de compilación.
Existen otras diferencias, pero estas son importantes y pueden haber sido lo que su entrevistador esperaba. Espero que esto haya sido útil.
fuente
interface
yabstract class
.Diferencia entre la clase Abstact y la interfaz
Métodos predeterminados de interfaz en Java 8
Método estático de interfaz Java
Interfaces funcionales Java
Clases abstractas versus interfaces en Java 8
Diferencia conceptual:
Las clases abstractas son válidas para implementaciones esqueléticas (es decir, parciales) de interfaces, pero no deberían existir sin una interfaz coincidente.
Entonces, cuando las clases abstractas se reducen efectivamente para que sean de baja visibilidad, las implementaciones esqueléticas de interfaces, ¿pueden los métodos predeterminados eliminar esto también? Decididamente: ¡No! La implementación de interfaces casi siempre requiere algunas o todas esas herramientas de construcción de clases de las que carecen los métodos predeterminados. Y si alguna interfaz no lo hace, es claramente un caso especial, que no debería llevarlo por mal camino.
Métodos predeterminados de interfaz en Java 8
Java 8 presenta la nueva característica " Método predeterminado " o (Métodos de defensa), que permite al desarrollador agregar nuevos métodos a las Interfaces sin interrumpir la implementación existente de estas Interfaces. Proporciona flexibilidad para permitir que la interfaz defina la implementación que se usará por defecto en la situación en la que una clase concreta no puede proporcionar una implementación para ese método.
Consideremos un pequeño ejemplo para entender cómo funciona:
La siguiente clase se compilará correctamente en Java JDK 8,
Si crea una instancia de OldInterfaceImpl:
Método predeterminado
Los métodos predeterminados se pueden proporcionar a una interfaz sin afectar las clases de implementación, ya que incluye una implementación. Si cada método agregado en una interfaz definida con implementación no afecta a ninguna clase de implementación. Una clase implementadora puede anular la implementación predeterminada proporcionada por la interfaz.
Cuando ampliamos una interfaz que contiene un método predeterminado, podemos realizar lo siguiente,
Error de compilación del método ForEach resuelto con el método predeterminado
Para Java 8, las colecciones JDK se han extendido y cada método se agrega a toda la colección (que funciona junto con lambdas). De manera convencional, el código se ve a continuación,
Dado que este resultado cada clase de implementación con errores de compilación, por lo tanto, se agrega un método predeterminado con una implementación requerida para que la implementación existente no deba cambiarse.
La interfaz Iterable con el método predeterminado está a continuación,
Se ha utilizado el mismo mecanismo para agregar Stream en la interfaz JDK sin romper las clases de implementación.
Método predeterminado y problemas de ambigüedad de herencia múltiple
Dado que Java Class puede implementar múltiples interfaces y cada interfaz puede definir un método predeterminado con la misma firma de método, por lo tanto, los métodos heredados pueden entrar en conflicto entre sí.
Considere el siguiente ejemplo,
El código anterior no se compilará con el siguiente error,
Para arreglar esta clase, necesitamos proporcionar la implementación del método predeterminado:
Además, si queremos invocar la implementación predeterminada proporcionada por cualquiera de las super interfaces en lugar de nuestra propia implementación, podemos hacerlo de la siguiente manera,
Podemos elegir cualquier implementación predeterminada o ambas como parte de nuestro nuevo método.
Puntos importantes sobre los métodos predeterminados de la interfaz de Java:
Enlace de recursos:
Método estático de interfaz Java
Método estático de interfaz Java, ejemplo de código, método estático frente a método predeterminado
El método estático de la interfaz Java es similar al método predeterminado, excepto que no podemos anularlos en las clases de implementación. Esta característica nos ayuda a evitar resultados no deseados en caso de una implementación deficiente en las clases de implementación. Veamos esto con un simple ejemplo.
Ahora veamos una clase de implementación que tiene el método isNull () con una implementación deficiente.
Tenga en cuenta que isNull (String str) es un método de clase simple, no anula el método de interfaz. Por ejemplo, si agregaremos la anotación @Override al método isNull (), se producirá un error del compilador.
Ahora, cuando ejecutaremos la aplicación, obtendremos el siguiente resultado.
Si hacemos que el método de interfaz sea estático a predeterminado, obtendremos el siguiente resultado.
El método estático de la interfaz Java es visible solo para los métodos de interfaz, si eliminamos el método isNull () de la clase MyDataImpl, no podremos usarlo para el objeto MyDataImpl. Sin embargo, como otros métodos estáticos, podemos usar métodos estáticos de interfaz usando el nombre de clase. Por ejemplo, una declaración válida será:
Puntos importantes sobre el método estático de la interfaz de Java:
Interfaces funcionales Java
Antes de concluir la publicación, me gustaría proporcionar una breve introducción a las interfaces funcionales. Una interfaz con exactamente un método abstracto se conoce como interfaz funcional.
Se
@FunctionalInterface
ha introducido una nueva anotación para marcar una interfaz como Interfaz funcional.@FunctionalInterface
La anotación es una facilidad para evitar la adición accidental de métodos abstractos en las interfaces funcionales. Es opcional pero es una buena práctica usarlo.Las interfaces funcionales son una característica muy esperada y muy buscada de Java 8 porque nos permite usar expresiones lambda para instanciarlas. Se agrega un nuevo paquete java.util.function con un montón de interfaces funcionales para proporcionar tipos de destino para expresiones lambda y referencias de métodos. Examinaremos interfaces funcionales y expresiones lambda en las próximas publicaciones.
Ubicación del recurso:
fuente
Todas sus declaraciones son válidas excepto su primera declaración (después del lanzamiento de Java 8):
Desde la página de documentación :
Métodos predeterminados:
Una interfaz puede tener métodos predeterminados , pero son diferentes a los métodos abstractos en clases abstractas.
Cuando extiende una interfaz que contiene un método predeterminado, puede hacer lo siguiente:
abstract
.Métodos Estáticos:
Además de los métodos predeterminados, puede definir métodos estáticos en las interfaces. (Un método estático es un método asociado con la clase en la que se define en lugar de con cualquier objeto. Cada instancia de la clase comparte sus métodos estáticos).
Esto le facilita la organización de métodos auxiliares en sus bibliotecas;
Código de ejemplo de la página de documentación sobre
interface
tenerstatic
ydefault
métodos.Use las siguientes pautas para elegir si desea usar una interfaz o una clase abstracta.
Interfaz:
Clase abstracta:
Compartir código entre varias clases estrechamente relacionadas. Establece es una relación.
Comparta el estado común entre clases relacionadas (el estado puede modificarse en clases concretas)
Artículos Relacionados:
Interfaz vs clase abstracta (OO general)
Implementa vs extiende: ¿Cuándo usarlo? ¿Cual es la diferencia?
Al seguir estos ejemplos, puede comprender que
Las clases no relacionadas pueden tener capacidades a través de la interfaz, pero las clases relacionadas cambian el comportamiento mediante la extensión de las clases base.
fuente
stateless
interfaz es un buen éxito. La interfaz no puede tener ningún estado (la interfaz podría tener constantes pero son finales / estáticas, por lo tanto inmutables).Su explicación parece decente, pero ¿puede parecer que lo estaba leyendo todo de un libro de texto? : - /
Lo que más me preocupa es, ¿qué tan sólido fue su ejemplo? ¿Se molestó en incluir casi todas las diferencias entre resumen e interfaces?
Personalmente, sugeriría este enlace: http://mindprod.com/jgloss/interfacevsabstract.html#TABLE
para una lista exhaustiva de diferencias ..
Espero que te ayude a ti y a todos los demás lectores en sus futuras entrevistas
fuente
Muchos desarrolladores junior cometen el error de pensar que las interfaces, las clases abstractas y concretas son pequeñas variaciones de la misma cosa, y eligen una de ellas únicamente por razones técnicas: ¿Necesito herencia múltiple? ¿Necesito algún lugar para poner métodos comunes? ¿Debo molestarme con algo más que una clase concreta? Esto está mal, y oculto en estas preguntas está el principal problema: "Yo" . Cuando escribes código para ti, por ti mismo, rara vez piensas en otros desarrolladores presentes o futuros trabajando en o con tu código.
Las interfaces y las clases abstractas, aunque aparentemente son similares desde un punto de vista técnico, tienen significados y propósitos completamente diferentes.
Resumen
Una interfaz define un contrato que alguna implementación cumplirá para usted .
Una clase abstracta proporciona un comportamiento predeterminado que su implementación puede reutilizar.
Estos dos puntos anteriores son lo que busco cuando estoy entrevistando, y es un resumen lo suficientemente compacto. Sigue leyendo para más detalles.
Resumen alternativo
Por ejemplo
Para decirlo de otra manera: una clase concreta hace el trabajo real, de una manera muy específica. Por ejemplo, un
ArrayList
usa un área contigua de memoria para almacenar una lista de objetos de manera compacta que ofrece acceso aleatorio rápido, iteración y cambios en el lugar, pero es terrible en las inserciones, eliminaciones y ocasionalmente incluso en adiciones; mientras tanto, unLinkedList
usa nodos de doble enlace para almacenar una lista de objetos, que en su lugar ofrece iteración rápida, cambios en el lugar e inserción / eliminación / adición, pero es terrible en el acceso aleatorio. Estos dos tipos de listas están optimizados para diferentes casos de uso, y es muy importante cómo los usará. Cuando intentas exprimir el rendimiento de una lista con la que estás interactuando mucho, y cuando eliges el tipo de lista, debes elegir con cuidado cuál estás creando una instancia.Por otro lado, a los usuarios de alto nivel de una lista realmente no les importa cómo se implementa realmente, y deberían estar aislados de estos detalles. Imaginemos que Java no expuso la
List
interfaz, sino que solo tenía unaList
clase concreta que en realidadLinkedList
es lo que es ahora. Todos los desarrolladores de Java habrían adaptado su código para que se ajuste a los detalles de implementación: evite el acceso aleatorio, agregue un caché para acelerar el acceso o simplemente vuelvaArrayList
a implementarlo por sí mismo, aunque sería incompatible con todos los demás códigos que realmente funcionanList
solo. Eso sería terrible ... Pero ahora imagine que los maestros de Java realmente se dan cuenta de que una lista vinculada es terrible para la mayoría de los casos de uso reales, y decidieron cambiar a una lista de matriz para su únicoList
clase disponible Esto afectaría el rendimiento de cada programa Java en el mundo, y la gente no estaría contenta con eso. Y el principal culpable es que los detalles de implementación estaban disponibles, y los desarrolladores asumieron que esos detalles son un contrato permanente en el que pueden confiar. Por eso es importante ocultar los detalles de implementación y solo definir un contrato abstracto. Este es el propósito de una interfaz: definir qué tipo de entrada acepta un método y qué tipo de salida se espera, sin exponer todas las agallas que tentarían a los programadores a ajustar su código para que se ajuste a los detalles internos que podrían cambiar con cualquier actualización futura. .Una clase abstracta está en el medio entre las interfaces y las clases concretas. Se supone que ayuda a las implementaciones a compartir código común o aburrido. Por ejemplo,
AbstractCollection
proporciona implementaciones básicasisEmpty
basadas en el tamaño es 0,contains
como iterar y comparar,addAll
como repetidoadd
, y así sucesivamente. Esto permite que las implementaciones se centren en las partes cruciales que las diferencian: cómo almacenar y recuperar datos.Otra perspectiva: API versus SPI
Las interfaces son puertas de enlace de baja cohesión entre diferentes partes del código. Permiten que las bibliotecas existan y evolucionen sin interrumpir a cada usuario de la biblioteca cuando algo cambia internamente. Se llama interfaz de programación de aplicaciones , no clases de programación de aplicaciones. En una escala más pequeña, también permiten que múltiples desarrolladores colaboren con éxito en proyectos a gran escala, separando diferentes módulos a través de interfaces bien documentadas.
Las clases abstractas son auxiliares de alta cohesión que se utilizarán al implementar una interfaz, asumiendo cierto nivel de detalles de implementación. Alternativamente, las clases abstractas se utilizan para definir SPI, interfaces de proveedor de servicios.
La diferencia entre una API y un SPI es sutil, pero importante: para una API, el foco está en quién lo usa , y para un SPI el foco está en quién lo implementa .
Agregar métodos a una API es fácil, todos los usuarios existentes de la API seguirán compilando. Agregar métodos a un SPI es difícil, ya que cada proveedor de servicios (implementación concreta) tendrá que implementar los nuevos métodos. Si se utilizan interfaces para definir un SPI, un proveedor tendrá que lanzar una nueva versión cada vez que cambie el contrato de SPI. Si se usan clases abstractas en su lugar, los nuevos métodos podrían definirse en términos de métodos abstractos existentes, o como
throw not implemented exception
resguardos vacíos , lo que al menos permitirá que una versión anterior de una implementación de servicio aún se compile y ejecute.Una nota sobre Java 8 y los métodos predeterminados
Aunque Java 8 introdujo métodos predeterminados para las interfaces, lo que hace que la línea entre las interfaces y las clases abstractas sea aún más borrosa, esto no fue para que las implementaciones puedan reutilizar el código, sino para que sea más fácil cambiar las interfaces que sirven como API y como SPI (o se usan incorrectamente para definir SPI en lugar de clases abstractas).
"Conocimiento del libro"
Los detalles técnicos proporcionados en la respuesta del OP se consideran "conocimiento del libro" porque este es generalmente el enfoque utilizado en la escuela y en la mayoría de los libros de tecnología sobre un idioma: qué es una cosa, no cómo usarlo en la práctica, especialmente en aplicaciones a gran escala. .
Aquí hay una analogía: supuse que la pregunta era:
La respuesta técnica suena así:
Todo eso es cierto, pero pierde por completo los puntos de que son dos cosas completamente diferentes, y ambas se pueden usar al mismo tiempo para diferentes propósitos, y el aspecto "hacerlo" no es lo más importante de ninguna de las dos opciones. . La respuesta carece de perspectiva, muestra una forma inmadura de pensar, mientras presenta correctamente "hechos" verdaderos.
fuente
¿Qué hay de pensar de la siguiente manera:
Entonces, cuando tienes una clase abstracta Mamíferos, una subclase Humana y una interfaz de Conducción, entonces puedes decir
Mi sugerencia es que la frase de conocimiento del libro indica que él quería escuchar la diferencia semántica entre ambos (como otros ya sugirieron aquí).
fuente
Una interfaz es un "contrato" donde la clase que implementa el contrato promete implementar los métodos. Un ejemplo en el que tuve que escribir una interfaz en lugar de una clase fue cuando estaba actualizando un juego de 2D a 3D. Tuve que crear una interfaz para compartir clases entre la versión 2D y 3D del juego.
Entonces puedo implementar los métodos basados en el entorno, sin dejar de llamarlos desde un objeto que no sabe qué versión del juego se está cargando.
public class Adventure extends JFrame implements Playable
public class Dungeon3D extends SimpleApplication implements Playable
public class Main extends SimpleApplication implements AnimEventListener, ActionListener, Playable
Típicamente, en el mundo del juego, el mundo puede ser una clase abstracta que realiza métodos en el juego:
fuente
Las clases abstractas no son pura abstracción porque su colección de métodos concretos (métodos implementados) así como métodos no implementados. Pero las interfaces son pura abstracción porque solo hay métodos no implementados, no métodos concretos.
¿Por qué clases abstractas?
¿Por qué las interfaces?
fuente
Una interfaz es como un conjunto de genes que están documentados públicamente para tener algún tipo de efecto: una prueba de ADN me dirá si los tengo, y si lo hago, puedo dar a conocer públicamente que soy un "portador" "y parte de mi comportamiento o estado se ajustará a ellos. (Pero, por supuesto, puedo tener muchos otros genes que proporcionan rasgos fuera de este alcance).
Una clase abstracta es como el ancestro muerto de una especie de un solo sexo (*): no puede ser traída a la vida, pero un descendiente vivo (es decir, no abstracto ) hereda todos sus genes.
(*) Para estirar esta metáfora, digamos que todos los miembros de la especie viven hasta la misma edad. Esto significa que todos los antepasados de un antepasado muerto también deben estar muertos, y del mismo modo, todos los descendientes de un antepasado vivo deben estar vivos.
fuente
Hago entrevistas por trabajo y también miraría desfavorablemente su respuesta (lo siento, pero soy muy honesto). Parece que has leído sobre la diferencia y revisado una respuesta, pero quizás nunca la hayas usado en la práctica.
Una buena explicación de por qué usaría cada uno puede ser mucho mejor que tener una explicación precisa de la diferencia. En última instancia, los empleadores quieren que los programadores hagan cosas que no saben, lo que puede ser difícil de demostrar en una entrevista. La respuesta que dio sería buena si solicita un trabajo técnico o de documentación pero no un rol de desarrollador.
Mucha suerte con entrevistas en el futuro.
Además, mi respuesta a esta pregunta es más sobre la técnica de la entrevista que sobre el material técnico que ha proporcionado. Quizás considere leer al respecto. https://workplace.stackexchange.com/ puede ser un excelente lugar para este tipo de cosas.
fuente
Eliges Interfaz en Java para evitar el Problema Diamante en herencia múltiple .
Si desea que su cliente implemente todos sus métodos, vaya a la interfaz. Significa que diseñas toda la aplicación en abstracto.
Eliges la clase abstracta si ya sabes lo que hay en común. Por ejemplo, tome una clase abstracta
Car
. En un nivel superior, implementa los métodos comunes de automóviles comocalculateRPM()
. Es un método común y permite que el cliente implemente su propio comportamiento comocalculateMaxSpeed()
etc. Probablemente lo habría explicado dando algunos ejemplos en tiempo real que haya encontrado en su trabajo diario.fuente
Una interfaz es puramente abstracta. No tenemos ningún código de implementación en la interfaz.
La clase abstracta contiene ambos métodos y su implementación.
haga clic aquí para ver un tutorial sobre interfaces y clases abstractas
fuente
La principal diferencia que he observado es que la clase abstracta nos proporciona un comportamiento común implementado ya y las subclases solo necesitan implementar la funcionalidad específica correspondiente a ellas. donde en cuanto a una interfaz solo especificará qué tareas deben hacerse y la interfaz no dará implementaciones. Puedo decir que especifica el contrato entre él y las clases implementadas.
fuente
Incluso me he enfrentado a la misma pregunta en múltiples entrevistas y créanme que hace su tiempo miserable convencer al entrevistador. Si inherente a todas las respuestas de arriba, entonces necesito agregar un punto clave más para hacerlo más convincente y utilizar OO en su mejor momento
En caso de que no esté planeando ninguna modificación en las reglas , para que se siga la subclase, en el futuro, vaya a la interfaz, ya que no podrá modificarla y, si lo hace, debe ir a la cambios en todas las otras subclases, mientras que, si piensa, desea reutilizar la funcionalidad, establecer algunas reglas y también hacer que se abran para modificaciones , vaya a la clase Resumen.
Piense de esta manera, ha utilizado un servicio de consumibles o ha proporcionado algún código al mundo y tiene la oportunidad de modificar algo, suponga un control de seguridad. Y si soy un consumidor del código y una mañana después de una actualización, encontrar todas las marcas de lectura en mi Eclipse, toda la aplicación está inactiva. Entonces, para evitar tales pesadillas, use Resumen sobre interfaces
Creo que esto podría convencer al entrevistador hasta cierto punto ... Felices entrevistas por delante.
fuente
Cuando intento compartir el comportamiento entre 2 clases estrechamente relacionadas, creo una clase abstracta que contiene el comportamiento común y sirve como padre para ambas clases.
Cuando intento definir un Tipo, una lista de métodos a los que el usuario de mi objeto puede recurrir de manera confiable, entonces creo una interfaz.
Por ejemplo, nunca crearía una clase abstracta con 1 subclase concreta porque las clases abstractas se tratan de compartir el comportamiento. Pero bien podría crear una interfaz con una sola implementación. El usuario de mi código no sabrá que solo hay una implementación. De hecho, en una versión futura puede haber varias implementaciones, todas las cuales son subclases de alguna nueva clase abstracta que ni siquiera existía cuando creé la interfaz.
Eso podría haber parecido un poco demasiado libro (aunque nunca lo he visto así en ningún lugar que yo recuerde). Si el entrevistador (o el OP) realmente quisiera más de mi experiencia personal al respecto, habría estado listo con anécdotas de que una interfaz ha evolucionado por necesidad y viceversa.
Una cosa más. Java 8 ahora le permite poner código predeterminado en una interfaz, difuminando aún más la línea entre las interfaces y las clases abstractas. Pero por lo que he visto, esa característica es utilizada en exceso incluso por los creadores de las bibliotecas centrales de Java. Esa característica se agregó, y con razón, para permitir extender una interfaz sin crear incompatibilidad binaria. Pero si está creando un nuevo tipo definiendo una interfaz, entonces la interfaz debe ser SOLO una interfaz. Si también desea proporcionar un código común, haga una clase auxiliar (abstracta o concreta). No esté abarrotando su interfaz desde el principio con la funcionalidad que desee cambiar.
fuente
La diferencia básica entre la interfaz y la clase abstracta es que la interfaz admite herencia múltiple, pero no la clase abstracta.
En la clase abstracta también puede proporcionar todos los métodos abstractos como la interfaz.
¿Por qué se requiere clase abstracta?
En algunos escenarios, mientras procesa la solicitud del usuario, la clase abstracta no sabe qué intención del usuario. En ese escenario, definiremos un método abstracto en la clase y le preguntaremos al usuario quién extiende esta clase, por favor proporcione su intención en el método abstracto. En este caso las clases abstractas son muy útiles.
¿Por qué se requiere interfaz?
Digamos que tengo un trabajo que no tengo experiencia en esa área. Ejemplo, si quieres construir un edificio o presa, ¿qué harás en ese escenario?
Aquí no me preocupo por la lógica de cómo construyeron. El objeto final satisfizo mis requisitos o no, ese es solo mi punto clave.
Aquí sus requisitos llamados interfaz y constructores se llaman implementador.
fuente
En pocas palabras, respondería de esta manera:
Las clases abstractas pueden tratarse como algo entre estos dos casos (presenta algún estado pero también obliga a definir un comportamiento), una clase completamente abstracta es una interfaz (este es un desarrollo adicional de clases que consisten en métodos virtuales solo en C ++ como hasta donde sé de su sintaxis).
Por supuesto, a partir de Java 8, las cosas cambiaron ligeramente, pero la idea sigue siendo la misma.
Supongo que esto es suficiente para una entrevista típica de Java, si no te están entrevistando a un equipo compilador.
fuente
Por lo que entiendo, una interfaz, que se compone de variables finales y métodos sin implementaciones, es implementada por una clase para obtener un grupo de métodos o métodos que están relacionados entre sí. Por otro lado, una clase abstracta, que puede contener variables y métodos no finales con implementaciones, generalmente se usa como una guía o como una superclase de la cual todas las clases relacionadas o similares heredan. En otras palabras, una clase abstracta contiene todos los métodos / variables que comparten todas sus subclases.
fuente
¡En clase abstracta, puede escribir la implementación predeterminada de métodos! Pero en la interfaz no puedes. Básicamente, en la interfaz existen métodos virtuales puros que deben ser implementados por la clase que implementa la interfaz.
fuente
Sí, sus respuestas fueron técnicamente correctas, pero cuando se equivocó no les mostró que comprende las ventajas y desventajas de elegir una sobre la otra. Además, probablemente estaban preocupados / asustados por la compatibilidad de su base de código con las actualizaciones en el futuro. Este tipo de respuesta puede haber ayudado (además de lo que dijo):
¡Buena suerte en tu próxima entrevista!
fuente
Intentaré responder usando un escenario práctico para mostrar la distinción entre los dos.
Las interfaces vienen con carga útil cero, es decir, no se debe mantener ningún estado y, por lo tanto, son una mejor opción para simplemente asociar un contrato (capacidad) con una clase.
Por ejemplo, supongamos que tengo una clase de Tarea que realiza alguna acción, ahora para ejecutar una tarea en un subproceso separado, realmente no necesito extender la clase de subproceso. Una mejor opción es hacer que la Tarea implemente la interfaz Ejecutable (es decir, implemente su método run () ) y luego pasar el objeto de esta clase de Tarea a una instancia de Thread y llamar a su método start ().
Bueno, técnicamente eso fue posible, pero en lo que respecta al diseño, esa habría sido una mala elección, ya que:
En otras palabras, la clase Task necesitaba una capacidad para ejecutarse en un subproceso que logró mediante la implementación de versos de interfaz Runnable que extendían la clase Thread que lo convertiría en un subproceso.
Descargo de responsabilidad: sigue un ejemplo tonto, trate de no juzgar :-P
Ahora se te ha dado la opción de ser GodLike, pero puedes elegir ser solo Perdonador (es decir, no GodLike) y hacer:
O puede elegir ser Dios y hacer:
La PS con interfaz java 8 también puede tener métodos estáticos y predeterminados (implementación reemplazable) y, por lo tanto, la diferencia de interfaz en blanco y negro y la clase abstracta se reducen aún más.
fuente
Casi todo parece estar cubierto aquí ya. Agregando solo un punto más sobre la implementación práctica de la
abstract
clase:fuente
hmm, ahora la gente tiene un enfoque práctico hambriento, tienes toda la razón, pero la mayoría de los entrevistadores se ve según su requisito actual y quiere un enfoque práctico.
después de terminar tu respuesta, debes saltar al ejemplo:
Resumen:
Por ejemplo, tenemos una función salarial que tiene algunos parámetros comunes a todos los empleados. entonces podemos tener una clase abstracta llamada CTC con cuerpo de método parcialmente definido y se extenderá por todo tipo de empleado y se redefinirá según sus beneficios adicionales. Para la funcionalidad común.
Interfaz
La interfaz en Java permite tener funcionalidad interfcae sin extender esa y debe ser claro con la implementación de la firma de funcionalidad que desea introducir en su aplicación. te obligará a tener una definición. Para diferentes funcionalidades.
puede tener una actividad tan forzada con la clase abstracta también mediante métodos definidos como abstractos, ahora una clase que extiende la clase abstracta recuerda una abstracta hasta que anule esa función abstracta.
fuente
Por lo que entiendo y cómo me acerco,
La interfaz es como una especificación / contrato, cualquier clase que implemente una clase de interfaz debe implementar todos los métodos definidos en la clase abstracta (excepto los métodos predeterminados (introducidos en Java 8))
Mientras que defino un resumen de clase cuando sé la implementación requerida para algunos métodos de la clase y algunos métodos aún no sé cuál será la implementación (podríamos conocer la firma de la función pero no la implementación). Hago esto para que más adelante en la parte de desarrollo, cuando sé cómo se implementarán estos métodos, pueda extender esta clase abstracta e implementar estos métodos.
Nota: No puede tener cuerpo de función en métodos de interfaz a menos que el método sea estático o predeterminado.
fuente
Creo que lo que el entrevistador intentaba llegar era probablemente la diferencia entre la interfaz y la implementación.
La interfaz, no una interfaz Java, sino "interfaz" en términos más generales, a un módulo de código es, básicamente, el contrato realizado con el código del cliente que utiliza la interfaz.
La implementación de un módulo de código es el código interno que hace que el módulo funcione. A menudo, puede implementar una interfaz particular de más de una manera diferente, e incluso cambiar la implementación sin que el código del cliente se dé cuenta del cambio.
Una interfaz Java solo debe usarse como una interfaz en el sentido genérico anterior, para definir cómo se comporta la clase en beneficio del código del cliente que usa la clase, sin especificar ninguna implementación. Por lo tanto, una interfaz incluye firmas de métodos (los nombres, los tipos de retorno y las listas de argumentos) para los métodos que se espera que sean invocados por el código del cliente, y en principio debería tener un montón de Javadoc para cada método que describa qué hace ese método. La razón más convincente para usar una interfaz es si planea tener múltiples implementaciones diferentes de la interfaz, quizás seleccionando una implementación dependiendo de la configuración de implementación.
Una clase abstracta de Java, por el contrario, proporciona una implementación parcial de la clase, en lugar de tener el propósito principal de especificar una interfaz. Debe usarse cuando varias clases comparten código, pero cuando también se espera que las subclases proporcionen parte de la implementación. Esto permite que el código compartido aparezca en un solo lugar, la clase abstracta, a la vez que deja en claro que partes de la implementación no están presentes en la clase abstracta y se espera que sean proporcionadas por subclases.
fuente
su respuesta es correcta, pero el entrevistador necesita que lo diferencie de acuerdo con la perspectiva de la ingeniería de software, no de acuerdo con los detalles de Java.
Palabras simples:
Una interfaz es como la interfaz de una tienda, todo lo que se muestra en él debe estar allí en la tienda, por lo que cualquier método en la interfaz debe implementarse en la clase concreta. Ahora, ¿qué pasa si algunas clases comparten algunos métodos exactos y varían en otros? Supongamos que la interfaz se trata de una tienda que contiene dos cosas y supongamos que tenemos dos tiendas que contienen equipo deportivo pero una tiene ropa extra y la otra tiene zapatos extra. Entonces, lo que debe hacer es crear una clase abstracta para Sport que implemente el método Sports y deje el otro método sin implementar. La clase abstracta aquí significa que esta tienda no existe en sí misma, pero es la base para otras clases / tiendas. De esta forma, está organizando el código, evitando errores de replicación del código, unificando el código y garantizando la reutilización por parte de alguna otra clase.
fuente