(1)本质是类
(2)内部类
(3)该类没有名字(名字不是能直接看到的,实际上是系统取的)
(4)同时还是一个对象
new 类或接口(参数列表) {类体
}
public class AnonymouseInnerClass {public static void main(String[] args) {Outer04 outer04 = new Outer04();hod();}
}class Outer04 {//外部类private int n1 = 10;public void method() {//基于接口的匿名内部类//解读://1.需求:使用IA接口,并创建对象//2.传统方式,写一个类,实现该接口,并创建对象IA tiger = new Tiger();();}
}interface IA {//接口public void cry();
}class Tiger implements IA {@Overridepublic void cry() {System.out.println("老虎叫唤...");}
}class Father {public Father(String name) {}public void test() {}
}
如果 Tiger
这个对象只用一次,后面不再使用了,如果再定义一个 Dog
类,而且也只用一次,这种情况下就会定义很多类,这种情况有可能很多只用一次的情况,创建对象浪费资源
解决方案:这个时候就可以使用 匿名内部类 来简化开发
需求:既不去创建 Tiger
对象,又能去调用 Tiger
类中的方法
接口是不能直接 new
的,但是后面重写的方法相当于在 Tiger
类中重写的方法
匿名内部类实现
public class AnonymouseInnerClass {public static void main(String[] args) {Outer04 outer04 = new Outer04();hod();}
}class Outer04 {//外部类private int n1 = 10;public void method() {//1.可以使用匿名内部类来开发//2.tiger的编译类型是 IA//3.tiger的运行类型是 匿名内部类/** 看底层 类名* class XXX implements IA {* @Overridepublic void cry() {System.out.println("老虎叫唤...");}* }* XXX = Outer04$1* * 系统会分配 类名 Outer04$1**/// 4. jdk底层在创建匿名内部类 Outer04$1 ,马上就创建了 Outer04$1 实例,并且把地址返回给 tiger // 5. 匿名内部类使用一次,就不能再使用了IA tiger = new IA(){@Overridepublic void cry() {System.out.println("老虎叫唤...");}};();System.out.println("tiger运行类型=" + Class());}}interface IA {//接口public void cry();
}
Outer04$1
,马上就创建了 Outer04$1
实例,并且把地址返回给 tiger
,匿名内部类使用一次,就不能再使用了。但是 tiger 对象可以使用。class XXX implements IA {@Overridepublic void cry() {System.out.println("老虎叫唤...");}}XXX 类名 = Outer04$1
就是等于在外部类的基础上 加上 $1
class XXX implements IA {@Overridepublic void cry() {System.out.println("老虎叫唤...");}
}
System.out.println("tiger运行类型=" + Class());
XXX
类名为 Outer04$1
,是系统分配的类名。jdk底层在创建匿名内部类 Outer04$1 ,马上就创建了 Outer04$1
实例,并且把地址返回给 tiger
案例演示:基于类的匿名内部类的实现
//分析
//1.father编译类型 Father
//2.father运行类型 Outer04$2
//3.底层会创建匿名内部类
/*class Outer04$2 extends Father{@Overridepublic void test() {System.out.println("匿名内部类重写了test()");}}*/
//4,同时也直接返回了 匿名内部类 Outer04$2 的对象
Father father = new Father("jack"){@Overridepublic void test() {System.out.println("匿名内部类重写了test()");}
};System.out.println("father运行类型=" + Class());
st();class Father {public Father(String name) {}public void test() {}
}
也可以直接查看的到匿名内部类的类名
基于抽象类的匿名内部类,编译类型是 Animal
,运行类型是匿名内部类
//基于抽象类的匿名内部类
Animal animal = new Animal(){@Overridevoid eat() {System.out.println("小狗吃骨头...");}
};
animal.eat();
//查看系统分配给匿名内部类的 类名abstract class Animal {abstract void eat();
}
public class AnonymousInnerClassDetail {public static void main(String[] args) {Outer05 outer05 = new Outer05();outer05.f1();}
}class Outer05 {private int n1 = 99;public void f1() {//创建一个基于类的匿名内部类Person person = new Person(){@Overridepublic void hi() {System.out.println("匿名内部类重写了 hi 方法");}};person.hi(); //动态绑定,运行类型是 Outer05$1//也可以直接调用, 匿名内部类本身也是返回对象// class 匿名内部类 extends Person{}new Person(){@Overridepublic void hi() {System.out.println("匿名内部类重写了 hi 方法,1111");}@Overridepublic void ok(String str) {super.ok(str);}}.ok("xdr");}
}
class Person {public void hi() {System.out.println("Person hi()");}public void ok(String str) {System.out.println("Person ok()" + str);}
}
public class AnonymousInnerClassDetail {public static void main(String[] args) {Outer05 outer05 = new Outer05();outer05.f1();}
}class Outer05 {private int n1 = 99;public void f1() {//创建一个基于类的匿名内部类Person person = new Person(){@Overridepublic void hi() {//可以直接访问外部类的所有成员,包含私有的System.out.println("匿名内部类重写了 hi 方法 n1=" + n1);}};person.hi(); //动态绑定,运行类型是 Outer05$1class Person {public void hi() {System.out.println("Person hi()");}
}
不能添加访问修饰符,因为它的地位就是一个局部变量。
作用域:仅仅在定义它的方法或代码块中。
匿名内部类——>访问——>外部类成员【访问方式:直接访问】
外部其他类——不能访问——>匿名内部类【因为匿名内部类地位是一个局部变量】
如果外部类和匿名内部类的成员重名时,匿名内部类访问的话,默认遵循就近原则如果想访问外部类的成员,则可以使用【外部类名.this.成员
】去访问
如果想访问同名外部类的话,可以使用 【外部类名.this.成员
】去访问
上面的 Outer05.this
就是调用 f1
的对象,谁调用 f1
对象,这个 Outer05.this
就是谁
可以看到都是同一个对象,所以对象外部类去访问 n1 ,指的就是外部类的属性
public class InnerClassExercise01 {public static void main(String[] args) {//传统方法f1(new Picture());}//静态方法,形参是接口类型public static void f1(IL il) {il.show();}
}//类->实现IL => 编程领域 (硬编码)
class Picture implements IL {@Overridepublic void show() {System.out.println("这是一副名画...");}
}
public class InnerClassExercise01 {public static void main(String[] args) {//当做实参直接传递,简洁高效f1(new IL() {@Overridepublic void show() {System.out.println("这是一副名画~~...");}});}//静态方法,形参是接口类型public static void f1(IL il) {il.show();}
}
//接口
interface IL {void show();
}
1.有一个铃声接口Bell,里面有个ring方法。(右图)
2. 有一个手机类Cellphone,具有闹钟功能alarmclock,参数是Bell类型(如下图)
3. 测试手机类的闹钟功能,通过匿名内部类(对象)作为参数,打印:懒猪起床了
4. 再传入另一个匿名内部类(对象),打印:小伙伴上课了
public class InnerClassExercise02 {public static void main(String[] args) {CellPhone cellPhone = new CellPhone();//解读://1. 传递的是实现了 Bell接口的匿名内部类 InnerClassExercise02$1//2. 重写了 ring//3. Bell bell = new Bell() {// @Override// public void ring() {// System.out.println("懒猪起床了");// }// }cellPhone.alarmClock(new Bell() {@Overridepublic void ring() {System.out.println("懒猪起床了");}});cellPhone.alarmClock(new Bell() {@Overridepublic void ring() {System.out.println("小伙伴上课了");}});}
}
interface Bell{ //接口void ring();//方法
}
class CellPhone{//类public void alarmClock(Bell bell){//形参是Bell接口类型System.out.Class());bell.ring();//动态绑定}
}
本文发布于:2024-01-29 17:13:23,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/170651960516949.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |