一、内部类
将一个类定义在另一个类或者一个方法的内部, 前者称为内部类,后者称为外部类 。内部类也是封装的一种体现在外部类中,内部类定义位置与外部类成员所处的位置相同,因此称为成员内部类。public class OutClass {class InnerClass {}}// OutClass 是外部类// InnerClass 是内部类根据内部类定义的位置不同,一般可以分为以下几种形式:1. 成员内部类 ( 普通内部类:未被 static 修饰的成员内部类 和 静态内部类:被 static 修饰的成员内部类 )2. 局部内部类 ( 不谈修饰符 ) 、匿名内部类
1.实例内部类:即未被static修饰的成员内部类。
1. 可以在实例内部类方法中 直接访问 外部类中的任何成员2. 实例内部类所处的位置与外部类成员位置相同,因此也受 public 、 private 等访问限定符的约束3. 在实例内部类方法中访问同名的成员时, 优先访问自己的 ,如果要 访问外部类同名 的成员,必须: 外部类名称.this.同名成员 来访问4. 必须在 先有外部类对象 前提下, 才能创建实例内部类对象5. 实例内部类的非静态方法中包含了一个指向外部类对象的引用6. 外部类中,如果要访 问实例内部类中的成员 ,必须 先要创建内部类的对象 。
class OuterClass{
//外部类基本上所有的变量都可以定义
public int a = 1;
public static int b = 2;
private int c = 3;
private static int d;
protected int e;
class InnerClass{
//实例内部类
public int a = 10;
// public static int b = 10;不能创建静态变量
//内部类是需要实例化对象,来使用的。而static不依赖于对象,所以不能创建变量
public static final int b = 20;//加上final就变成常量了,可以使用
private int d = 30;
public void test(){
System.out.println("InnerClass::test()");
System.out.println(a);//10,实例内部类,和外部类有同名变量的时候,实例内部类优先
System.out.println(OuterClass.this.b);//2,访问外部类同名变量
System.out.println(c);//3,实例内部类没有该变量,去外部类找
System.out.println(d);//30
}
}
public void test(){
System.out.println("OuterClass::test()");
}
}
public class Test2 {
public static void main(String[] args) {
//不能直接实例化内部类对象
//需要外部类的引用,实例化内部类对象
OuterClass outerClass = new OuterClass();
OuterClass.InnerClass innerClass = outerClass.new InnerClass();
innerClass.test();//调用内部方法
}
}
2.静态内部类:被static修饰的内部成员类称为静态内部类。
1. 在静态内部类中只能访问外部类中的静态成员如果确实想访问,我们该如何做? 提供一个外部类的引用2. 创建静态内部类对象时,不需要先创建外部类对象
class Out{
public int a = 1;
public static int b = 2;
private int c = 3;
static class InnerClass{
public int d = 10;
public static int e = 20;
private int f = 30;
public void test(){
Out out = new Out();
System.out.println("InnerClass::test()");
System.out.println(out.a);//静态类不能直接访问非静态类的成员
System.out.println(b);
System.out.println(out.c);//静态类不能直接访问非静态类的成员
//自己内部的成员可以直接访问
System.out.println(d);
System.out.println(e);
System.out.println(f);
}
}
public void test(){
System.out.println("OuterClass::test()");
}
}
public class Test2 {
public static void main(String[] args) {
Out.InnerClass innerClass = new Out.InnerClass();
innerClass.test();
}
}
3.局部内部类:定义在外部类的方法体或者{}中,该种内部类只能在其定义的位置使用
1. 局部内部类 只能在所定义的方法体内部使用2. 不能被 public 、 static 等修饰符修饰3. 编译器也有自己独立的字节码文件,命名格式:外部类名字 $ 数字内部类名字 .class4. 几乎不会使用(一般使用的非常少)
public class Test2 {
public void func(){
class InnerClass{
public int a = 1;
}
InnerClass innerClass = new InnerClass();
System.out.println(innerClass.a);
}
public static void main(String[] args) {
Test2 test2 = new Test2();
test2.func();
}
}
4.匿名内部类
interface IA{
void test();
}
public class Test2 {
public static void main(String[] args) {
//相当于一个类实现了IA接口,重写了test这个方法
//方法1
new IA(){
@Override
public void test() {
System.out.println("这是重写了接口的方法!");
}
}.test();
}
//方法2
IA ia = new IA() {
@Override
public void test() {
System.out.println("这是重写了接口的方法!");
}
};
ia.test();
}