Interface should only have methods that are applicable to all child classes.
If an interface contains a method applicable to some child classes then we need to force the rest to provide dummy implementation. Move such methods to a new interface.
Bad Implementation :
Vehicle interface contains the fly() method which is not supported by all vehicles i.e. Bus, Car, etc. Hence they've to forcefully provide a dummy implementation.
It violates the Interface Segregation principle as shown below:
publicinterfaceVehicle{voidaccelerate(){}voidapplyBreaks(){}voidfly(){}}publicclassAeroplaneimplementsVehicle{@Overridepublicvoidaccelerate(){...}@OverridepublicvoidapplyBreaks(){...}@Overridepublicvoidfly(){...}}// Aeroplane implements all methods as it supports all operationspublicclassBusimplementsVehicle{@Overridepublicvoidaccelerate(){...}@OverridepublicvoidapplyBreaks(){...}@Overridepublicvoidfly(){// dummy implementation}}//Here bus provide dummy implementation for fly() method as it didn't support fly
Good Implementation :
Pulling out fly() method into new Flyable interface solves the issue.
Now, Vehicle interface contains methods supported by all Vehicles.
And, Aeroplane implements both Vehicle and Flyable interface as it can fly too.
publicinterfaceVehicle{voidaccelerate(){}voidapplyBreaks(){}}publicinterfaceFlyable{voidfly(){}}publicclassAeroplaneimplementsVehicle,Flyable{@Overridepublicvoidaccelerate(){...}@OverridepublicvoidapplyBreaks(){...}@Overridepublicvoidfly(){...}}// Aeroplane class implements both Vehicle and Flyable interfacepublicclassBusimplementsVehicle{@Overridepublicvoidaccelerate(){...}@OverridepublicvoidapplyBreaks(){...}}// Bus implements only vehicle interface as it didn't support fly()