700 字
4 分钟
内部类
有一种类是被定义在某一个类中的(类中类)称为内部类
Inner Class
如果一个类定义在某一个类的内部,这个类就是 Inner Class
class Outer{ class Inner{ //这里定义了一个内部类 }}在这里 Outer是一个普通类,而 Inner是一个内部类,Inner Class的实例(对象)不能单独存在,必须依附于一个 Outer类的实例存在
public class Main { public static void main(String[] args) { Outer outer = new Outer("Nested"); // 实例化一个Outer Outer.Inner inner = outer.new Inner(); // 实例化一个Inner inner.hello(); }}观察上述代码,要实例化一个 Inner,必须首先创建一个 Outer的实例,然后,调用 Outer实例的 new来创建 Inner实例:
Outer.Inner inner = outer.new Inner();匿名内部类 Anonymous Class
匿名内部类是一种没有名字的内部类,它可以直接在声明和实例化时定义。匿名内部类通常用于简化代码,特别是在实现接口或继承类时 匿名内部类的语法结构如下:
new SuperType() { // 重写方法或实现接口方法};以下是一完整使用匿名内部类实现接口的例子:
public class Main { public static void main(String[] args) { Outer outer = new Outer("Nested"); //创建了一个外部类的实例,并使用构造函数传入name参数 outer.asyncHello(); //调用outer类中使用匿名内部类实现的asyncHello方法 }}
class Outer { private String name;
Outer(String name) { //构造方法 this.name = name; }
void asyncHello() { Runnable r = new Runnable() { //匿名内部类 @Override public void run() { //这里覆写实现Runnable接口中的run抽象方法 System.out.println("Hello, " + Outer.this.name); } }; new Thread(r).start(); //启动新线程 }}NOTE在
Main()中outer.asyncHello()的这里调用的是Outer类的实例方法asyncHello(),而不是直接调用匿名内部类的方法
asyncHello()内部的内容:
- 在
asyncHello()方法内部,创建了一个匿名内部类,这个类实现了Runnable接口,并重写了其run方法。 Runnable r = new Runnable() { ... }:这里定义了一个匿名内部类并将其实例化,赋值给变量r。Outer.this.name:在匿名内部类中,通过Outer.this.name访问外部类Outer的实例变量name。
可以理解为匿名内部类把(将接口转为类、再将类实例化为对象)两个步骤直接简化,在将接口实例化的时候,因为接口已经实现了好了,并直接赋值给某变量,也就跳过了变成类的步骤,没有类名
因此匿名内部类存在局限:
- 不能有构造函数:匿名内部类不能定义构造函数,因为它们没有类名。
- 不能被重用:匿名内部类只能在声明时使用,不能在其他地方实例化。