内部类
内部类分为四种:实例内部类、静态内部类、本地内部类、匿名内部类
实例内部类
1.实例内部类中的方法可以直接使用外部类的实例变量和实例方法。
2.在实例内部类中可以直接用内部类创建对象
class OuterClass2{
private int a = 10;
private int b = 20;
private static int c = 30;
private static final int d = 40;
private int data1 = 1000;
public OuterClass2(){
System.out.println("OuterClass() init!");
}
class InnerClass{//实例内部类
private int data1 = 10;
private int data2 = 20;
//private static int data3 = 30;//error
private static final int data4 = 30;//立即数
//private static final int data5 = data1 + 30;//error
public InnerClass(){
System.out.println("InnerClass init!!");
}
public void show(){
System.out.println(a);
System.out.println(b);
System.out.println(c);
System.out.println("data1:"+this.data1);
System.out.println("outer data1:"+OuterClass2.this.data1);
System.out.println(data2);
System.out.println("InnerClass show()!!!");
}
}
}
public class TestDemo6 {
public static void main(String[] args) {
OuterClass2 outer = new OuterClass2();//实例化 一个实例内部类
//InnerClass in = new InnerClass(); error
OuterClass2.InnerClass in = outer.new InnerClass();//OuterClass2 作用域
in.show();
}
}
由此可见,要new一个新的内部类对象,必须通过一个外部类的对象进行new。
1、为什么实例内部类中必须定义一个编译期间可以确定的立即数
<1>static 实例方法 static
<2>实例内部类的设计意义?
每一个实例内部类 必须有一个外部类对象,依赖外部类对象
假设:static InnerClass in = new InnerClass();
OuterClass2.InnerClass.in 直接拿到了你的实例内部类的一个实例 ,违背设计意义
2、实例内部类有没有额外的内存消耗??
实例内部类 还拥有外层类的 this 引用变量
静态内部类
由于static内部类不具有任何对外部类实例的引用,因此static内部类中不能使用this关键字来访问外部类中的实例成员,但是可以访问外部类中的static成员。
class OuterClass{
private int a = 10;
private int b = 20;
private static int c = 30;
private static final int d = 40;
public OuterClass(){
System.out.println("OuterClass() init!");
}
public void show(){
System.out.println("OuterClass show()!!");
}
static class InnerClass{//静态内部类
OuterClass outer2;
public InnerClass(OuterClass o2){//传入外部类
outer2 = o2;
System.out.println("InnerClass init!!");
}
public void show2(){
System.out.println("a:"+ outer2.a);//??如何访问??
System.out.println("c:"+c);
System.out.println("InnerClass show2!!!");
}
}
}
public class ju55 {
public static void main(String[] args) {
OuterClass outer = new OuterClass();
//InnerClass in2 = new InnerClass(); error
OuterClass.InnerClass in = new OuterClass.InnerClass(outer);//得到静态内部类的对象
in.show2();
}
}
静态内部类必须依靠于外部类
问:静态内部类如何访问外部类的实例成员变量?
1、因为实例成员变量依赖外部类对象
2、所以传入一个外部类对象 构造函数 传入
3、主函数内 OuterClass outer = new OuterClass();
4、InnerClass(OuterClass o2){传入外部类的对象}
5、接收外部类对象OuterClass outer2;
6、outer2 拿到了外部类对象
7、System.out.println(“a:”+ outer2.a);
本地内部类
1.局部内部类只在方法体中有效,就想定义的局部变量一样,在定义的方法体外不能创建局部内部类的对象
2.在方法内部定义类时,应注意以下问题:
(1)方法定义局部内部类同方法定义局部变量一样,不能使用private、public等访问修饰说明符修饰,也不能使用static修饰,但可以使用final修饰
(2)方法中的内部类可以访问外部类成员。对于方法的参数和局部变量,必须有final修饰才可以访问。
(3)static方法中定义的内部类可以访问外部类定义的static成员
class OuterClass3{
private int a = 10;
private int b = 20;
private int c = 30;
public void test(){//可以是static
final int data = 10;//局部变量---》
//本地内部类 只能访问拥有这个内部类方法的被final修饰的变量
class InnerClass{
private int a = 100;
//private static int b = 20;//内部类中不能定义静态成员
private static final int b = 200;//立即数
//static InnerClass in = new InnerClass();
public InnerClass(){
System.out.println("test():InnerClass init!!");
}
public void show(){
System.out.println("a :"+a);//内外同名变量,访问内部变量 输出结果为100
System.out.println("b :"+b);//内外同名变量,访问内部变量 输出结果为200
System.out.println("c :"+c);//可以直接访问外部变量
System.out.println("data :"+ data);
System.out.println("test(): show()!!");
}
}
InnerClass in = new InnerClass();//在方法中new一个内部类对象
in.show();//调用内部方法
}
}
public class TestDemo2 {
public static void main(String[] args) {
// TODO Auto-generated method stub
OuterClass3 a = new OuterClass3();
a.test();
}
}
匿名内部类
匿名内部类:定义类的最终目的是创建一个类的实例,但是如果某个类的实例只是用一次,则可以将类的定义与类的创建,放到与一起完成,或者说在定义类的同时就创建一个类,以这种方法定义的没有名字的类成为匿名内部类。
一般格式:
new ClassOrInterfaceName(){
/*类体*/
}
someMethod(new Name(){
/*类体*/ });
class TestDemo{
private int a = 10;
private int b = 20;
public void show(){
System.out.println("a:" + a + ", b:" + b);
}
}
public class TestDemo3 {
public static void test(TestDemo s){
s.show();
}
public static void main(String[] args) {
// TODO Auto-generated method stub
test(new TestDemo(){
public void show(){
System.out.println("unname show()!!");
}
});
new TestDemo(){//匿名内部类相当于 当前类的子类
public void show(){
System.out.println("unname show()!!");
}
}.show();
}
}
运行结果为: