匿名内部类精讲
匿名内部类适合创建那种只需要一次使用的类,例如命令模式时所需要的Command对象。匿名内部类的语法有点奇怪,创建匿名内部类时会立即创建一个该类的实例,这个类定义立即消失,匿名内部类不能重复使用。
定义匿名内部类的格式如下:
new 父类构造器(参数列表)|实现接口() { //匿名内部类的类体部分 }
从上面定义可以看出,匿名内部类必须继承一个父类,或实现一个接口,但最多只能继承一个父类,或实现一个接口。
关于匿名内部类还有如下两条规则:
1)匿名内部类不能是抽象类,因为系统在创建匿名内部类的时候,会立即创建内部类的对象。因此不允许将匿名内部类
定义成抽象类。
2)匿名内部类不等定义构造器,因为匿名内部类没有类名,所以无法定义构造器,但匿名内部类可以定义实例初始化块,
通过实例初始化块来完成构造器需要完成的事情。
最常用的创建匿名内部类的方式是需要创建某个接口类型的对象,如下程序所示:
interface Product{ public double getPrice(); public String getName(); } public class TestAnonymous{ public void test(Product p){ System.out.println("购买了一个"+p.getName()+",花掉 了"+p.getPrice()); } public static void main(String[]args){ TestAnonymous ta = new TestAnonymous(); ta.test(new Product(){ public double getPrice(){ return 567; } public String getName(){ return "AGP显卡"; } }); } }
上面程序中的TestAnonymous类定义了一个test方法,该方法需要一个Product对象作为参数,但Product只是一个接口,
无法直接创建对象,因此此处考虑创建一个Product接口实现类的对象传入该方法---如果这个Product接口实现类需要重复
使用,则应该经该实现类定义一个独立类;如果这个Product接口实现类只需一次使用,则可采用上面程序中的方式,定义
一个匿名内部类。
正如上面程序中看到,定义匿名类不需要class关键字,而是在定义匿名内部类时直接生成该匿名内部类的对象。上面
粗体字代码部分就是匿名类的类体部分。
由于匿名内部类不能是抽象类,所以匿名内部类必须实现它的抽象父类或者接口里包含的所有抽象方法。
对于上面创建Product实现类对象的代码,可以拆分成如下代码:
class AnonymousProduct implements Product{ public double getPrice(){ return 567; } public String getName(){ return "AGP显卡"; } } ta.test(new AnonymousProduct());
当通过实现接口来创建匿名内部类时,匿名内部类也不能显示创建构造器,因此匿名内部类只有一个隐式的无参数构造
器,故new接口名后的括号里不能传入参数值。
但如果通过继承父类来创建匿名内部类是,匿名内部类将拥有和父类相似的构造器,此处的相似指的是拥有相同的形参
列表。
abstract class Device{ private String name; public Device(){ } public Device(String name){ this.name = name; } public abstract double getPrice(); //此处省略了name属性的setter和getter方法 } public class AnonymousInner{ public void test(Device d){ System.out.println("购买了一个"+d.getName()+",花掉了"+d.getPrice()); } public static void main(String[] args){ AnonymousInner ai = new AnonymousInner(); //调用有参数的构造器创建Device匿名实现类的对象 ai.test(new Device("电子示波器"){ public double getPrice(){ return 67; } }); //调用无参数的构造器创建Device匿名实现类的对象 Device d = new Device(){ //初始化块 { System.out.println("匿名内部类的初始化块..."); } //实现抽象方法 public double getPrice(){ return 56; } public Sting getName(){ return "键盘"; } }; ai.test(d); } }
上面程序创建了一个抽象父类Device,这个抽象父类里包含两个构造器:一个无参数的,一个有参数的。当创建以Device
为父类的匿名内部类时,即可以传入参数(如上面程序中第一段粗体字部分),也可以不传入参数(如上面程序中第二段粗体
字部分)。
当创建匿名内部类时,必须实现接口或抽象父类里的所有抽象方法。如果有需要,也可以重写父类中的普通方法,如上面
程序的第二段粗体字代码部分,匿名内部类重写了抽象父类Device类的getName方法,其中getName方法并不是抽象方法。
如果匿名内部类需要访问外部类的局部变量,则必须使用final修饰符来修饰外部类的局部变量,
否则系统将报错。
interface A{ void test(); } public class TestA{ public static void main(Strign[] args){ int age = 0; A a = new A(){ public void test(){ //下面语句将提示错误:匿名内部类内访问局部变量必须使用final修饰 System.out.println(age); } }; } }
上面程序中粗体子代码是匿名内部类访问了外部类的局部变量,由于age变量没有使用final修饰符修饰,所以粗体字代码将
引起编译异常。
更多匿名内部类精讲相关文章请关注PHP中文网!

Alat AI Hot

Undresser.AI Undress
Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover
Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool
Gambar buka pakaian secara percuma

Clothoff.io
Penyingkiran pakaian AI

AI Hentai Generator
Menjana ai hentai secara percuma.

Artikel Panas

Alat panas

Notepad++7.3.1
Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina
Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1
Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6
Alat pembangunan web visual

SublimeText3 versi Mac
Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Topik panas



Kelas dalaman tanpa nama boleh menyebabkan kebocoran memori Masalahnya ialah mereka memegang rujukan kepada kelas luar, menghalang kelas luar daripada dikumpul. Penyelesaian termasuk: 1. Gunakan rujukan yang lemah Apabila kelas luar tidak lagi dipegang oleh rujukan yang kuat, pemungut sampah akan segera mengitar semula objek rujukan yang lemah memerlukan ingatan semasa pengumpulan sampah Hanya kemudian objek rujukan lembut dikitar semula. Dalam pertempuran sebenar, seperti dalam aplikasi Android, masalah kebocoran memori yang disebabkan oleh kelas dalaman tanpa nama boleh diselesaikan dengan menggunakan rujukan yang lemah, supaya kelas dalaman tanpa nama boleh dikitar semula apabila pendengar tidak diperlukan.

Kelas dalaman tanpa nama ialah kelas dalaman khas dalam Java yang tidak mempunyai nama eksplisit dan dicipta melalui ungkapan baharu Ia digunakan terutamanya untuk melaksanakan antara muka tertentu atau melanjutkan kelas abstrak dan digunakan serta-merta selepas penciptaan. Corak reka bentuk kelas dalaman tanpa nama biasa termasuk: Corak penyesuai: menukar satu antara muka kepada antara muka yang lain. Corak Strategi: Mentakrifkan dan Menggantikan Algoritma. Corak pemerhati: Daftar pemerhati dan kendalikan peristiwa. Ia sangat berguna dalam aplikasi praktikal, seperti menyusun TreeSet mengikut panjang rentetan, mencipta benang tanpa nama, dsb.

Kelas dalaman tanpa nama digunakan di Java sebagai kelas dalaman khas yang memudahkan subkelas, memudahkan kod dan mengendalikan acara (seperti klik butang). Kes praktikal termasuk: Pengendalian acara: Gunakan kelas dalaman tanpa nama untuk menambah pendengar acara klik untuk butang. Transformasi data: Isih koleksi menggunakan kaedah Collections.sort dan kelas dalaman tanpa nama sebagai pembanding.

Kelas dalaman tanpa nama tidak sesuai digunakan apabila: perlu mengakses ahli persendirian, memerlukan berbilang contoh, memerlukan warisan, perlu mengakses jenis generik

Ralat penggunaan kelas dalaman tanpa nama: Mengakses pembolehubah di luar skop menggunakan menangkap pengecualian yang tidak diisytiharkan dalam persekitaran bukan benang selamat

Masalah prestasi kelas dalaman tanpa nama ialah ia dicipta semula setiap kali ia digunakan, yang boleh dioptimumkan melalui strategi berikut: 1. Simpan kelas dalaman tanpa nama dalam pembolehubah tempatan 2. Gunakan kelas dalaman bukan statik; ungkapan. Ujian praktikal menunjukkan bahawa pengoptimuman ekspresi lambda mempunyai kesan terbaik.

Jangka hayat kelas dalam tanpa nama ditentukan oleh skopnya: Kaedah-kelas dalam tempatan: Sah hanya dalam skop kaedah yang menciptanya. Kelas dalaman pembina: terikat kepada contoh kelas luar dan dikeluarkan apabila tika kelas luar dikeluarkan. Kelas dalaman statik: dimuatkan dan dipunggah pada masa yang sama dengan kelas luaran.

Kelas dalaman tanpa nama memudahkan penciptaan kod berbilang benang, menghapuskan keperluan untuk menamakan dan mendayakan definisi segera dan penggunaan kelas benang. Kelebihan utama adalah untuk memudahkan kod, manakala hadnya ialah ia tidak boleh dilanjutkan. Gunakan apabila anda perlu membuat satu atau dua benang dengan cepat. Jika logik yang lebih kompleks diperlukan, fail kelas yang berasingan harus dibuat.
