30/09/2018, 18:01

Câu hỏi về Interface và abstract trong Java?

Mình mới học java tới phần này thấy nó khá lằng nhằng
mình muốn hỏi : mình hiểu interface như thế này có đúng ko

  1. interface dùng như 1 bản thiết kế (chỉ mô tả khái quát không cụ thể) , 1 giao ước bắt buộc các lớp mà implement nó phải thực hiện , định nghĩa các ràng buộc đó (dùng để dể quản lý khi làm các dự án lớn)
    2.interface nó giúp ta giải quyết vấn đề đa thừa kế trong java , trong và java nó ko cho phép đa thừa kế , vì vậy nếu 1 lớp muốn có nhiều chức năng từ những lớp khác thì ta dùng interface để bổ sung các chức năng đó
    3.interface nó là tập hợp các phương thức có nhiệm vụ thực hiện 1 chức năng nào đó và nó thực chất cũng là 1 chức năng , bất cứ lớp nào cũng có thể implement 1 hay nhiều interface

còn abstract bản chất là 1 lớp trừu tượng trong đó có thể có 1 hoặc nhiều phương thức được khai báo abstract

lớp abstract không giải quyết đc vấn đề đa thừa kế , nhưng nó có ưu điểm hơn interface là khi hoạt động nó sẽ chạy nhanh hơn (hix vì sao???)

mình muốn hỏi nữa là khi nào nên dùng interface , khi nào nên dùng abstract???

so sánh giữa extends và implement ???

còn mấy câu nữa nhưng ko nhớ hết…@@

Itachi Citus viết 20:03 ngày 30/09/2018

Interface không phải là một bản thiết kế, nó là một giao ước hay một hợp đồng, yêu cầu các lớp implement nó phải có những chức năng này.

Abstract classlà một lớp trừu tượng, trừu tượng nghĩa là… không có thực, hay object của nó không có ý nghĩa. Lớp abstract hoàn toàn có thể không có bất cứ một phương thức abstract nào nha bạn.

Nó liên quan đến tư tưởng thiết kế hơn là về mặt chức năng. Tên những interface thường là tính từ, Runnable, Throwable hoặc một “giao diện”, một từ đặc tả một nhóm chức năng nào đó… Còn tên của abstact class là các danh từ, nhưng những danh từ này ko có object có ý nghĩa trên thực tế, như Animal.

Interface bạn cần phân biệt với class: Tính từ >< Danh từ hay tính chất >< Loại. Còn Abtract class bạn cần phân biệt với Conrete class: Không có thực / đối tượng không có ý nghĩa >< Có thực/ đối tượng có ý nghĩa. Không nên xem interface và abstract class là hai thứ gần nhau.

Reoteu Ray viết 20:16 ngày 30/09/2018

hix rắc rồi vc…abstract class là 1 lớp trừu tượng nghĩa là ko có thực , obj nó ko có ý nghĩa là sao hả bạn .

vậy trong abstract class ta viết 1 abstract constructor có đc hay không

Còn 1 abstract class mà không chứa field chỉ chứa toàn là abstract method thì nó có giống với 1
interface ko

1 interface mà toàn chứa abstract method thì nó gọi là gì , tính chất thế nào

ý bạn là interface thể hiện tính chất , còn class thể hiện loại , vậy class abstract thể hiện gì loại hay tính chất

mà vì sao lại ko nên xem interface và abstract class gần nhau ,

khi nào dùng interface khi nào dùng abstract class???

Itachi Citus viết 20:04 ngày 30/09/2018

À lúc nãy mình có nhầm lẫn tí… mới sửa lại…

hix rắc rồi vc…abstract class là 1 lớp trừu tượng nghĩa là ko có thực , obj nó ko có ý nghĩa là sao hả bạn .

Không có thực chẳng hạn như Animal (ví dụ cổ điển), không có object nào là Animal được hết á, không có con nào là con Animal cả, nhưng nó vẫn là một loại, vẫn có thể coi là một lớp được. Còn những con Dog hay Cat là những concrete class và nó có thực. Trong lập trình, chẳng hạn bạn cần quản lý sinh viên, thì HocVien nên là Abstract, còn SinhVienChinhQuy, SinhVienCaoDang, HocVienCaoHoc là concrete.

Còn 1 abstract class mà không chứa field chỉ chứa toàn là abstract method thì nó có giống với 1 interface ko

Không.

1 interface mà toàn chứa abstract method thì nó gọi là gì , tính chất thế nào

Đa số interface chỉ chứa abstract method. java 6 hay java 7 trở xuống interface chỉ chứa abstract method.

ý bạn là interface thể hiện tính chất , còn class thể hiện loại , vậy class abstract thể hiện gì loại hay tính chất

Uhm chỗ này mình nhầm, interface nhằm chỉ ra có thể thực hiện những gì, hay nói nôm na là có hỗ trợ ít nhất những method gì, chẳng hạn như interface List là có thể hoạt động như một danh sách; còn class thể hiện loại, chẳng hạn như HocVien ở ví dụ trên.

mà vì sao lại ko nên xem interface và abstract class gần nhau ,

khi nào dùng interface khi nào dùng abstract class???

Hai câu này dài quá, để người khác vậy

Van Huong viết 20:16 ngày 30/09/2018

Cái này phải làm nhiều thực tế mới “thấm”, chứ giải thích cũng khó hết được.
Nhưng tôi xin gợi ý bạn một số thứ có thể tham khảo:

  1. Theo dõi 2 video đầu tiên trong links sau đây để nắm được khái niệm cơ bản của OOP trong Java, trong đó có ví dụ đề cập interface và abstract class: https://www.youtube.com/playlist?list=PLF206E906175C7E07

  2. Bạn muốn so sánh 2 cái này, google “interfaces vs abstract class + java”, có thể tham khảo kết quả: http://www.javatpoint.com/difference-between-abstract-class-and-interface

  3. Theo kinh nghiệm cá nhân của tôi đã có làm một số dự án với Java (mà thực ra tôi chỉ biết mỗi Java thui. ;)). Các khái niệm interfaces và abstract class trong Java, mục đích thực chất là tránh duplicate code (code bị lặp lại) trong lập trình (DRY - Don’t Repeat Yourself rule).

Tùy mục đích sử dụng mà mình có thể chọn interface hay abstract class cho phù hợp. Điểm đáng lưu ý nhất là inteface thì không chứa non-abstract methods (hàm mà có mã thực thi) còn abstract class thì có đấy (xem link ở mục 2. nhé)

Thứ nhất, tôi hay dùng inteface rất nhiều để giải quyết vấn đề duplicated code với Generics. Ví dụ hơi dài, bạn gán theo dõi nhé

Tôi có 2 class là HelpText và Section, mỗi class đều có thuộc tính riêng của nó, nhưng có chung 1 điểm đều có thuộc tính “name” kiểu String, nhưng lại khác tên biến.

class HelpText{
 private String id;
 private String name;
//getters, setter
}

class Section{
private String id;
private String displayName;
//getters, setters
}

Bài toán đặt ra là viết một hàm để tạo một tên mới cho “name” khi tạo mới 1 object HelpText hay Section. Thông thường bạn sẽ có 2 hàm như vầy:

class GeneratingNameUtils{
    public static String generateUniqueName(Helptext helpText, List<HelpText> helpTexts){
     //implement ở đây và return
     return helpText.name+ "<một nùi gì đó dựa vào cái list helpTexts>";
    }
    
    public static String generateUniqueName(Section section, List<Section> sections){
     //implement ở đây và return
     return section.displayName+ "<một nùi gì đó dựa vào cái list sections>";
    }
}

Rõ ràng là đã xảy ra duplicated code, có sự giống nhau phần implementation chỉ khác nhau class truyền vào giữa 2 hàm trên. Tôi sẽ dùng interface và Generic để giải quyết vấn đề này chỉ với 1 hàm chung.

public interface IUniqueName{
    public String getUniqueName();
}
  
class HelpText implements IUniqueName{
   private String id;
   private String name;
  //getters, setter
  
   public String getUniqueName()  {
     return name;
   } 
 }
      
class Section implements IUniqueName{
  private String id;
  private String displayName;
  //getters, setters
  public String getUniqueName()  {
     return displayName;
  } 
}

class GeneratingNameUtils{
	public static <T> String generateUniqueName(T item, List<T extends IUniqueName> items){
	//implement
 // HelpText hay Section bây giờ đều có  getUniqueName() --> tính đa hình đấy
	return item.getUniqueName() + "<một nùi gì đó dựa vào cái list items>";
	}
}

Có thể code trên bị lỗi syntax, tôi không chắc lắm do lỗi lỗi đánh máy. Cái này là bài toán thực tế trong project của tôi, bạn có thể tham thảo ý tưởng ở đây nhé: http://vhandit.blogspot.com/2015/08/snippet-generate-new-unique-name-string.html. (PR blog ) .

Thứ 2, dùng astract class thì cũng tương tự với vấn đề duplicate code. Bây giờ tôicó 2 class mà trong mỗi class bạn có method y chang nhau luôn. Tôi quyết định dùng một class mới là superclass để chứa các method chung này. Ví dụ

 class A1{
    public void methodA(){
    //code a
    //có gọi methodB();
    }
    
    public void methodB();
    //code b
    }
 }

 class A2{
    public void methodA(){
    //code a
    //có gọi methodB();
    }
    
    public void methodB(){
    //code b1
    }
 }

Bạn thấy rằng cả 2 class A1 và A2 có có phần //code a là y chang chỉ khác mỗi chổ method B() (//code b và //code b1). Bây giờ tôi sẽ dùng abstract class để giải quyết vấn đề này.

class abstract A{
 //non-abstract method
  public void methodA(){
    //code a
    //có gọi methodB();
  }
  
 //abstract method
  public abstract void methodB();

}

class A1 extends A{
    public void methodB();
    //code b
    }
 }

 class A2  extends A{
    public void methodB(){
    //code b1
    }
 }

Okay! Bây giờ A1 và A2 đều có thể sử dụng methodA() mà không cần suy nghĩ đến nước Mỹ, chỉ cần viết phần implement cho methodB() thui, hết duplicated code nhé.

Thêm nữa, dựa vào interface và abstract class người ta build rất nhiều pattern (Design Pattern) rất hay. Bạn có thể tham khảo pattern đơn giản này để hiểu rõ hơn về abstract class: http://www.tutorialspoint.com/design_pattern/chain_of_responsibility_pattern.htm. Thật ra, tôi thấy mục đích chính của mấy cái này vẫn là DRY. hehe.

Reoteu Ray viết 20:04 ngày 30/09/2018

cảm ơn bạn nha…cho mình hỏi vậy trong tư duy lập trình hướng đối tượng thì đối tượng có trước hay class có trước hay nói cách khác là ta đi từ đối tượng đến lớp hay ta đi từ lớp rồi đến đối tượng , vd : mở 1 shop quần áo thì ta nhóm các kiểu quần khác nhau lại thành lớp quần các kiểu áo khác nhau lại thì kiểu áo…vậy giống như là đi từ đối tượng rồi mới tạo ra lớp vậy…???

vũ xuân quân viết 20:09 ngày 30/09/2018

cái này thì thuộc về phân tích hướng đối tượng rồi.
Em đi làm nhiều năm mới biết được.
Thường thì đi từ đối tượng mới tạo ra class.

Van Huong viết 20:15 ngày 30/09/2018

Tôi cũng nghĩ như @masoivn, tôi cũng nghĩ đó là lĩnh vực phân tích hệ thống hướng đối tượng (Object-oriented analysis and design), đây sẽ làm một trong những môn cơ bản mình sẽ được học ở trường. Có thể bạn sẽ phải tìm hiểu về lĩnh vực này thêm rồi.

Tuy nhiên, nếu nói như cách của bạn:

mở 1 shop quần áo thì ta nhóm các kiểu quần khác nhau lại thành lớp quần các kiểu áo khác nhau lại thì kiểu áo…vậy giống như là đi từ đối tượng rồi mới tạo ra lớp vậy…???

Tôi không nghĩ “kiểu quần” khác nhau (Quần jean, quần kaki, quần short, v.v) là những objects và “Quần”
là một class. Tôi nghĩ nếu là tôi khi implement với Java, Quần jean là 1 class, quần kaki là 1 class, v.v. Còn 1 đối tượng phải là 1 cái Quần jean cụ thể trong các cái quần jean. “Quần” lúc này thường sẽ là 1 abstract class.

Tóm lại, ở thời điểm này tôi cũng đồng ý là đi từ phân tích đối tượng trước (lúc phân tích) rồi mình sẽ có class (lúc code) là đúng.

Thành Phạm viết 20:02 ngày 30/09/2018

Bạn có thể đọc thêm bài viết này, rất là hay

YinYang's Programing Blog – 15 Jan 12

OOP – Interface vs Abstract class

Hiện nay mặc dù OOP đã rất phổ biến nhưng đa số vẫn còn khá mơ hồ trong việc phân biệt và định nghĩa hai khái niệm Interface và Abstract class. Có vẻ vấn đề này không được dạy rõ ràng ở trường, hoặ…

Một vài ý chí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).

  • 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.
  • Dùng Interface như một “bản thiết kế” của class?
    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.

bongtoi viết 20:09 ngày 30/09/2018

bây giờ e có bài toán là quản lý của hàng, yêu cầu là có sử dụng interface và abstract, cụ thể gồm các thông tin như sau:

  1. Sản Phẩm: tên, mã, chủng loại, giá, mô tả;
  2. Khách hàng: tên, mã, địa chỉ, số DT
  3. khách hàng sẽ có 1 số thao tác: tìm kiếm sản phẩm, xem thông tin …

vậy chỗ nào nên sử dụng interface, chỗ nào nên sử dụng abstract vậy các pro

Demon Hunter viết 20:04 ngày 30/09/2018

@smookiekins_2 bạn vẫn chưa hiểu về abtract và interface, ví dụ của bạn đưa ra là khái niệm generic thui. Hiểu nôm na là thế này.

  • Interface dùng để đặc tả một nhóm chức năng, thường bạn lên kiến trúc của hệ thống viết interface giúp bạn có cái nhìn tổng quan (đối tượng đó cần có những chức năng gì). Giống như một cái khung để bạn mường tượng mình cần làm những gì, sau đó rồi mới implement nó, ngoài ra dùng interface giúp giới hạn truy cập phương thức tức chìa cái j thì dùng cái đó.
  • Abstract là lớp trườu tượng, gôm nhóm các đối tượng có cùng tính chất(tham số), hành động (hàm, chức năng).

Chỉ cần nắm vậy là đủ không cần cao siêu hơn làm j.

Van Huong viết 20:05 ngày 30/09/2018

À, tôi chỉ đưa ra một use-case thôi. . Về mặt thiết kế hệ thống thì tôi cũng đồng ý với @DemonHunter về cách đưa ra khái niệm “nôm na” mang tính cốt lõi của bạn. Gần giống ý của @thanhmssl10

Thanh Nguyễn viết 20:16 ngày 30/09/2018

Theo mình thì Sản phẩm dùng abstract class, vì Sản phẩm nó chung chung, không cụ thể. Sau khi tạo abstract class Sản phẩm thì mình sẽ có những class cụ thể như : xà bông, gạo, trứng…
Còn interface thì là Khách hàng vì nó mô tả Khách hàng sẽ có những hành vi gì, ví dụ như bài tập : tìm kiếm, xem thông tin… Khách hàng nó cũng chung chung, không cụ thể, sau đó mình tạo instance của Khách hàng như là : nội trợ, học sinh, nhân viên văn phòng… để những người này override lại các chức năng của interface Khách hàng.
Trên đây là ý kiến của mình, mình cũng có thắc mắc giống như mọi người. Mong mọi người đóng góp ý kiến

Bài liên quan
0