Java8-11 presenta el método de prohibición predeterminado y el método de prohibición estática

Antes de Java 8, todos los métodos de una interfaz eran públicos y abstractos de forma predeterminada. Pero esta limitación se rompió en Java 8. Java 8 permite a los desarrolladores agregar nuevos métodos a las interfaces sin ningún cambio en las clases que implementan estas interfaces.

¿Por qué existe un método predeterminado?
Principalmente para facilitar la expansión de interfaces existentes; si no hay un método predeterminado, si se agrega un nuevo método abstracto a una interfaz en Java, entonces todas las clases que implementan la interfaz deben modificarse y el impacto será muy grande.

Por ejemplo, la interfaz Sortable y las clases SortableNumberCollection y SortableStringCollection que implementan la interfaz. Esta interfaz tiene dos métodos: void sort () y T peek ().

public interface Sortable<T> {
    
    
 void sort();
 T peek();
}

El método sort () se usa para ordenar objetos, y T peek () se usa para obtener los elementos especificados Además, se necesita una clase comparadora ObjectComparator para ordenar los objetos.

public class ObjectComparator implements Comparator<Comparable> {
    
    
 @Override
 public int compare(Comparable o1, Comparable o2) {
    
    
  return o1.compareTo(o2);
 }
}

SortableStringCollection es una clase de colección personalizada que puede ordenar y ver los elementos especificados de la cadena. El código es el siguiente:

public class SortableStringCollection implements Sortable<String> {
    
    
 
 private List<String> items = new ArrayList<>();
 
 public void add(String item) {
    
    
  items.add(item);
 }
 
 @Override
 public void sort() {
    
    
  items.sort(new ObjectComparator());
 }
 
 @Override
 public String peek() {
    
    
  return items.get(0);
 }
}

De manera similar, SortableNumberCollection es una clase de colección personalizada que contiene elementos específicos de una lista de números que se pueden ordenar y ver mediante métodos de interfaz. El código es el siguiente:

public class SortableNumberCollection implements Sortable<Integer> {
    
    
 
 private List<Integer> items = new ArrayList<>();
 
 public void add(Integer item) {
    
    
  items.add(item);
 }
 
 @Override
 public void sort() {
    
    
  items.sort(new ObjectComparator());
 }
 
 @Override
 public Integer peek() {
    
    
  return items.get(0);
 }
}

Antes de Java8, si se agrega un nuevo método a la interfaz Sortable: T sortAndPeek (), luego SortableStringCollection y

SortableNumberCollection debe implementar el método T sortAndPeek ().

Después de Java8, se proporciona un nuevo método de implementación, el método predeterminado, el método predeterminado, podemos modificar Sortable de la siguiente manera:

public interface Sortable<T> {
    
    
 void sort();
 T peek();
 
 default T sortAndPeek(){
    
     // New 'default method' added in the interface
  sort();
  return peek();
 }
 
}

Al mismo tiempo, las clases SortableStringCollection y SortableNumberCollection no requieren ningún cambio. Esto puede reducir nuestros cambios al código original. Al mismo tiempo, si es necesario, también puede anular la implementación predeterminada de T sortAndPeek () en cualquier clase que implemente esta interfaz.

En la siguiente figura, vemos el logo que falla el método predeterminado:
Inserte la descripción de la imagen aquí

El problema de usar métodos predeterminados en herencia múltiple
Si dos o más interfaces tienen la misma firma de método predeterminado y una clase implementa estas dos interfaces, se generará un error en tiempo de compilación. P.ej:

public interface Interface1 {
    
    
 void methodOne(String str);
 default void newMethod(){
    
    
  System.out.println("Interface1: Newly added method");
 }
}
 
 
 
public interface Interface2 {
    
    
 void methodTwo(String str);
 default void newMethod(){
    
    
  System.out.println("Interface2: Newly added method");
 }
}
 
 
 
public class InterfaceImplementation implements Interface1, Interface2{
    
    
 @Override
 public void methodOne(String str) {
    
    
  System.out.println("Overridden methodOne: " + str);
 }
 
 @Override
 public void methodTwo(String str) {
    
    
  System.out.println("Overridden methodTwo: " + str );
 }
}

En este momento, el código generará la siguiente excepción:

InterfaceImplementation hereda valores predeterminados no relacionados para newMethod () de los tipos Interface1 e Interface2

Para resolver este problema, tendremos que anular el método en la clase InterfaceImplementation:

public class InterfaceImplementation implements Interface1, Interface2{
    
    
 @Override
 public void methodOne(String str) {
    
    
  System.out.println("Overridden methodOne: " + str);
 }
 
 // newMethod implemented to resolve the conflict.
 @Override
 public void newMethod() {
    
    
  System.out.println("InterfaceImplementation: Newly added method");
 }
 
 @Override
 public void methodTwo(String str) {
    
    
  System.out.println("Overridden methodTwo: " + str );
 }
}

El método estático definido en la interfaz del método estático se agrega en Java 8
independientemente de cualquier llamada de objeto. Por lo tanto, al llamar a un método estático, no es necesario implementar una interfaz, ni una instancia de la interfaz.

Al igual que el "método predeterminado", el "método estático" también se puede agregar a la interfaz. Por ejemplo, podemos agregar un método estático Direction getDefaultDirection (), que devolverá la Direction predeterminada, por ejemplo:

public interface Sortable<T> {
    
    
 
 Direction defaultDirection = Direction.DESC;
 
 enum Direction {
    
    
  ASC,
  DESC
 };
 
 void sort();
 T peek();
 
 static Direction getDefaultDirection(){
    
     // 'static method' added to the interface.
  return defaultDirection;
 }
}

En el ejemplo anterior, puede usar la referencia de clase para llamar al método estático Direction getDefaultDirection ():

Sortable.getDefaultDirection()

Un poco de pensamiento sobre los métodos predeterminados y los métodos estáticos. La
interfaz es una experiencia de principios de apertura y cierre en el patrón de diseño. Java 8 le da a la interfaz nuevas características, lo que hace que la interfaz sea más práctica de usar, lo que también nos ayuda a ser más cohesivos. Estructura de código. También hay muchos escenarios en el código fuente de Java que usan métodos predeterminados, como la interfaz Iterator.Podemos usar más características nuevas en el desarrollo para mejorar la eficiencia del desarrollo y aumentar la solidez del código.

public interface Iterable<T> {
    
    
 
 Iterator<T> iterator();
  
 default void forEach(Consumer<? super T> action) {
    
    
  Objects.requireNonNull(action);
  for (T t : this) {
    
    
   action.accept(t);
  }
 }
  
 default Spliterator<T> spliterator() {
    
    
  return Spliterators.spliteratorUnknownSize(iterator(), 0);
 }
  
}

Hasta ahora, se presenta este artículo sobre los métodos predeterminados y los métodos estáticos de las nuevas características de Java 8. Para obtener más métodos predeterminados y métodos estáticos relacionados con Java 8, preste atención al editor para actualizaciones continuas o agregue QQ1411943564

Supongo que te gusta

Origin blog.csdn.net/dcj19980805/article/details/115207579
Recomendado
Clasificación