JavaRush /Java Blog /Random EN /Default methods in interfaces

Default methods in interfaces

Published in the Random EN group
Each new version of Java is different from the previous ones. Here's an example of the changes from the material we covered: Before Java 5, there were no enum's in the language.
Default methods in interfaces - 1
Likewise, Java 8 is noticeably different from Java 7. Most of our lectures are written in the 7th version of the language, but, of course, we will not ignore important innovations. Since we're talking about interfaces in this lecture, let's look at one update - default methods in interfaces . You already know that an interface does not implement . Its task is to describe what behavior all objects that implement it should have . But quite often developers encountered situations where the implementation of a method in all classes was the same. Let's look at our old car example:
public interface Car {

   public void gas();

   public void brake();
}
public class Sedan implements Car {

   @Override
   public void gas() {
       System.out.println("Газ!");
   }

   @Override
   public void brake() {
       System.out.println("Тормоз!");
   }
}


public class Truck implements Car {

   @Override
   public void gas() {
       System.out.println("Газ!");
   }

   @Override
   public void brake() {
       System.out.println("Тормоз!");
   }
}


public class F1Car implements Car {
   @Override
   public void gas() {
       System.out.println("Газ!");
   }

   @Override
   public void brake() {
       System.out.println("Тормоз!");
   }
}
What do you think is the main problem with this code? You probably noticed that we wrote a bunch of the same code! This problem is common in programming and should be avoided. Another thing is that before the release of Java 8 there were no special solution options. When this version came out, it became possible to define default methods and implement them right inside the interface! Here's how it's done:
public interface Car {

   public default void gas() {
       System.out.println("Газ!");
   }

   public default void brake() {
       System.out.println("Тормоз!");
   }
}

public class Sedan implements Car {

}

public class Truck implements Car {

}

public class F1Car implements Car {

}
Now the methods gas()and brake(), which were the same for all machines, are included in the interface, and duplicate code is not needed. Moreover, the methods are available in each of the classes!
public class Main {

   public static void main(String[] args) {

       F1Car f1Car = new F1Car();
       Sedan sedan = new Sedan();
       Truck truck = new Truck();
       truck.gas();
       sedan.gas();
       f1Car.brake();
   }
}
What if there are 100 classes with a method gas(), but only 99 of them have the same behavior? This ruins everything, and the default method will not work in this case? Of course not :) Default methods of interfaces can be overridden.
public class UnusualCar implements Car {
   @Override
   public void gas() {
       System.out.println("Эта машина газует по-другому!");
   }

   @Override
   public void brake() {
       System.out.println("Эта машина тормозит по-другому!");
   }
}
All the other 99 types of machines will implement the default method, and the class UnusualCar- the exception - will not spoil the overall picture and will calmly determine its behavior. Multiple Inheritance in Interfaces As you already know, there is no multiple inheritance in Java. There are many reasons for this; we will look at them in detail in a separate lecture. In other languages, for example, in C++, it is the other way around. Without multiple inheritance, a serious problem arises: the same object can have a number of different characteristics and "behaviors." An example from life: for our parents we are children, for teachers we are students, for doctors we are patients. In life, we appear in different roles and, accordingly, behave differently: we will obviously talk to teachers differently than to close friends. Let's try to translate this situation into code. Let's imagine that we have two classes: Pond and Aviary. For a pond you need swimming birds, and for an aviary you need flying ones. To do this, we created two base classes - FlyingBirdand Waterfowl.
public class Waterfowl {
}

public class FlyingBird {
}
Accordingly, we will send to the aviary those birds whose classes are inherited from FlyingBird, and to the pond - those who descend from Waterfowl. Everything seems simple. But what will we do if we need to identify the duck somewhere? She both swims and flies. But we don't have multiple inheritance. Fortunately, Java provides multiple implementations of interfaces. If a class cannot inherit from several parents, implementing several interfaces is easy! Our duck can be both flying and swimming :) It is enough to use interfaces FlyingBirdrather Waterfowlthan classes to achieve the desired result.
public class Duck implements FlyingBird, Waterfowl {

   //методы обоих интерфейсов легко объединяются в одном классе

   @Override
   public void fly() {
       System.out.println("Летим!");
   }

   @Override
   public void swim() {

       System.out.println("Плывем!");
   }
}
Thanks to this, our program retains flexible class management, and in combination with the implementation of default methods, our ability to define the behavior of objects becomes almost limitless! :)
Comments
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION