Sự Khác Nhau Giữa Interface Và Abstract Class Trong Java / Top 7 # Xem Nhiều Nhất & Mới Nhất 6/2023 # Top View | Channuoithuy.edu.vn

Sự Khác Nhau Giữa Abstract Class Và Interface Trong Java

Ở những bài trước, chúng ta đã biết đến tính trừu tượng, và đi song song đó là abstract class và interface để triển khai tính trừu tượng trong java.

Chúng ta cùng xem thử nó sẽ khác nhau ở điểm nào qua bảng liệt kê sau

1

Abstract class chỉ có thể thừa kế một class hoặc một abstract class khác.

Interface có thể thừa kế một hoặc nhiều interface khác.

2

Abstract class có thể chứa abstract method và method thông thường(method có thân hàm).

Interface chỉ có abstract method.

3

Abstract class có thể chứa protected hoặc public abstract method.

Interface chỉ có public abstract method.

4

Abstract class có thể chứa static, final hoặc static final biến.

Interface chỉ có public static final biến.

Abstract class chỉ có thể thừa kế một class hoặc một abstract class khác public class Example1{ public void display1(){ System.out.println("method ex1"); } } public abstract class Example2 extends Example1{ abstract void display2(); } public class Example3 extends Example2{ public void display3(){ System.out.println("method ex3"); } } public class Main{ public static void main(String args[]){ Example3 obj=new Example3(); obj.display3(); } }

Output: method ex3

Interface có thể thừa kế một hoặc nhiều interface khác public interface Example1{ public void display1(); } public interface Example2 { public void display2(); } public interface Example3 extends Example1,Example2{} public class Example4 implements Example3{ public void display1(){ System.out.println("method ex1"); } public void display2(){ System.out.println("method ex2"); } } public class Main{ public static void main(String args[]){ Example4 obj=new Example4(); obj.display1(); obj.display2(); } }

Output:

method ex1

method ex2

Abstract class có thể chứa abstract method và method thông thường(method có thân hàm) public abstract class Example1 { abstract void display1(); public void display2(){ System.out.println("method" ex2); } } public class Example2 extends Example1{ public void display1(){ System.out.println("method ex1"); } } public class Main { public static void main(String args[]){ Example2 obj=new Example2(); obj.display1(); obj.display2(); } }

Output:

method ex1

method ex2

Interface chỉ có abstract method public interface Example1{ public abstract void display(); } public class Example2 implements Example1{ public void display(){ System.out.println("method dispaly="); } } public class Main{ public static void main(String args[]){ Example2 obj=new Example2(); obj.display(); } }

Output: display

Abstract class có thể chứa protected hoặc public abstract method public abstract class Example1{ protected abstract void display1(); public abstract void display2(); public abstract void display3(); } class Example2 extends Example1{ public void display1(){ System.out.println("method ex1"); } public void display2(){ System.out.println("method ex2"); } public void display3(){ System.out.println("method ex3"); } } public class Main{ public static void main(String args[]){ Example2 obj=new Example2(); obj.display1(); obj.display2(); obj.display3(); } }

Output:

method ex1

method ex2

method ex3

Interface chỉ có public abstract method public interface Example1{ void display1(); } public class Example2 implements Example1{ public void display1(){ System.out.println("method ex1"); } public void display2(){ System.out.println("method ex2"); } } public class Main{ public static void main(String args[]){ Example2 obj=new Example2(); obj.display1(); obj.display2(); } }

Output:

method ex1

method ex2

Abstract class có thể chứa static, final hoặc static final biến public abstract class Example1{ private int num_1 = 1; protected final int num_2 = 2; public static final int num_ 3 = 3; public void display1(){ System.out.println("Num1="+num_1); } } public Example2 extends Example1{ public void display2(){ System.out.println("Num2="+num_2); System.out.println("Num3="+num_3); } } public class Main{ public static void main(String args[]){ Example2 obj=new Example2(); obj.display1(); obj.display2(); } }

Output:

1

2

3

Interface chỉ có public static final biến public interface Example1{ int num_1=10; } public class Example2 implements Example1{ public void display1(){ System.out.println("Num1="+num_1); } } public class Main{ public static void main(String args[]){ Example2 obj=new Example2(); obj.display1(); } }

Output: 10

Note:

Interface thường được dùng để mô tả một tập các chức năng. Một class thừa kế một interface A, ta nói rằng class đó có thể thực hiện các năng của interface A khai báo, mà chưa cần xem code.

Ví dụ: Chúng ta có Mail là một interface và MailImpl implements Mail

public class MailImpl implements Mail

Chúng ta sẽ hiểu rằng class MailImpl sẽ có thể thực hiện được các chứng năng mà Mail khai báo.

Abstract class thường được dùng trong mối quan hệ thừa kế, vì tính linh hoạt của nó có thể chứa abstract method và method thông thường. Dựa vào đó mà chúng ta có thể định nghĩa các khuôn mẫu hay triển khai những thuộc tính, method mà các class con có thể dùng chung.

Abstract Class Và Interface Trong Java

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.

Abstract class (Class trừu tượng). Hãy xem ví dụ về một class như thế:

public abstract class ClassA { public abstract void doSomething(); protected abstract String doNothing(); abstract void todo() ; } public abstract class ClassB { }

Đặc điểm của một class trừu tượng là:

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.

package org.o7planning.tutorial.abs; public abstract class AbstractJob { public AbstractJob() { } public abstract String getJobName(); public abstract void doJob(); } package org.o7planning.tutorial.abs; public class JavaCoding extends AbstractJob { public JavaCoding() { } @Override public void doJob() { System.out.println("Coding Java..."); } @Override public String getJobName() { return "Coding Java"; } } package org.o7planning.tutorial.abs; public abstract class ManualJob extends AbstractJob { public ManualJob() { } @Override public String getJobName() { return "Manual Job"; } } package org.o7planning.tutorial.abs; public class BuildHouse extends ManualJob { public BuildHouse() { } @Override public void doJob() { System.out.println("Build a House"); } } package org.o7planning.tutorial.abs; public class JobDemo { public static void main(String[] args) { AbstractJob job1 = new JavaCoding(); job1.doJob(); String jobName = job1.getJobName(); System.out.println("Job Name 1= " + jobName); AbstractJob job2 = new BuildHouse(); job2.doJob(); String jobName2 = job2.getJobName(); System.out.println("Job Name 2= " + jobName2); } }

Chúng ta biết rằng một class chỉ có thể mở rộng từ một class cha.

public class B extends A { } public class B { } public class B extends Object { }

Nhưng một class có thể mở rộng từ nhiều Interface

public class Cat extends Animal implements CanEat, CanDrink { } Các đặc điểm của 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ử).

NoAccessModifierInterface.java

package org.o7planning.tutorial.itf; interface NoAccessModifierInterface { } package org.o7planning.tutorial.itf; public interface CanMove { public abstract void run(); void back(); public int getVelocity(); } package org.o7planning.tutorial.itf; public interface CanDrink { public static final String PEPSI = "PEPSI"; final String NUMBER_ONE = "NUMBER ONE"; String SEVENUP = "SEVEN UP"; public void drink(); } package org.o7planning.tutorial.itf; public interface CanEat { public void eat(); } package org.o7planning.tutorial.cls; import org.o7planning.tutorial.itf.CanMove; public abstract class Animal implements CanMove { @Override public void run() { System.out.println("Animal run..."); } } package org.o7planning.tutorial.cls; import org.o7planning.tutorial.itf.CanDrink; import org.o7planning.tutorial.itf.CanEat; public class Cat extends Animal implements CanEat, CanDrink { private String name; public Cat(String name) { this.name = name; } public String getName() { return this.name; } @Override public void back() { System.out.println(name + " cat back ..."); } @Override public int getVelocity() { return 110; } @Override public void eat() { System.out.println(name + " cat eat ..."); } @Override public void drink() { System.out.println(name + " cat drink ..."); } } 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 ..."); } } package org.o7planning.tutorial.cls; import org.o7planning.tutorial.itf.CanEat; public class AnimalDemo { public static void main(String[] args) { System.out.println("Drink " + Cat.SEVENUP); CanEat canEat1 = new Cat("Tom"); CanEat canEat2 = new Mouse(); canEat1.eat(); canEat2.eat(); boolean isCat = canEat1 instanceof Cat; System.out.println("catEat1 is Cat? " + isCat); if (canEat2 instanceof Mouse) { Mouse mouse = (Mouse) canEat2; mouse.drink(); } } }

Sự Khác Biệt Giữa Abstract Class Và Interface

Cả Abstract class và Interface đều được sử dụng để đạt được sự trừu tượng nơi chúng ta có thể khai báo các phương thức trừu tượng. Cả Abstract class và Interface đều không thể được khởi tạo.

Nhìn chung, chúng khá giống nhau, nhưng có nhiều điểm khác biệt giữa Abstract class và Interface khiến nó được sử dụng ở những trường hợp khác nhau.

Sự khác biệt đơn giản, abstract class có thể đạt được trừu tượng một phần (0 đến 100%) trong khi interface đạt được mức trừu tượng hoàn toàn (100%).

Ghi chú: Nếu bạn đang tích cực học Java, KHÓA HỌC LẬP TRÌNH JAVA với sự hướng dẫn của chuyên gia doanh nghiệp này chắc chắn sẽ giúp bạn học tập nhanh hơn, bài bản hơn.

Ví dụ về Abstract class và Interface trong JAVA

Hãy xem một ví dụ đơn giản trong đó chúng ta đang sử dụng cả interface và lớp trừu tượng.

interface A{ void a(); void b(); void c(); void d(); } abstract class B implements A{ public void c(){ System.out.println("Tôi là C"); } } class M extends B{ public void a(){ System.out.println("Tôi là a"); } public void b(){ System.out.println("Tôi là b"); } public void d(){ System.out.println("Tôi là d"); } } class Test{ public static void main(String args[]){ A a = new M(); a.a(); a.b(); a.c(); a.d(); } }

Kết quả:

Tôi là a Tôi là b Tôi là C Tôi là d Tổng kết

Như vậy là trong và viết này mình đã giúp bạn tìm hiểu rõ sự khác nhau của Abstract class và Interface trong Java.

Sự Khác Biệt Giữa Một Interface Và Một Abstract Class

1

Lớp trừu tượng có thể có các phương thức abstract và non-abstract

Interface chỉ có thể có phương thức abstract

2

Lớp trừu tượng không hỗ trợ đa kế thừa

Interface hỗ trợ đa kế thừa

3

Lớp trừu tượng có thể có các biến final, non-final, static và non-static

Interface chỉ có các biến static và final

4

Lớp trừu tượng có thể có phương thức static, phương thức main và constructor

Interface không thể có phương thức static, main hoặc constructor.

5

Từ khóa abstract được sử dụng để khai báo lớp trừu tượng

Từ khóa interface được sử dụng để khai báo Interface

6

Lớp trừu tượng có thể cung cấp trình triển khai của Interface

Interface không cung cấp trình triển khai cụ thể của lớp abstract

Bỏ qua tất cả những phần về lý thuyết của việc tạo một abstract class và interface. Bạn không cần quan tâm nhiều đến việc abstract có thể khai báo những gì, hay interface có được phép định nghĩa nội dung phương thức hay không. Điểm cơ bản khi bạn được hỏi về sự khác biệt giữa chúng là gì? Đó chính là mục đích mà chúng được sử dụng:

– Abstract class: là một class cha cho tất cả các class có cùng bản chất. Bản chất ở đây được hiểu là kiểu, loại, nhiệm vụ của class. Hai class cùng hiện thực một interface có thể hoàn toàn khác nhau về bản chất.

– Interface: là một chức năng mà bạn có thể thêm và bất kì class nào. Từ chức năng ở đây không đồng nghĩa với phương thức (hoặc hàm). Interface có thể bao gồm nhiều hàm/phương thức và tất cả chúng cùng phục vụ cho một chức năng.

Vậy, bạn không nên nhầm lẫn khi nói về việc một class được implement hay extend. Nhiều người thường hay đồng nhất là không phân biệt hai từ này, nhưng chính chúng đã nói lên sự khác biệt giữa interface và abstract class. Bạn chỉ có thể thừa kế (extend) từ một class và chỉ có thể hiện thực (implement) các chức năng (interface) cho class của mình.

Theo cách ngắn gọn, quan hệ giữa một class khi thừa kế một abstract class được gọi là is-a, và một class khi hiện thực một interface được gọi là can-do (hoặc -able).

Hãy xem ví dụ sau, tôi có:

– Interface: Barkable, Runable, Flyable, Swimable.

– Abstract class Animal và các sub class: Bolt, AngryBird và Nemo.

– Abstract class Machine và các sub class: McQueen, Siddeley.

Như bạn thấy, mặc dù cả McQueen và Bolt đều được hiện thực interface Runable, nhưng chúng hoàn toàn thuộc hai loại khác nhau. Và tất nhiên một class có thể can-do nhiều thứ, ví dụ như Bolt có thể chạy và “bow wow”.

Đây là một điều thường được dùng để trả lời cho hai câu hỏi:

– Interface được dùng để làm gì?

– Tại sao không thể định nghĩa phần thân cho các phương thức của interface.

Xét ở một mức độ nào đó điều này là hợp lý, nhưng như đã nói ở phần trên, nó chỉ được dùng để mô tả một “bản thiết kế” cho một chức năng của class. Nếu muốn tạo một bản thiết kế, hãy sử dụng abstract class. Một bản thiết kế tất nhiên sẽ có những thứ đã được dựng sẵn và có những thứ là abstract.

Một câu trả lời có thể lý giải phần nào câu hỏi thứ hai là việc cho phép định nghĩa thân phương thức trong các interface có thể khiến cho hiệu suất bị giảm sút. Nguyên nhân là việc tìm kiếm các phương thức sẽ diễn ra lâu hơn vì phải duyệt qua các interface, thay vì chỉ cần phải tìm trong class cha của nó.

Về công dụng của interface, xét ở mức ứng dụng, các interface có thể được hiểu như các plugin hoặc thư viện/phần mềm third-party. Việc hiện thực một interface cho class cũng giống như cài thêm plugin cho một phần mềm vậy.

Cuối cùng, cũng nên liệt kê các điểm khác biệt giữa hai khái niệm này để bạn có thể sử dụng được khi cần thiết. Các điểm khác biệt này có thể khác nhau tùy vào ngôn ngữ mà bạn sử dụng. Vì vậy bạn chỉ cần nhớ các điểm căn bản sau: