详述:java匿名内部类

一、内部类的产生原因及其分类:

1.每个内部类都能独立地继承自一个(接口的)实现,所以无论外围类是否已经继承了某个(接口的)实现,对于内部类都没有影响。内部类使得多重继承的解决方案变得完整。接口解决了部分问题,而内部类有效地实现了“多重继承”。
2.内部类可以分为四种:它们分别是:1.成员内部类,2.方法内部类,3.匿名内部类,4.静态嵌套类。本文主要讲解匿名内部类。

二、匿名内部类的定义以及实例化

1.匿名内部类,即没有名字的内部类,因此它不能单独存在,定义匿名内部类的同时需直接实例化该类,语法格式如下:
new 父类构造器([参数列表])|接口(){
//匿名内部类类体
}
代码示例如下:

public class Mammal {	
	public void move() {
	};
	public void eat() {	
	};
}
public class Main {

	public static void main(String[] args) {
		Mammal sheep = new Mammal() {
			public void eat() {
				System.out.println("羊在吃草。");
			}
		};	//此处定义匿名内部类的同时也实例化了匿名内部类
	}
}

三、抽象类与接口的匿名内部类:

1.抽象类的匿名内部类相当于该类的子类。
eg:

public abstract class Mammal {
	public abstract void move();
	public abstract void eat();
}
public class Main {

	public static void main(String[] args) {
		Mammal sheep = new Mammal() {
			public void eat() {
				System.out.println("羊在吃草。");
			}
			public void move() {
				System.out.println("羊在奔跑。");
			}
		};//定义时必须重写父类中的所有方法,否则会报错,由此可见该匿名内部类是其父类(这个抽象类)的子类
	}
}

2.接口的匿名内部类实质是该接口的实现类:
eg:

public interface IMammal {
	public abstract void move();
	public abstract void eat();
}
public class Main {

	public static void main(String[] args) {
		IMammal sheep = new IMammal() {
			public void eat() {
				System.out.println("羊在吃草。");
			}
			public void move() {
				System.out.println("羊在奔跑。");
			}	
		};//定义时必须重写接口中的所有方法,否则会报错,由此可见该匿名内部类是其接口(这个抽象类)的实现类
	}
}

四、匿名内部类的特点:

1.匿名内部类一定是接口的实现类(该实现类仅能实现一个接口)或类(普通类或抽象类)的子类,其中new 关键字后面的类名或接口名即是该匿名内部类继承的父类或实现的接口;
2.匿名内部类不能自定义构造方法,但是可以通过非静态代码块初始化成员变量;
3.匿名内部类一定不能是抽象类;
4.可以在匿名内部类中添加新的属性和方法,但是这些属性和方法不能被上转型对象所调用,只能被非上转型对象方式创建的匿名内部类对象所调用,eg:

public interface IMammal {
	public abstract void move();
	public abstract void eat();
}
public class Main {

	public static void main(String[] args) {
		IMammal sheep = new IMammal() {//sheep为上转型对象;
			public void eat() {
				System.out.println("羊在吃草。");
			}
			public void move() {
				System.out.println("羊在奔跑。");
			}
			public void sleep() {
				System.out.println("羊在睡觉。");
			}		
		};
		sheep.sleep();//此处无法调用新增的sleep()方法,因此会报错
	}
}

正确的调用方法为:


		new IMammal() {
			public void eat() {
				System.out.println("羊在吃草。");
			}
			public void move() {
				System.out.println("羊在奔跑。");
			}
			public void sleep() {
				System.out.println("羊在睡觉。");
			}		
		}.sleep();
		
发布了10 篇原创文章 · 获赞 2 · 访问量 168

猜你喜欢

转载自blog.csdn.net/weixin_44785966/article/details/105249620