2010-05-15 20 views
7

clase abstracta que estoy leyendo el libro - Hadoop: The Definitive Guideinterfaz Java y emisión

En el capítulo 2 (página 25), se menciona "La nueva API favorece clase abstracta a través de interfaces, ya que estos son más fáciles de evolucionar para. Por ejemplo, puede agregar un método (con una implementación predeterminada) a una clase abstracta sin romper implementaciones antiguas de la clase ". ¿Qué significa (especialmente lo que significa "romper viejas implementaciones de la clase")? Apreciar si alguien podría mostrarme una muestra ¿por qué desde esta perspectiva la clase abstracta es mejor que la interfaz?

gracias de antemano, George

Respuesta

10

En el caso de una interfaz, todos métodos que se definen en una interfaz deben ser implementadas por una clase que implementa.

Dada la interfaz A

interface A { 
    public void foo(); 
} 

y una clase B:

class B implements A { 
} 

que tiene que proporcionar una implementación para el método definido en la interfaz:

class B implements A { 
    @Override 
    public void foo() { 
     System.out.println("foo"); 
    } 
} 

De lo contrario, es un error en tiempo de compilación. Desde aquí, tomar una clase abstracta con una implementación por defecto de un método:

abstract class C { 
    public void bar() { 
     System.out.println("bar"); 
    } 
} 

donde una clase que hereda de esta clase abstracta puede tener este aspecto:

class D extends C { } 

sin un error. Pero también puede anular la implementación del método predeterminado si está inclinado a hacerlo.

Lo que el autor decía allí: Si su API todavía no es estable y necesita adaptar interfaces (sí, las clases abstractas también son interfaces (en OOP-speak)), una clase abstracta le permite agregar cosas sin romper las clases que ya están allí. Sin embargo, esto solo es válido para los métodos no abstractos. Si agrega métodos abstractos, aún deben implementarse en todas las clases derivadas. Pero aún así, puede hacerte la vida más fácil si tienes una API que todavía está evolucionando y ya tiene muchas cosas desarrolladas.

+0

¡Gracias! Lo que estoy confundiendo es esta afirmación: "romper implementaciones antiguas de la clase" en el libro. "La clase" significa que la clase se deriva de la clase abstracta, o clase en que se basa la clase abstracta? – George2

+1

@George: Significa la clase que se deriva de la versión anterior de la clase interface/abstract. Con las interfaces ya no es válido, ya que no implementa un método que ha agregado a la interfaz. Con clases abstractas y métodos no abstractos, puede simplemente utilizar la implementación de la clase base sin siquiera saber que está allí. – Joey

+0

Gracias! Quiere decir supongamos que en la versión 1, la clase abstracta tiene el método Foo y una clase deriva de la clase abstracta implementa Foo. Y en la versión 2 de la clase abstracta, se agrega un nuevo método Goo, y la clase derivada seguirá funcionando sin ser impactada (si Goo tiene implementación predeterminada en la clase abstracta)? – George2

6

Si agrega un método con una implementación por defecto a una clase abstracta, no se necesita hacer ningún cambio en las clases derivadas.

Alternativamente, si agrega un método a una interfaz, las clases que implementen esa interfaz deben implementar el método; de lo contrario, no compilarán.

+0

Gracias! "nada necesita cambiar en ninguna clase base" - "cualquier clase base", ¿te refieres a la clase base de la clase abstracta, o la clase que deriva de la clase abstracta? – George2

+1

Maldita sea. Debería haber dejado esos ejemplos. Me tomó cuatro minutos más ;-) – Joey

+0

¿Alguna respuesta a mi comentario anterior? :-) – George2

1

Por favor, véanse las siguientes pautas de Eclipse Wiki

APIs basadas en Java Evolving

Adding an API method

Ejemplo 4 - Adición de un método de API

Pueden adición de un método de API a una clase o interfaz romper la compatibilidad con los clientes existentes?

Si el método se agrega a una interfaz que los Clientes pueden implementar, entonces definitivamente es un cambio radical.

Si el método se agrega a una clase (interfaz) que los Clientes no pueden subclasificar (implementar), entonces no es un cambio brusco.

Sin embargo, si el método se agrega a una clase en la que los clientes pueden crear una subclase, entonces el cambio normalmente debería verse como un cambio de última hora. El motivo de esta dura conclusión es la posibilidad de que la subclase de un Cliente ya tenga su propia implementación de un método con ese nombre. Agregar el método API a la superclase socava el código del Cliente, ya que sería pura coincidencia si el método existente del Cliente cumpliera con el contrato API del método recién agregado. En la práctica, si la probabilidad de este tipo de coincidencia de nombre es suficientemente baja, este tipo de cambio a menudo se trata como si no se rompiera.