Java Anonymous Class
Anonymous Class là gì? Anonymous Class là một loại class trong Java, trong đó các class này không được định nghĩa tên ở cú pháp, tên của chúng chỉ được sinh ra do quá trình biên dịch mã nguồn. Sử dụng Anonymous Class giúp code ngắn gọn và súc tích. Kĩ thuật này cho phép khởi tạo và định nghĩa ...
Anonymous Class là gì?
Anonymous Class là một loại class trong Java, trong đó các class này không được định nghĩa tên ở cú pháp, tên của chúng chỉ được sinh ra do quá trình biên dịch mã nguồn.
Sử dụng Anonymous Class giúp code ngắn gọn và súc tích. Kĩ thuật này cho phép khởi tạo và định nghĩa class cùng lúc hay cụ thể là bạn viết định nghĩa lớp ngay tại nơi sử dụng nó.
Cách dùng Anonymous Class
Khi sử dụng Anonymous class, do lớp không được định nghĩa từ trước nên trong cú pháp cần gọi method new(...) để khởi tạo một đối tượng Anonymous.
Anonymos Class được sử dụng dưới 3 hình thức:
- Local class
- Local inner class
- Interface
** SỬ DỤNG LOCAL CLASS **
abstract class Person{ abstract void eat(); } public class TestAnonymousInner{ public static void main(String args[]){ Person p=new Person(){ void eat(){System.out.println("nice fruits");} }; p.eat(); } }
output: nice fruits
Một đối tượng Person được tạo mà không cần định nghĩa trước class. Thay vì viết riêng class Person, sau đó khởi tạo 1 đối tượng và gọi method eat() như thông thường, object Person được định nghĩa ngay lúc sử dụng.
Decode mã sau khi biên dịch, thu được kết quả sau:
( Có thể tham khảm decomplile file class của project bằng Java Decompiler. http://jd.benow.ca)
import java.io.PrintStream; static class TestAnonymousInner$1 extends Person { TestAnonymousInner$1(){} void eat() { System.out.println("nice fruits"); } }
Sau khi compile, Anonymous đã được định nghĩa tên TestAnonymousInner. Lớp này thừa kế từ lớp cha Person.
Trường hợp lớp cha không viết dạng abtract, lúc đó, ở đối tượng dùng Anonymous Class có thể override lại bất kì method của lớp cha. Tuy nhiên nếu sự thay đổi giưã lớp con và lớp cha nhỏ, số hàm cần override ít thì mới nên sử dụng Anonymous, còn lại cần tách riêng thành class để dễ maintain mã về sau.
** SỬ DỤNG LOCAL INNER CLASS **
public class localInner1{ private int data=30;//instance variable void display(){ class Local{ void msg(){System.out.println(data);} } Local l=new Local(); l.msg(); } public static void main(String args[]){ localInner1 obj=new localInner1(); obj.display(); } }
output: nice fruits
File sau khi biên dịch
import java.io.PrintStream; class localInner1$Local { final localInner1 this$0; localInner1$Local() { super(); this$0 = Simple.this; } void msg() { System.out.println(localInner1.access$000(localInner1.this)); } }
Tạo một lớp bên trong method của class localInnerl. Khi đó trình biên dịch sẽ định nghĩa tên cho class Anonymous localInner1$Local(), lớp này tham chiếu đến lớp ngoài (outer) LocalInner1.
** SỬ DỤNG INTERFACE **
interface Eatable{ void eat(); } class TestAnnonymousInner1{ public static void main(String args[]){ Eatable e=new Eatable(){ public void eat(){ System.out.println("nice fruits");} }; e.eat(); } }
Tương tự như trên, Eatable định nghĩa hàm eat() và được gọi lúc sử dụng. Xem code sau khi compile:
import java.io.PrintStream; static class TestAnonymousInner1$1 implements Eatable { TestAnonymousInner1$1(){} void eat(){ System.out.println("nice fruits");} }
output: nice fruits
Lưu ý do sử dụng interface nên giống với trường hợp local class là abstract, mọi method của đối tượng Anonymous đều phải được định nghĩa lại. Khi implement một interface phức tạp về hàm và số lượng hàm, hãy sử dụng class extend thay vì Anonymous.
**Như vậy ưu điểm của Anonymous Class: **
Thay vì sử dụng extends class, Anonymous Class có ưu điểm riêng. Trong các trường hợp trên, lớp Anonymous được viết ngay trong method của class khác, sử dụng ngay lúc định nghĩa xong. Do vậy nên sử dụng Anonymous Class khi đối tượng chỉ được dùng một lần.
Thêm nữa Anonymous phù hợp trong trường hợp cần tạo đối tượng con, trong đó method viết lại từ lớp cha là ít, và đơn giản. Lúc đó code sẽ đơn giản hơn.
**Các điểm lưu ý khi sử dụng Anonymous Class: **
Anonymous luôn luôn được thừa kế từ 1 lớp cha hoặc implement từ một interface.
Vì không định nghĩa class cho mình, nên Anonymous không có contrucstor để khởi tạo chính nó. Đây là nhược điểm của Anonymous. Mọi tham số truyền vào lúc khởi tạo 1 instance Anonymous luôn được truyền vào contructor của lớp cha để khởi tạo.