内部类
1、概述
当一个事物 A 的内部,还有一个部分需要一个完整的结构 B 进行描述,而这个内部的完整的结构 B 又只为外部事物 A 提供服务,不在其他地方单独使用,那么整个内部的完整结构 B 最好使用内部类。
2.分类
2.1、成员内部类
[修饰符] class 外部类{
[其他修饰符] [static] class 内部类{
}
}
2.1.1、使用特征
作为类的成员
- 内部类可以声明为private和protected
- 可以调用外部类的结构
- 可以声明为static,但久不能再调用外层类的非static的成员变量。
作为类的
-
可以在内部定义属性、方法、构造器等结构
- 可以继承父类,可以实现接口,也可以被其他内部类继承
- 可以声明为final,表示不被继承
2.1.2、创建成员内部类对象
实例化静态内部类
外部类名.静态内部类名 变量 = 外部类名.静态内部类名();
实例化非静态内部类
外部类名 变量 1 = new 外部类();
外部类名.非静态内部类名 变量 2 = 变量 1.new 非静态内部类名();
代码
public class example {
public static void main(String[] args) {
//静态内部类实例
Outer.StaticInner inner = new Outer.StaticInner();
inner.innerFun();
Outer.StaticInner.innerMethod();
System.out.println("--------------");
//非静态内部类实例
Outer outer = new Outer();
Outer.NoStaticInner inner1 = outer.new NoStaticInner();//outer.getNoStaticInner();
inner1.innerFun();
}
}
class Outer{
private static String a = "外部静态a";
private static String b = "外部静态b";
private String c = "外部非静态c";
private String d = "外部非静态d";
static class StaticInner{
private static String a = "静态类内部静态a";
private String c = "静态类内部非静态c";
public static void innerMethod(){
System.out.println("Inner.a = " + a);
System.out.println("Outer.a= " + Outer.a);
System.out.println("b = " + b);
}
public void innerFun(){
System.out.println("Inner.innerFun");
System.out.println("Outer.a = " + Outer.a);
System.out.println("Inner.a = " + a);
System.out.println("b = " + b);
System.out.println("c = " + c);
}
}
class NoStaticInner{
private String a = "非静态内部类a";
private String c = "非静态内部类c";
public void innerFun(){
System.out.println("NoStaticInner.inFun");
System.out.println("Outer.a =" + Outer.a);
System.out.println("a = " + a);
System.out.println("b = " + b);
System.out.println("Outer.c = " + Outer.this.c);
System.out.println("c = " + c);
System.out.println("d = " + d);
}
}
//获取NoStaticInner实例的外部方法
public NoStaticInner getNoStaticInner(){
return new NoStaticInner();
}
}
2.2、局部内部类
2.2.1、非匿名局部内部类
[修饰符] class 外部类{
[修饰符] 返回值类型 方法名(形参列表){
[final/abstract] class 内部类{
} }}
public class example2 {
public static void main(String[] args) {
Runner runner = Outer.getRunner();
runner.run();
}
}
class Outer {
public static Runner getRunner() {
class LocalRunner implements Runner {
@Override
public void run() {
System.out.println("LocalRunner.run");
}
}
return new LocalRunner();
}
}
interface Runner {
void run();
}
2.2.2、匿名内部类
考虑到这个子类或实现类是一次性的,那么我们给它定义一个类,就显得多余。完全可以使用匿名内部类的方式来实现,避免给类命名的问题。
三种方式
使用匿名内部类的对象直接调用方法
public class example03 {
interface A {
void a();
}
public static void main(String[] args) {
new A() {
@Override
public void a() {
System.out.println("aaaa");
}
}.a();
}
}
通过父类或父接口的变量多态引用匿名内部类的对象
public class example04 {
interface A {
void a();
}
public static void main(String[] args) {
A obj = new A() {
@Override
public void a() {
System.out.println("aaaa");
}
};
obj.a();
}
}
匿名内部类的对象作为实参
public class example05 {
interface A {
void method();
}
public static void test(A a) {
a.method();
}
public static void main(String[] args) {
test(new A() {
@Override
public void method() {
System.out.println("aaaa");
}
});
}
}