嵌套类(nested class ['nestɪd] ):被定义在另一个类的内部的类;
外围类(enclosing class)
嵌套类(nested class)有四种:
- 静态成员类(static member class)、
- 非静态成员类(nonstatic member class)、
- 匿名类(anonymous class) 、
- 局部类(local class)。
除了第一种之外,其他三种都被称为内部类。
1、静态成员类
静态成员类是最简单的一种嵌套类。最好把它看作是普通的类,只是碰巧被声明在另一个类的内部而已,它可以访问外围类的所有静态成员(包括声明为私有的成员)。
静态成员类是外围类的一个静态成员,与其他的静态成员一样,也遵守同样的可访问规则。如果它被声明为私有的,就只能在外围类的内部才可以被访问。
public class Father {
private static int cc = 0;
static class Flower{
public Flower() {
System.out.println("Flower:::构造方法执行" + cc);
}
}
}
静态成员类的一种常见应用是作为公有的辅助类,当且仅当与它的外部类一起使用时才有意义。
2、非静态成员类
非静态成员类和静态成员类之间的区别:
非静态成员类的每个实例都隐含着与外围类的一个外围实例相关联。在非静态成员类的实例方法内部(实例方法:对象的方法,只有对象创建后才起作用),可以调用外围实例上的方法,或者利用修饰过的this构造获得外围实例的引用。
public class OuterClass {
public OuterClass() {
System.out.println("OuterClass:::构造方法执行");
}
public void haha() {
System.out.println("OuterClass:::haha方法执行");
}
class InnerClass{
public InnerClass() {
haha(); //在非静态成员类的实例方法内部调用外围实例上的方法
System.out.println("InnerClass:::构造方法执行");
}
}
static class InnerClassStatic{
public InnerClassStatic() {
// haha(); //当haha()是静态方法时才不会出错
System.out.println("InnerClassStatic:::构造方法执行");
}
}
}
如果 嵌套类的实例 可以在 外围类的实例 之外独立存在,这个嵌套类就必须是静态成员类;在没有外围类的实例的情况下,要想创建非静态成员类的实例是不可能的。
/**
* 非静态内部类实例化
* 外部类对象名.new 内部类名()
*/
OuterClass oc = new OuterClass();
OuterClass.InnerClass ic = oc.new InnerClass(); //需要外围类的实例来创建非静态成员类
/**
* 静态内部类实例化
* new 外部类名.内部类名()
*/
StaticInnerClass sic = new OuterClass.StaticInnerClass();
当非静态成员类的实例被创建的时候,它和外围实例之间的关联关系也随之建立起来,而且这种关联关系以后也不能被修改。
如果声明成员类不要求访问外围实例,就要始终把static修饰符放在它的声明中,使他成为静态成员类,而不是非静态成员类。
3、匿名类
匿名类在使用的同时被声明和实例化。
匿名类的使用方法:
FatherClassName reference = new FatherClassName(){
//方法
};
匿名类可以看作两种情况:
3.1、匿名类继承一个父类
/**
* 匿名类继承一个父类
*/
class Polygon {
public void display() {
System.out.println("在 Polygon 类内部");
}
}
class AnonymousDemo {
public void createClass() {
// 创建的匿名类继承了 Polygon 类
Polygon p1 = new Polygon() {
public void display() {
System.out.println("在匿名类内部。");
}
};
p1.display();
}
}
class Main {
public static void main(String[] args) {
AnonymousDemo an = new AnonymousDemo();
an.createClass();
}
}
输出结果为:
在匿名类内部。
需要注意的是,匿名类中自定义的方法只能在匿名类的内部使用:
public class DemoFather {
public DemoFather() {
System.out.println("DemoFather:::构造方法执行");
}
public static void main(String args[]) {
OuterClass oc=new OuterClass() {
//匿名类中自定义的方法只能在匿名类的内部使用
public void anonymousInnerClassMethod() {
System.out.println("DemoFather:::OuterClass的匿名内部类执行");
}
//OuterClass存在haha()
public void haha() {
System.out.println("DemoFather:::OuterClass的haha()");
anonymousInnerClassMethod();
}
};
oc.haha();
// oc.anonymousInnerClassMethod(); //错误
}
}
输出结果为:
OuterClass:::构造方法执行
DemoFather:::OuterClass的haha()
DemoFather:::OuterClass的匿名内部类执行
所以,注意到,实例化抽象类时,是使用了匿名类的写法:
//抽象类
public abstract class Red {
public abstract void draw();
}
//匿名类的使用
Red red = new Red() {
@Override
public void draw() {
Log.v("-->", "Draw");
}
};
代码等价于:
//抽象类
public abstract class Red {
public abstract void draw();
}
//继承抽象类
public class RedChild extends Red {
@Override
public void draw() {
Log.v("-->", "Draw");
}
}
//实体类的使用
RedChild redChild = new RedChild();
redChild.draw();
–2021.9.17–我认为上述代码有个错误
//代码最后,“ 实体类的使用 ”,应该为
Red redChild = new RedChild();
redChild.draw();
==–2022.7.26 补充说明,匿名类的使用相当于Red redChile = new RedChild(); ==
3.2、匿名类实现一个接口
/*
*匿名类实现一个接口
*/
interface Polygon {
public void display();
}
class AnonymousDemo {
public void createClass() {
// 匿名类实现一个接口
Polygon p1 = new Polygon() {
public void display() {
System.out.println("在匿名类内部。");
}
};
p1.display();
}
}
class Main {
public static void main(String[] args) {
AnonymousDemo an = new AnonymousDemo();
an.createClass();
}
}
4、局部类
局部类是四种嵌套类中使用的最少的类。
package cn.zzx;
public class ClassA {
private int a;
public void test() {
System.out.println("外部类...");
}
/**
* 局部内部类是嵌套在方法里面的
*/
public void testB() {
class ClassB {
private int b;
public void testB() {
System.out.println("局部类...");
}
}
ClassB b = new ClassB(); //局部类创建实例
b.testB(); //实例调用testB()方法
}
}
package cn.zzx;
public class TestA {
public static void main(String[] args) {
ClassA classA = new ClassA();
classA.test();
classA.testB(); //调用局部类
}
}
外部类…
局部类…
参考文章:
https://blog.csdn.net/jiankunking/article/details/54932462