Một interface có thể dùng để định nghĩa hành vi contract và cũng có thể đóng vai trò như một contract giữa hai hệ thống để tương tác trong khi abstract class chủ yếu dùng để định nghĩa hành vi mặc định cho subclass, nghĩa là tất cả child classes phải thực hiện cùng chức năng.
Khi nào dùng abstract class
- Abstract class là lựa chọn tốt nếu chúng ta dùng khái niệm inheritance vì nó cung cấp common base class implementation cho derived classes.
- Abstract class cũng tốt nếu muốn khai báo non-public members. Trong interface, tất cả methods phải là public.
- Nếu muốn thêm methods mới trong tương lai, abstract class là lựa chọn tốt hơn. Vì nếu thêm methods mới vào interface, thì tất cả classes đã implement interface đó sẽ phải thay đổi để implement methods mới.
- Nếu muốn tạo nhiều version của component, hãy tạo abstract class. Abstract classes cung cấp cách đơn giản và dễ dàng để version components. Bằng cách update base class, tất cả inheriting classes tự động được update với thay đổi. Interfaces, mặt khác, không thể thay đổi sau khi tạo. Nếu cần version mới của interface, phải tạo interface hoàn toàn mới.
- Abstract classes có lợi thế cho phép forward compatibility tốt hơn. Khi clients dùng interface, chúng ta không thể thay đổi nó; nếu dùng abstract class, chúng ta vẫn có thể thêm behavior mà không phá vỡ code hiện có.
- Nếu muốn cung cấp common, implemented functionality cho tất cả implementations của component, dùng abstract class. Abstract classes cho phép partially implement class, trong khi interfaces không chứa implementation cho bất kỳ member nào.
Ví dụ
abstract class Car {
public void accelerate() {
System.out.println("Do something to accelerate");
}
public void applyBrakes() {
System.out.println("Do something to apply brakes");
}
public abstract void changeGears();
}Bây giờ, bất kỳ Car nào muốn được instantiate phải implement phương thức changeGears().
class Alto extends Car {
public void changeGears() {
System.out.println("Implement changeGears() method for Alto Car");
}
}
class Santro extends Car {
public void changeGears() {
System.out.println("Implement changeGears() method for Santro Car");
}
}Khi nào dùng interface
- Nếu functionality chúng ta tạo sẽ hữu ích trên nhiều đối tượng khác biệt, dùng interface. Abstract classes nên dùng chủ yếu cho các đối tượng liên quan chặt chẽ, trong khi interfaces phù hợp nhất để cung cấp common functionality cho các class không liên quan.
- Interfaces là lựa chọn tốt khi nghĩ API sẽ không thay đổi trong một thời gian.
- Interfaces cũng tốt khi muốn có cái gì đó tương tự multiple inheritance vì có thể implement nhiều interfaces.
- Nếu thiết kế các bit functionality nhỏ, ngắn gọn, dùng interfaces. Nếu thiết kế large functional units, dùng abstract class.
Ví dụ
public interface Actor {
void perform();
}
public interface Producer {
void invest();
}Ngày nay hầu hết actor giàu đủ để produce phim của mình. Nếu dùng interfaces thay vì abstract classes, chúng ta có thể implement cả Actor và Producer. Cũng có thể định nghĩa ActorProducer interface mới extends cả hai.
public interface ActorProducer extends Actor, Producer{
// some statements
}