Tóm Tắt
1- Giới thiệu
Trong tài liệu hướng dẫn này tôi sẽ hướng dẫn về Interface và class trừu tượng ( Abstract Class ). Đồng thời phân tích sự giống và khác nhau giữa chúng .
2- Class trừu tượng (Abstract Class)
Bạn đang đọc: Abstract class và Interface trong Java
Abstract class ( Class trừu tượng ). Hãy xem ví dụ về một class như vậy :
// Đây là một lớp trừu tượng.
// Nó bắt buộc phải khai báo là abstract
// vì trong nó có một phương thức trừu tượng
public abstract class ClassA {
// Đây là một phương thức trừu tượng.
// Nó không có thân (body).
// Access modifier của phương thức này là public.
public abstract void doSomething();
// Access modifier của phương thức này là protected.
protected abstract String doNothing();
// Phương thức này không khai báo access modifier.
// Access modifier của nó là mặc định.
abstract void todo() ;
}
// Đây là một lớp trừu tượng.
// Nó được khai báo là abstract,
// mặc dù nó không có phương thức trừu tượng nào.
public abstract class ClassB {
}
- Nó được khai báo abstract.
- Nó có thể khai báo 0, 1 hoặc nhiều method trừu tượng bên trong.
- Không thể khởi tạo 1 đối tượng trực tiếp từ một class trừu tượng.
Đặc điểm của một class trừu tượng là :
3- Ví dụ với lớp trừu tượng
Hãy xem hình minh họa :
AbstractJob. java
package org.o7planning.tutorial.abs;
// Một lớp trừu tượng (Mô phỏng một công việc)
// Nó khai báo 2 phương thức trừu tượng.
public abstract class AbstractJob {
public AbstractJob() {
}
// Đây là một phương thức trừu tượng.
// Method này trả về tên của công việc.
public abstract String getJobName();
// Đây là một phương thức trừu tượng.
public abstract void doJob();
}
JavaCoding. java
package org.o7planning.tutorial.abs;
// Lớp này thực hiện hết các phương thức trừu tượng của lớp cha.
public class JavaCoding extends AbstractJob {
public JavaCoding() {
}
// Thực hiện phương thức trừu tượng khai báo tại lớp cha.
@Override
public void doJob() {
System.out.println("Coding Java...");
}
// Thực hiện phương thức trừu tượng khai báo tại lớp cha.
// Phương thức này sẽ có thân (body).
// Và trả về tên của công việc.
@Override
public String getJobName() {
return "Coding Java";
}
}
ManualJob. java
package org.o7planning.tutorial.abs;
// ManualJob - (Mô phỏng một công việc phổ thông)
// Lớp cha (AbstractJob) có 2 phương thức trừu tượng.
// Lớp này mới chỉ thực hiện 1 phương thức trừu tượng của lớp cha.
// Vì vậy nó bắt buộc phải khai báo là abstract.
public abstract class ManualJob extends AbstractJob {
public ManualJob() {
}
// Thực hiện phương thức trừu tượng của lớp cha.
@Override
public String getJobName() {
return "Manual Job";
}
}
BuildHouse. java
package org.o7planning.tutorial.abs;
// Class này thừa kế từ class trìu tượng ManualJob
// BuildHouse không được khai báo là trừu tượng.
// Vì vậy nó cần thực hiện tất cả các phương thức trừu tượng còn lại.
public class BuildHouse extends ManualJob {
public BuildHouse() {
}
// Thực hiện phương thức trừu tượng của lớp cha.
@Override
public void doJob() {
System.out.println("Build a House");
}
}
Ví dụ demo
JobDemo. java
package org.o7planning.tutorial.abs;
public class JobDemo {
public static void main(String[] args) {
// Khởi tạo một đối tượng AbstractJob
// từ Constructor của lớp JavaCoding.
AbstractJob job1 = new JavaCoding();
// Gọi phương thức doJob()
job1.doJob();
// Phương thức getJobName là trừu tượng trong lớp AbstractJob.
// Nhưng nó đã được thực hiện tại một lớp con nào đó.
// Vì vậy bạn có thể gọi nó.
String jobName = job1.getJobName();
System.out.println("Job Name 1= " + jobName);
// Khởi tạo một đối tượng AbstractJob
// từ Constructor của lớp BuildHouse.
AbstractJob job2 = new BuildHouse();
job2.doJob();
String jobName2 = job2.getJobName();
System.out.println("Job Name 2= " + jobName2);
}
}
Kết quả chạy ví dụ :
Coding Java...
Job Name 1= Coding Java
Build a House
Job Name 2= Manual Job
4- Tổng quan về Interface
Chúng ta biết rằng một class chỉ hoàn toàn có thể lan rộng ra từ một class cha .
// Lớp B là con của lớp A, hoặc nói cách khác là B mở rộng từ A
// Java chỉ cho phép một lớp mở rộng từ duy nhất một lớp khác.
public class B extends A {
// ....
}
// Trong trường hợp không chỉ rõ lớp B mở rộng từ một lớp cụ thể nào.
// Mặc định, hiểu rằng B mở rộng từ lớp Object.
public class B {
}
// Cách khai báo này, và cách phía trên là tương đương nhau.
public class B extends Object {
}
Nhưng một class có thể mở rộng từ nhiều Interface
// Một lớp chỉ có thể mở rộng từ 1 lớp cha.
// Nhưng có thể thực hiện (mở rộng) từ nhiều Interface.
public class Cat extends Animal implements CanEat, CanDrink {
// ....
}
The characteristics of the interface
- Interface luôn luôn có modifier là: public interface, cho dù bạn có khai báo rõ hay không.
- 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.
- 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.
- Interface không có Constructor (cấu tử).
5- Cấu trúc của một Interface
NoAccessModifierInterface. java
package org.o7planning.tutorial.itf;
// Đây là một interface không chỉ định rõ 'access modifier'.
// Access modifier của nó là mặc định.
// Chỉ các lớp cùng package mới có thể thi hành interface này.
interface NoAccessModifierInterface {
}
CanMove. java
package org.o7planning.tutorial.itf;
// Interface này định nghĩa một tiêu chuẩn
// về những thứ có khả năng di chuyển.
public interface CanMove {
// Các phương thức trong Interface đều là trừu tượng và public.
public abstract void run();
// Cho dù bạn không viết rõ 'public abstract' thì java luôn hiểu là vậy.
void back();
// Tốc độ.
public int getVelocity();
}
CanDrink. java
package org.o7planning.tutorial.itf;
// Interface này định nghĩa ra một tiêu chuẩn
// về những thứ có khả năng biết uống.
public interface CanDrink {
// Các trường (field) 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
package org.o7planning.tutorial.itf;
// Interface này định nghĩa ra một tiêu chuẩn
// về những thứ có khả năng biết ăn.
public interface CanEat {
public void eat();
}
6- Class thực hiện Interface
Animal. java
package org.o7planning.tutorial.cls;
import org.o7planning.tutorial.itf.CanMove;
// Animal (Động vật).
// Lớp này mở rộng từ lớp Object (Mặc dù không ghi rõ).
// Và được khai báo thực hiện hiện (hoặc gọi là thừa kế) interface CanMove.
// Interface CanMove có 3 phương thức trừu tượng.
// Lớp này chỉ thực hiện 1 phương thức.
// Vì vậy nó bắt buộc phải khai báo là abstract.
// Các phương thức trừu tượng còn lại sẽ được các lớp con thực hiện.
public abstract class Animal implements CanMove {
// Thực hiện phương thức run() của interface CanMove.
@Override
public void run() {
System.out.println("Animal run...");
}
}
Cat.java
package org.o7planning.tutorial.cls;
import org.o7planning.tutorial.itf.CanDrink;
import org.o7planning.tutorial.itf.CanEat;
// Lớp Cat mở rộng từ lớp Animal và thi hành 2 interface CanEat, CanDrink.
// Cat là lớp thông thường (Nó không được khai báo là trừu tượng).
// Vì vậy nó phải thực hiện mọi phương thức trừu tượng của các Interface.
public class Cat extends Animal implements CanEat, CanDrink {
private String name;
public Cat(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
// Thực hiện phương thức của interface CanMove.
@Override
public void back() {
System.out.println(name + " cat back ...");
}
// Thực hiện phương thức của interface CanMove.
@Override
public int getVelocity() {
return 110;
}
// Thực hiện phương thức của interface CanEat.
@Override
public void eat() {
System.out.println(name + " cat eat ...");
}
// Thực hiện phương thức của interface CanDrink.
@Override
public void drink() {
System.out.println(name + " cat drink ...");
}
}
Mouse. java
package org.o7planning.tutorial.cls;
import org.o7planning.tutorial.itf.CanDrink;
import org.o7planning.tutorial.itf.CanEat;
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
package org.o7planning.tutorial.cls;
import org.o7planning.tutorial.itf.CanEat;
public class AnimalDemo {
public static void main(String[] args) {
// 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 (Polymorphism) 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 (Cast).
if (canEat2 instanceof Mouse) {
Mouse mouse = (Mouse) canEat2;
// Gọi phương thức drink (Thừa kế từ CanDrink).
mouse.drink();
}
}
}
Kết quả chạy ví dụ :
Drink SEVEN UP
Tom cat eat ...
Mouse eat ...
catEat1 is Cat? true
Mouse drink ...
Source: https://final-blade.com
Category: Kiến thức Internet