Abstract Class v.s. Interface -- Java
Refer
http://www.jianshu.com/p/2b5a9bdcd25f
https://docs.oracle.com/javase/tutorial/java/IandI/abstract.html
Review Access Level
Modifier | Class self | Package | Subclass | World |
public | Y | Y | Y | Y |
protected | Y | Y | Y | N |
no modifier | Y | Y | N | N |
private | Y | N | N | N |
In General
Abstract Class -- Class which has the common variable and function of a certain type of Classes; Such as Cat and Dog.
Interface -- group of ONLY functions, which any class will behave like these functions could use; Such as Bird and Flight
Abstract Class
1. Cannot be instantiated (new), But can have constructor
2. If a class inlcudes an abstract function, it must be defiend as Abstract class
3. Subclass must override abstract function
4. Abstract class could contain non-abstract function
5. Abstract class may NOT contain abstract function
6. Abstract class could contain Variables, with any access level (public, protected, private)
7. Abstract class could contain Static Variables, with any access level
8. Abstract function in Subclass cannot use the same name as one abstract function in parent.
9. Abstract function cannot use modifier as Private, Static, Final or Native.
10. When the subclass does NOT implement ALL of the abstract methods, the subclass must also be declared Abstract
Interface
1. All functions in Interface will automatically be public, and can NOT be declare as protected or private -- compile error
2. There could be variables in Interface, but they will automatically be public final static, which means they are constant, and must be explicitly initialize.
3. All functions in the interface can NOT be static
4. If a non-abstract class implements an interface, it must implement all functions in the interface
5. If an abstract class implements an interface, it do NOT have to implement all functions
6. Use instanceOf to determine whether a class implements an interface
7. Take care of functions in different interface with the same name.
When to use which
- Consider using abstract classes if any of these statements apply to your situation:
- You want to share code among several closely related classes.
- You expect that classes that extend your abstract class have many common methods or fields, or require access modifiers other than public (such as protected and private).
- You want to declare non-static or non-final fields. This enables you to define methods that can access and modify the state of the object to which they belong.
- Consider using interfaces if any of these statements apply to your situation:
- You expect that unrelated classes would implement your interface.
- You want to specify the behavior of a particular data type, but not concerned about who implements its behavior.
- You want to take advantage of multiple inheritance of type.
Examples
Interface does not have the Diamond Problem
1 interface T1 { 2 void print(); 3 } 4 5 interface T2 { 6 void print(); 7 } 8 9 public class Test implements T1, T2 { 10 11 @Override 12 public void print() { 13 // TODO Auto-generated method stub 14 System.out.println("Hello World!"); 15 } 16 17 public static void main(String[] args) { 18 Test t = new Test(); 19 t.print(); 20 } 21 }
Functions in 2 interfaces with same name/different return types cannot be implement by one class
interface T1 { void print(); } interface T2 { int print(); } public class Test implements T1, T2 { @Override public void print() { } public static void main(String[] args) { Test t = new Test(); t.print(); } }
Unresolved compilation problem:
The return type is incompatible with T2.print()
JDK 1.8 support Default Implementation of function in Interface
interface T1 { default void print1() { System.out.println("print1"); } } interface T2 { default void print2() { System.out.println("print2"); } } public class Test implements T1, T2 { public void print() { print1(); print2(); } public static void main(String[] args) { Test t = new Test(); t.print(); } }
/*
print1
print2
*/
Abstract cannot be Implemented, but can be used to declare Array
abstract class AC { public AC() { } } public class Test extends AC { public static void main(String[] args) { Test t = (Test) new AC(); // will be Error Test[] ts = (Test[]) new AC[10]; // correct } }
Anonymous Inner Class -- An inner class declared without a class name
abstract class AC1 { public abstract void print(); } abstract class AC2 { } // abstract class without Abstract funtcion public class Test { public static void main(String[] args) { AC1 ac1 = new AC1() { @Override public void print() { System.out.println("Hello World!"); } }; AC2 ac2 = new AC2() { }; } }
Anonymous Implementation
interface It { int compare(int a, int b); } public class Test { public boolean Larger(int a, int b, It it) { return it.compare(a, b) > 0; } public static void main(String[] args) { Test test = new Test(); test.Larger(2, 1, new It() { // Anonymous Implementation @Override public int compare(int a, int b) { if (a > b) return 1; else if (a == b) return 0; else return -1; } } ); } }