Java8-11 features default ban method and static ban method

Before Java 8, all methods in an interface were public and abstract by default. But this limitation was broken in Java 8. Java 8 allows developers to add new methods to interfaces without any changes in the classes that implement these interfaces.

Why is there a default method?
Mainly to facilitate the expansion of existing interfaces; if there is no default method, if a new abstract method is added to an interface in Java, then all classes that implement the interface have to be modified, and the impact will be very large.

For example, the Sortable interface and the SortableNumberCollection and SortableStringCollection classes that implement the interface. This interface has two methods: void sort(); and T peek().

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

The sort() method is used to sort objects, and T peek() is used to get the specified elements. In addition, a comparator class ObjectComparator is needed to sort the objects.

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

SortableStringCollection is a custom collection class that can sort and view the specified elements of the string. The code is as follows:

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);
 }
}

Similarly, SortableNumberCollection is a custom collection class that contains specified elements of a number list that can be sorted and viewed using interface methods. The code is as follows:

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);
 }
}

Before Java8, if a new method is added to the interface Sortable: T sortAndPeek(), then SortableStringCollection and

SortableNumberCollection must implement the T sortAndPeek() method.

After Java8, a new implementation method is provided, the default method default method, we can modify Sortable as follows:

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

At the same time, the SortableStringCollection and SortableNumberCollection classes do not require any changes. This can reduce our changes to the original code. At the same time, if necessary, you can also override the default implementation of T sortAndPeek() in any class that implements this interface.

In the figure below, we see the logo that the default method fails:
Insert picture description here

The problem of using default methods in multiple inheritance
If two or more interfaces have the same default method signature, and a class implements these two interfaces, a compile-time error will be raised. E.g:

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 );
 }
}

At this time, the code will prompt the following exception:

InterfaceImplementation inherits unrelated defaults for newMethod() from types Interface1 and Interface2

To solve this problem, we will have to override the method in the class 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 );
 }
}

The static method defined in the static method interface is added in Java 8
independent of any object call. Therefore, when calling a static method, there is no need to implement an interface, nor an instance of the interface.

Just like "default method", "static method" can also be added to the interface. For example, we can add a static method Direction getDefaultDirection(), which will return the default Direction, for example:

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;
 }
}

In the above example, you can use the class reference to call the static Direction getDefaultDirection() method:

Sortable.getDefaultDirection()

A little thinking about default methods and static methods.
Interface is an experience of opening and closing principles in the design pattern. Java 8 gives the interface new features, which makes the interface more convenient to use, which also helps us to be more cohesive. Code structure. There are also many scenarios in the Java source code that use default methods, such as the Iterator interface. We can use more new features in development to improve development efficiency and increase code robustness.

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);
 }
  
}

So far, this article about the default methods and static methods of the new features of Java 8 is introduced. For more related Java 8 default methods and static methods, please pay attention to the editor for continuous updates or add QQ1411943564

Guess you like

Origin blog.csdn.net/dcj19980805/article/details/115207579