INTERFACE
Interface không phải là lớp thông thường mà nó là 1 giao tiếp (chỉ mô tả khái quát không cụ thể các phương thức hoặc thuộc tính) mà một hoặc nhiều lớp khác muốn truy xuất đến để bổ sung cho nó mà không thể thực hiện thừa kế được (do đã 1 lần thừa kế), thông qua từ khóa implement. Interface trong java được dùng để xử lý đa thừa kế.
Chúng ta biết rằng một class chỉ có thể thừa kế từ một class cha. Tuy nhiên, trong thực tế một lớp con đôi khi cần thừa kế từ nhiều lớp cha.
Ví dụ : Ta có lớp Hình bình hành. Có 2 lớp con thừa kế từ nó là lớp Hình thoi và lớp Hình chữ nhật. Rõ ràng muốn xây dựng lớp Hình vuông thì ta phải kế nó từ lớp Hình Hình thoi và lớp Hình chữ nhật. Như vậy lớp Hình vuông đã thực hiện đồng thời thừa kế từ 2 lớp (đa thừa kế).
Nhưng trong ngôn ngữ Java, khác với C++, không cho phép đa thừa kề từ nhiều lớp. Do đó,làm thế nào giải quyết trường hợp này ?
Java giải quyết trường hợp này bằng cách đưa ra một khái niệm gọi là : Interface.
Hình bình hành |
Hình chữ nhật |
H. thoi |
Hình vuông |
1. Interface luôn luôn có modifier: public interface, cho dù bạn có khai báo rõ hay không.
2. Nếu có các trường (field) thì chúng đều là: public static final, cho dù bạn có khai báo rõ hay không.
3. Các method của nó đều là method trừu tượng, nghĩa là không có thân hàm, và đều có modifier là: public abstract, cho dù bạn có khai báo hay không.
4. Interface không có cấu tử tạo thành (Constructor).
CanMove.java
public interface CanMove {
// (Chạy)
// Các method trong Interface đều là method trừu tượng.
// Luôn luôn là: public abstract ...
public abstract void run();
// (Quay trở lại)
// Cho dù không viết rõ public abstract thì java luôn hiểu là vậy.
void back();
// (Lấy ra vận tốc chạy).
public int getVelocity();
}
CanDrink.java
// Interface này định nghĩa những thứ có khả năng biết uống.
public interface CanDrink {
// Các trường trong Interface đều là public static final.
// Cho dù bạn có khai báo rõ hay không java luôn hiểu ngầm vậy.
public static final String PEPSI = "PEPSI";
final String NUMBER_ONE = "NUMBER ONE";
String SEVENUP = "SEVEN UP";
public void drink();
}
CanEat.java
// Interface này định nghĩa thứ có khả năng biết ăn.
public interface CanEat {
public void eat();
}
Animal.java
// Animal (Dùng để mô phỏng lớp động vật)
public abstract class Animal implements CanMove {
// Triển khai method run() từ interface CanMove.
@Override
public void run() {
System.out.println("Animal run...");
}
}
Cat.java
// Class Cat mở rộng từ class Animal và thi hành 2 interface CanEat, CanDrink.
public class Cat extends Animal implements CanEat, CanDrink {
private final String name;
public Cat(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
// Triển khai method của interface CanMove
@Override
public void back() {
System.out.println(name + " cat back ...");
}
// Triển khai method của interface CanMove
@Override
public int getVelocity() {
return 110;
}
// Triển khai method của interface CanEat
@Override
public void eat() {
System.out.println(name + " cat eat ...");
}
// Triển khai method của interface CanDrink
@Override
public void drink() {
System.out.println(name + " cat drink ...");
}
}
Mouse.java
public class Mouse extends Animal implements CanEat, CanDrink {
@Override
public void back() {
System.out.println("Mouse back ...");
}
@Override
public int getVelocity() {
return 85;
}
@Override
public void drink() {
System.out.println("Mouse drink ...");
}
@Override
public void eat() {
System.out.println("Mouse eat ...");
}
}
AnimalDemo.java
public class AnimalDemo {
public static void main(String[] args) {
// Class Cat thừa kế trường tĩnh từ interface CanDrink.
System.out.println("Drink " + Cat.SEVENUP);
// Khởi tạo một đối tượng CanEat
// Một đối tượng khai báo là CanEat
// Nhưng thực tế là Cat.
CanEat canEat1 = new Cat("Tom");
// Một đối tượng khai báo là CanEat
// Nhưng thực tế là Mouse.
CanEat canEat2 = new Mouse();
// Tính đa hình thể hiện rõ tại đây.
// Java luôn biết một đối tượng là kiểu gì
// ==> Tom cat eat ...
canEat1.eat();
// ==> Mouse eat ...
canEat2.eat();
boolean isCat = canEat1 instanceof Cat;
System.out.println("catEat1 is Cat? " + isCat);
// Ép kiểu
if (canEat2 instanceof Mouse) {
Mouse mouse = (Mouse) canEat2;
// Gọi method drink (Thừa kế từ CanDrink).
mouse.drink();
}
}
}
2.3.LỚP FINAL (Lớp vô sinh):
Lớp không thể có lớp dẫn xuất từ nó (không có lớp con) gọi là lớp “vô sinh”, hay nói cách khác không thể kế thừa được từ một lớp “vô sinh”. Lớp “vô sinh” dùng để hạn chế, ngăn ngừa các lớp khác dẫn xuất từ nó.Để khai báo một lớp là lớp “vô sinh”, chúng ta
dùng từ khóa final class.
Tất cả các phương thức của lớp vô sinh đều vô sinh, nhưng các thuộc tính của lớp vô sinh thì có thể không vô sinh.
Ví dụ:
public final class A {
public final int x;
private int y;
public final void method_1(){
// …
}
public final void method_2(){
// …
}
}
---o0o---
BÀI TẬP
Câu 1 .Xây dựng một interface có tên là HCNInterface (được đặt trong gói HCNPackage) chứa một số phương thức sau:
- Phương thức dientichHCN() dùng để tính diện tích hình chữ nhật.
- Phương thức getChieuDai() và getChieuRong() dùng để lấy giá trị chiều dài và chiều rộng của của hình chữ nhật.
- Phương thức setDaiRong(cd, cr) dùng để cập nhật giá trị cd, cr cho hai cạnh của hình chữ nhật.
Câu 2.Sử dụng interface HCNInterface trên để xây dựng lớp Hinhchunhat chứa hai thuộc tính là: chieudai, chieurong và các phương thức dientichHCN(), getChieuDai(), getChieuRong(), setDaiRong(cd,cr) đã khai báo trong Interface HCNInterface trên?
Câu 3. Xây dựng lớp HCNTest thừa kế lớp Hinhchunhat chứa phương thức main thực hiện các công việc sau:
a. Khai báo một mảng chứa n hình chữ nhật (với n là số nguyên dương bất kỳ được nhập từ bàn phím). Sau đó nhập chiều dài và chiều rộng cho n hình chữ nhật đó.
b. In ra màn hình thông tin: chiều dài, chiều rộng và diện tích của n hình chữ nhật trên.
c. In ra màn hình thông tin về hình chữ nhật có diện tích lớn nhất.
» Tin mới nhất:
» Các tin khác: