内部类和匿名类

内部类:

编译器生成XXXX$XXXX这样的class文件


使用

1.类名前要加以外部类的名字

2.使用new创建内部类时,也要在new前面冠以对象变量


public class TestInnerClass {
 public static void main(String[] args) {
 	Parcel p = new Parcel();
 	p.testShip();
 	Parcel.Contents contents = p.new Contents(33); /* 在Parcel外部使用Parcel内部类。。*/
 	Parcel.Destination d = p.new Destination("Hawai"); 
 	p.setProperty(contents, d);
 	p.ship();
 }
}
public class Parcel {
	private Contents c;
	private Destination d;
	class Contents{
		private int i;
		Contents(int i){
			this.i = i;
		}
		int value(){
			return i;
		}
	}
	class Destination{
		private String label;
		Destination(String whereTo){
			label = whereTo;
		}
		String readLabel(){
			return label;
		}
	}
	void setProperty(Contents c,Destination d){
		this.c = c;
		this.d = d;
	}
	void ship(){
		System.out.println("move "+ c.value() + " to " + d.readLabel());
	}
	public void testShip(){
		c = new Contents(22);
		d = new Destination("BeiJing");
		ship();
	}
}

内部类可以直接访问外部类的字段和方法(即时private也可以)

若与外部类有同名的字段或者方法 则可用外部类名.this.字段及方法

内部类也是外部类的成员:

所以访问控制符可以有:public protected默认以及private.

final(不可继承的) abstract(抽象的)

static修饰内部类 则表明该内部类实际上是一种外部类

1.实例化staic类时 不需要在new前面加上对象实例变量

2. static不能访问非static

局部类

在一个方法中也可以定义类,这种类叫做局部类。

1.跟局部变量一样 不能用public,private static等等修饰 可以用 final abstract

2.可以访问外部类的成员

3.不能够访问该方法的局部变量 除非是final局部变量

public class Outer {
	private int size = 5;
	public Object makeTheInner(int localVar) {
		final int finalLocalVar = 99;
		class Inner {
			public String toString() {
				return ("InnerSize " + size + "" + " finalLocalVar:" + finalLocalVar);
			}
		}
		return new Inner();
	}
	public static void main(String[] args) {
		Outer outer = new Outer();
		System.out.println(outer.makeTheInner(2).toString());
		/*多态的体现。。
		 * 输出:InnerSize 5 finalLocalVar:99
		 * */
	}
}


匿名内部类

顾名思义,是一种特殊的内部类

1.没有类名,定义该对象的同时就生成该对象的一个实例

2.“一次性使用”的类

匿名类的使用

1.不取名字,直接采用父类或接口的名字

2.编译器生成XXXX$1之类的名字

3.类定义的时候就创建实例

即 new 类名或接口名

4.在构造对象时使用父类的构造方法(不能定义构造方法 要带参数的话 只能使用父类构造方法的参数)

匿名类的应用

1.用到界面的时间处理(事件监听处理 )

2.作为方法的参数 (如作为一个比较大小的接口)

import java.util.Arrays;
import java.util.Comparator;

public class SortTest {
	public static void main(String[] args) {
		Integer arrays[] = {5,4,6,1,2};
	     Arrays.<Integer>sort(arrays,new Comparator<Integer>(){ /*实现Comparator接口的匿名内部类*/
			@Override
			public int compare(Integer o1, Integer o2) {
				// TODO Auto-generated method stub
				return o1-o2;
			}
	     });
	     for (Integer integer : arrays) {
			System.out.println(integer+" ");
		}
	}
}


### ### Java 中内部类匿名类的定义及其区别 #### 内部类(Member Inner Class) 内部类是定义在另一个类内部的类。它作为外部类的一个成员存在,可以访问外部类的所有成员,包括私有成员。内部类与外部类之间存在一种强关联关系,每个内部类实例都必须依附于一个外部类的实例[^4]。例如: ```java public class Outer { private String message = "Hello from Outer!"; public class Inner { public void printMessage() { System.out.println(message); // 可以访问外部类的私有成员 } } } ``` 在上面的代码中,`Inner` 是 `Outer` 的一个内部类。要创建 `Inner` 的实例,必须先创建 `Outer` 的实例,然后通过该实例创建 `Inner` 的实例: ```java Outer outer = new Outer(); Outer.Inner inner = outer.new Inner(); inner.printMessage(); ``` #### 匿名类(Anonymous Inner Class) 匿名类是没有显式类名的内部类,通常用于简化代码编写。它必须继承一个父类或实现一个接口,且只能使用一次。由于没有类名,匿名类不能被其他类复用,也不能定义构造器。编译器会为每个匿名类生成一个唯一的类名,格式为外部类名加上 `$` 序号,例如 `OuterClass$1`[^1]。 一个典型的匿名类示例如下: ```java abstract class Animal { abstract void speak(); } public class Test { public static void main(String[] args) { Animal a = new Animal() { @Override void speak() { System.out.println("Anonymous animal speaks!"); } }; a.speak(); } } ``` 在上述代码中,`new Animal() { ... }` 定义了一个匿名类,它继承自 `Animal` 并立即实例化。该匿名类只能使用一次,并且不能在其他地方通过类名访问。 #### 内部类匿名类的区别 | 特性 | 内部类 | 匿名类 | |------|--------|--------| | **类名** | 有明确的类名 | 没有类名,由编译器生成唯一名称 | | **可访问性** | 可以有 `public`、`private`、`protected` 或默认访问权限 | 只能在定义它的代码块中访问 | | **是否允许静态成员** | 允许定义静态成员(仅限静态内部类) | 不允许定义静态成员 | | **能否被继承** | 可以被其他类继承 | 不能被其他类继承 | | **构造器** | 可以定义构造器 | 不能定义构造器,但可以定义实例初始化块 | | **用途** | 适用于需要多次使用的类 | 适用于一次性使用的类,通常用于实现简单的接口或抽象类方法 | | **代码可读性** | 代码结构清晰,易于维护 | 过度使用可能导致代码可读性下降 | | **复用性** | 可以被其他类复用 | 无法复用,只能在定义实例化 | #### 使用场景 - **内部类** 更适合需要多次使用、结构较复杂的类定义。它可以拥有完整的类结构,包括构造器、静态成员等,适合用于组织代码结构[^4]。 - **匿名类** 适用于只需要使用一次的类,尤其是在需要实现接口或继承抽象类的简单实现。它常用于事件监听器、回调机制等场景,能够简化代码编写,但不适用于复杂逻辑的实现[^2]。 ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值