/** Multiple inheritance in Java with default methods and diamond problem.
 * @author Jaanus
 * @since 1.8
 */
public class J8example7 {

  public static void main (String[] args) {
    Amphibian a = new Amphibian();
    a.startEngine();  // Vehicle engine started
    a.makeNoise();    // both Car and Boat are kind of Vehicle
    a.drive();        // diamond problem (both Car and Boat provide drive method)
    a.enjoyCar();     // inherited from Car
    a.enjoyBoat();    // inherited from Boat
    a.stopEngine();   // Car is more specific than Vehicle
  }
  
  @FunctionalInterface
  interface Vehicle {

	  void makeNoise();
	  
	  default void startEngine() {
		  System.out.println ("Vehicle engine started");
	  }
	  
	  default void stopEngine() {
		  System.out.println ("Vehicle engine stopped");
	  }
  }

  @FunctionalInterface
  interface Car extends Vehicle {   // obligation to provide method makeNoise

	@Override
	default void stopEngine() {
	  System.out.println ("Car engine stopped");
	}
	  
	default void enjoyCar() {
      System.out.println ("I enjoy my car: Car interface default");
    }

    default void drive() {
      System.out.println ("I drive my car: Car interface default");
    }
    
    // possible to override also startEngine
  }
   
  @FunctionalInterface
  interface Boat extends Vehicle {    // obligation to provide method makeNoise

    default void enjoyBoat() {
      System.out.println ("I enjoy my boat: Boat interface default");
    }

    default void drive() {
      System.out.println ("I drive my boat: Boat interface default");
    }
    
    // possible to override also startEngine, stopEngine
  }

  static class Amphibian implements Car, Boat {

	@Override
    public void makeNoise() { // my obligation from Vehicle
      System.out.println ("makeNoise: compulsory Vehicle behaviour: from Amphibian class");
    }

    @Override
    public void drive() { // diamond problem solved in Java way
      System.out.println ("I drive my amphibian: from Amphibian class");
    }
    
    // possible to override also startEngine, stopEngine, enjoyCar, enjoyBoat 
  }

}
