- 类中套类,外面的称为外部类,里面的称为内部类
- 内部类通常只服务于外部类,对外不具备可见性
- 内部类对象只能在外部类中创建
- 内部类中可以直接访问外部类的成员(包括私有的),在内部类中有个隐式的引用指向了创建它的外部类对象------外部类名.this
成员内部类是定义在另一个类内部的类。它是外部类的成员,可以访问外部类的所有成员变量和方法,甚至是私有的。成员内部类通常用于需要访问外部类的成员而不希望暴露给外部的情况。
代码实例一:
public class InnerClassDemo {
public static void main(String[] args) {
Mama m = new Mama();
//Baby b = new Baby(); //编译错误,内部类对外不具备可见性
}
}
class Mama{ //外部类
private String name;
Baby b = new Baby(); //内部类对象通常在外部类中创建
class Baby{ //内部类
void show(){
System.out.println(name);
System.out.println(Mama.this.name); //Mama.this指代它的外部类对象
}
}
}
代码实例二:
public class OuterClass {
private int outerVar;
public void outerMethod() {
// 外部类方法中可以访问成员内部类
InnerClass inner = new InnerClass();
inner.innerMethod();
}
public class InnerClass {
private int innerVar;
public void innerMethod() {
// 成员内部类方法中可以访问外部类的成员变量和方法
outerVar = 10;
outerMethod();
}
}
}
要创建成员内部类的对象,需要先创建外部类的对象,然后再使用外部类对象创建内部类对象:
OuterClass outer = new OuterClass();
OuterClass.InnerClass inner = outer.new InnerClass();
注意,由于成员内部类隐含地保存了对外部类对象的引用,因此不能在静态上下文中引用成员内部类。如果想要在静态上下文中使用内部类,可以将内部类声明为静态内部类。
- 若想创建一个类(派生类)的对象,并且对象只创建一个,此时该类不必命名,称为匿名内部类
- 匿名内部类中不能修改外面变量的值,因为在此处该变量默认为final的
匿名内部类是指在使用时直接定义并实例化一个类,而不需要显式地给出类的名称。它通常用于创建一个只需要用到一次的类对象。
匿名内部类可以作为一个接口的实现类、一个抽象类的子类或者一个具体类的子类,并且可以直接在创建对象的地方定义和实现它。通常情况下,匿名内部类会重写或实现外部类或接口中的某个方法。
匿名内部类的语法如下: new 父类名或接口名() { // 匿名内部类的定义和实现 };
使用匿名内部类可以减少代码量,提高代码的可读性和简洁性。但是需要注意的是,匿名内部类不能有构造函数,因为它没有名称。
实例代码一:
public class AnonInnerClassDemo {
public static void main(String[] args) {
//1)创建了Aoo的一个派生类,但是没有名字
//2)为该派生类创建了一个对象,名为o1
//3)大括号中的为派生类的类体
Aoo o1 = new Aoo(){
};
//1)创建了Aoo的一个派生类,但是没有名字
//2)为该派生类创建了一个对象,名为o2
//3)大括号中的为派生类的类体
Aoo o2 = new Aoo(){
};
int num = 5;
num = 55;
//1)创建了Boo的一个派生类,但是没有名字
//2)为该派生类创建了一个对象,名为o3
//3)大括号中的为派生类的类体
Boo o3 = new Boo(){
void show(){
System.out.println("showshow");
//num = 66; //编译错误,匿名内部类中不能修饰外面变量的值,因为在此处默认为final的
}
};
o3.show();
}
}
abstract class Boo{
abstract void show();
}
abstract class Aoo{
}
代码实例二
public class AnonymousInnerClassExample {
interface HelloWorld {
void sayHello();
}
public static void main(String[] args) {
// 使用匿名内部类实现HelloWorld接口
HelloWorld helloWorld = new HelloWorld() {
@Override
public void sayHello() {
System.out.println("Hello, World!");
}
};
// 调用匿名内部类的方法
helloWorld.sayHello();
}
}
在上面的代码中,我们定义了一个接口HelloWorld
,它只包含一个sayHello
方法。然后,在main
方法中,我们使用匿名内部类实现了这个接口。
通过使用HelloWorld helloWorld = new HelloWorld() {...};
的语法,我们创建了一个实现HelloWorld
接口的匿名内部类。在大括号内,我们可以定义匿名内部类的具体实现,包括实现接口的方法。
在main
方法的最后,我们调用了匿名内部类的sayHello
方法。
成员内部类和匿名内部类都是内部类的一种形式,即定义在另一个类的内部的类。
以下是匿名内部类的特点:
使用成员内部类和匿名内部类可以为Java项目提供更好的封装性和灵活性。成员内部类可以作为外部类的一个功能扩展,实现逻辑上的组织和划分;匿名内部类可以直接创建对象,省去了定义类的过程,使代码更加简洁。