Interface and Abstraction in Java - Complete Guide
Interface and Abstraction in Java
JDK 1.7 Features - Interface Rules
- Interface is a keyword used to achieve multiple inheritance.
- Interface is like a class used to hold constant variables and fully abstract methods.
- Constant variable can never change:
public static final int i = 10;- public static final is implicit. - Fully abstract method has no body:
public abstract void eat();- public abstract is implicit. - You can never create an instance of an interface because it has no constructor.
- Interface always has public property (methods and variables are public by default).
- Interface can be used only through inheritance.
- A class can implement one or more interfaces separated by comma:
class A implements B, C {} // B and C are Interfaces - An interface can extend one or more interfaces:
interface A extends B, C {} // B and C are interfaces - A class can extend another class and also implement interfaces:
class A extends B implements C, D {} // B is class, C,D are interfaces - Interface can never be made final (because it must be inherited).
- Interface can be abstract (all interfaces are abstract by default).
- We can achieve loose coupling using interface.
- Interface can never extend or implement a class.
- A marker interface has no methods, e.g., Cloneable, Serializable.
- We can never use super keyword in interface (in JDK 1.7).
- All interface methods are implemented by its subclass using overriding.
JDK 1.8 Features
- In an interface you can define a non-static method using
defaultkeyword:default void show() { System.out.println("default method"); } - We can also define static method inside an interface:
static void display() {} - We can use super keyword in interface using interface name:
InterfaceName.super.methodName();
What is Functional Interface?
- An interface which has single abstract method only.
- Can have default and static methods also.
- Annotated with
@FunctionalInterface
What is Lambda Expression?
- Lambda Expression is used to optimize your code (reduce boilerplate).
- Applies only with functional interface.
- Can be no-parameter or parameterized.
- Syntax:
() -> System.out.println("No Parameterized"); - Syntax:
(x) -> System.out.println("Parameterized: " + x);
JDK 1.9 Features
In an interface you can have private methods to reuse code inside default methods:
private void commonLogic() {
// reusable code for default methods
}
Abstraction in Java
Abstraction means hiding complexity and showing only functionality to the user.
Using abstract class you can achieve abstraction. Let's see example:
Problem Without Abstraction - Complexity
Each and every Vehicle needs to provide implementation of all methods separately - lots of duplicate code:
interface Vehicle {
void gear();
void headLight();
void backLight();
void wheel();
void seat();
}
class Bmw implements Vehicle {
@Override public void gear() {}
@Override public void headLight() {}
@Override public void backLight() {}
@Override public void wheel() {}
@Override public void seat() {}
}
class Scoda implements Vehicle {
@Override public void gear() {}
@Override public void headLight() {}
@Override public void backLight() {}
@Override public void wheel() {}
@Override public void seat() {}
}
// Same for Audi, Duster, Yamaha, Tvs, Suzuki, Scooty...
// Every class repeats same 5 methods - high complexity!
Solution Using Abstraction - Clean Code
Using abstract classes we group common behavior - Car and Bike provide common implementation:
interface Vehicle {
void gear();
void headLight();
void backLight();
void wheel();
void seat();
}
// Abstract class for all Cars - common implementation
abstract class Car implements Vehicle {
@Override public void gear() { System.out.println("Car gear system"); }
@Override public void headLight() {}
@Override public void backLight() {}
@Override public void wheel() {}
@Override public void seat() {}
}
// Now Bmw, Scoda, Audi, Duster just extend Car - no need to override all methods
class Bmw extends Car {}
class Scoda extends Car {}
class Audi extends Car {}
class Duster extends Car {}
// Abstract class for all Bikes
abstract class Bike implements Vehicle {
@Override public void gear() { System.out.println("Bike gear system"); }
@Override public void headLight() {}
@Override public void backLight() {}
@Override public void wheel() {}
@Override public void seat() {}
}
class Yamaha extends Bike {}
class Tvs extends Bike {}
class Suzuki extends Bike {}
class Scooty extends Bike {}
public class Test {
public static void main(String[] args) {
Vehicle v1 = new Bmw();
Vehicle v2 = new Yamaha();
}
}
Conclusion
Use interface to achieve 100% abstraction and multiple inheritance. Use abstract class to provide common implementation and achieve partial abstraction. From JDK 1.8, interfaces are more powerful with default and static methods.
No comments:
Post a Comment