目录
相关参考链接:https://blog.csdn.net/weixin_45861283/article/details/119344772
1.介绍
使用 Java 编程时,常常需要创建不会被再次使用的对象。在这种情况下,非常适合使用一种特殊的内部类:匿名内部类。这种类没有名称,是在同一条语句中声明和创建的。
要使用匿名内部类,可将引用对象的代码替换为关键字 new、对构造函数的调用以及用大括号({和})括起的类定义。
既然是匿名类,所以你无法在别的地方实例化和使用这个类。
匿名内部类也可用于接口(interface)的实现使用匿名内部类可以大大减少代码量
匿名对象:没有名字的对象。 new ClassName().run();
非匿名对象:含有名字的对象。 ClassName c=new ClassName(); c.run();
2.基于抽象类的匿名内部类
示例1:
abstract class Person{
public abstract void eat();
public void sleep(){
System.out.println("去睡觉吧");
}
}
//常规来讲,新建一个类,去继承抽象类,然后实例化继承抽想类的类
//class Man extends Person{
// @Override
// public void eat() {
// System.out.println("吃饭了");
// }
//}
public class Demo01_abstract {
public static void main(String[] args) {
//少些一个类,减少代码量
Person person = new Person() {
@Override
public void eat() {
System.out.println("吃大餐");
}
};
person.eat();
person.sleep();
}
}
示例2:
abstract class Animal{
public abstract void call();
public abstract void play();
}
public class Demo02_abstract_2 {
public static void main(String[] args) {
new Animal(){
@Override
public void call() {
System.out.println("大声叫");
}
@Override
public void play() {
System.out.println("别老想着玩");
}
}.call();//有其他方法需要再 new
new Animal(){
@Override
public void call() {
System.out.println("小声叫");
}
@Override
public void play() {
System.out.println("怎么能不想着玩");
}
}.play();
}
}
3.基于接口匿名内部类
示例1:
interface A{
void Test();
}
public class Demo03_interface {
public static void main(String[] args) {
// A a = new A(){
//
// @Override
// public void testA() {
// System.out.println("嘻嘻");
// }
// };
// a.testA();
new A(){
@Override
public void Test() {
System.out.println("扶额");
}
}.Test();
// ((A) () -> System.out.println("扶额")).Test();
}
}
示例2
class Student {
String name;
int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
public class Demo04_interface_main {
public static void main(String[] args) {
// Set<Student> set = new TreeSet<>((o1, o2) -> {
// int num = o1.age - o2.age;
// return num;
// });
Set<Student> set = new TreeSet<>(new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
int num = o1.age - o2.age;
return num;
}
});
set.add(new Student("王强", 23));
set.add(new Student("永新", 19));
set.add(new Student("赵高", 18));
set.add(new Student("运绝", 28));
set.add(new Student("龙发", 36));
System.out.println(set);
}
}
注意:一个方法参数就是一个接口对象,不用再新建一个类去实现这个接口,直接方法中去new 接口
示例3:
interface B {
void eat();
}
public class Demo5 {
public static void main(String[] args) {
test(new B() {
@Override
public void eat() {
System.out.println("吃大餐");
}
});
}
public static void test (B b) {
b.eat();
}
}
4.内部类
在一个类的内部再定义一个类,那么此时这个类就称之为内部类。
特点:
1.内部类可以直接访问外部类的成员,包括私有成员
2 外部类要访问内部类的成员(成员变量,成员方法),必须要建立内部类的对象
class MemberDemo{
String name = "王五";
int age = 20;
public void play(){
System.out.println("打篮球");
}
class Inner{ //就是成员内部类 (在方法外,在类中)
String name = "李小名";
public void test(){
play(); //可以在内部类中调用外部类的方法
System.out.println(age);//20
System.out.println(name);//李小名
//访问外部特定的属性:类名.this.属性
System.out.println(MemberDemo.this.name);//王五
//test(); //死循环
}
}
}
public class Demo01 {
public static void main(String[] args) {
//成员内部类的 创建步骤
//1.实例化外部类的类对象
MemberDemo memberDemo = new MemberDemo();
//2.实例化内部类对象,但是new得改为 外部对象.new
MemberDemo.Inner inner = memberDemo.new Inner();
inner.test();
}
}
//输出结果
打篮球
20
李小名
王五