java 内部类的使用

内部类,将一个类A定义在另外一个类B的内部,那么我们就称类A为内部类

1.成员内部类

实验探究:
创建类Test
public class Test {

public static void main(String[] args) {

}

}
创建一个类Out代表外部类,一个类In代表内部类,在类中声明各种属性
class Out {//java中并不推荐在命名中使用_来定义变量名和方法名,但为了表述直观,这里暂
且这么做。
int out_a;//定义一个外部类成员变量
static int static_out_a;//定义一个外部类静态成员变量
void out_print(){//定义一个外部类成员方法

}
static void static_out_print(){//定义一个外部类静态成员方法

}
class In {
int in_a;//定义一个内部类成员变量
//static int static_in_a; //定义一个内部类静态成员变量,见注解①
static final int final_in_a=10;//静态final常量是允许被定义的
void in_print(){

}
//static void static_out_print(){//定义一个内部类静态成员方法,见注解


//}

}
}
注解①:这时候,我们发现成员内部类中是不允许定义静态变量和静态方法的,但是可以定义静
态常量
然后我们试图在main方法里创建内部类对象,于是输入In in=new In(),这时候程序报错了,因
成员内部类对象的创建依赖于外部类对象,于是修改代码为
Out out = new Out();
Out.In in = out.new In();

或者Out.In in=new Out().new In();编译成功。
尝试在内部类的方法中访问外部类的成员,不管是out_a还是static_out_a,或者方法,添加了
private修饰符的变量,都可以访问得到并且不报错,内部类可以访问外部类的一切成员,即包括
了任何属性和方法。
接下来,我们在外部类和内部类中同时声明相同的String变量same和相同的方法print(),两个
print()方法中打印变量的值:System.out.println("In same String:"+same);在main方法中再
创建一个Out对象,注意了,不能直接再new一个对象出来,因为那样的话跟原来的代码指向的不
是同一个对象:
Out.In in=new Out().new In();
Out out=new Out();---->错误。
修改为
Out out=new Out();
Out.In in=out.new In();----->正确

两个对象各自调用方法
in.print();
out.print();
输出结果为:
In same String:same
out same String:same
然后在内部类中的print()方法添加语句Out.this.same="out_same";Out.this.print();再次打印
,得到:
In same String:same
out same String:out_same
out same String:out_same
这说明在外部类和内部类中拥有同名的变量和方法时,可用外部类名.this.成员名的形式来指明
其为外部类的对象的成员。不过这种形式只能在方法体内进行,并且是非静态的或者静态的常量

(这很好理解,因为内部类可以定义静态的常量,但不能定义非静态变量和方法)

成员内部类的定义可以加入访问控制符:
添加private 只能在本类中访问
添加protected 不同包情况下,只能访问外部类的子类
添加public 都可以访问

public class Test {

    public static void main(String[] args) {
        // In in = new In();//创建内部类对象失败,成员内部类对象的创建依赖于外部类对象
        // Out out = new Out();
        // Out.In in = out.new In();//创建内部类对象成功
        //Out.In in = new Out().new In();// 创建内部类对象成功
        Out out = new Out();
        Out.In in=out.new In();
        in.print();
        out.print();
    }

}

class Out {// java中并不推荐在命名中使用_来定义变量名和方法名,但为了表述直观,这里暂且这么做。
    int out_a;// 定义一个外部类成员变量
    static int static_out_a;// 定义一个外部类静态成员变量
    private int private_out_a;
    String same = "same";// 定义外部类和内部类的同名属性
    static final int final_out_a = 9;
    void out_print() {// 定义一个外部类成员方法

    }

    void print() {// 定义外部类和内部类的同名方法
        System.out.println("out same String:" + same);
    }

    static void static_out_print() {// 定义一个外部类静态成员方法

    }

    class In {
        int in_a;// 定义一个内部类成员变量
        // static int static_in_a; //定义一个内部类静态成员变量
        static final int final_in_a = 10;// 静态final常量是允许被定义的
        String same = "same";

        void in_print() {
            private_out_a = 10;
            System.out.println("private_out_a:" + private_out_a);
        }

        void print() {
            
            Out.this.same="out_same";
            System.out.println("In same String:" +same);
            Out.this.print();
        }
        //Out.this.print();//错误,只能在方法内调用
    }
}

 

2.静态内部类

我们先看下这段代码

package com.epilogue.day1;

class Out {
    int out_a = 5;
    static int out_static_a = 5;
    static class In {
        static int in_static_a;//注解①
        static void in_static_print() {//注解①
            // System.out.println("out_a = "+out_a);//错误,注解②
            System.out.println("out_static_a = " + out_static_a);
            System.out.println("静态内部类的静态方法");
        }
        int b;
        void in_print() {
           // System.out.println("out_a = "+out_a);//错误,注解②
            System.out.println("out_static_a = " + out_static_a);
            System.out.println("静态内部类的非静态方法");
        }
    }
}
public class Test {
    public static void main(String[] args) {
        
        System.out.println(" Out.In.a = " + Out.In.in_static_a);// 访问静态内部类的静态成员,注解③
        Out.In.in_static_print();// 访问静态内部类的静态成员,注解③        
        Out.In in = new Out.In();// 创建内部类对象,注解④
        System.out.println("b = " + in.b);//访问静态内部类的非静态成员:
        in.in_print();
    }
}

 

注解①:可以看出,静态内部类是可以定义静态成员的

注解②:静态内部类的内部不能访问外部类的非静态成员:静态内部类对象不依赖外部类的对象

注解③:当外部内要访问内部类的静态成员时,只需要外部类名.内部类名.静态成员名即可调用 
注解④:创建内部类对象只需用外部类名.内部类名 对象名=new 外部类名.内部类名()即可

 

局部内部类

/*
 * 局部内部类:类比局部变量。
 *   1.只能在定义的代码块中使用
 *   2.局部内部类不能加访问控制符和static
 *   3.局部内部类中的成员不能加static,但是可以加访问控制符
 *   4.局部内部类可以访问外部类的任何成员
 *   5.局部内部类中的方法要访问局部变量的话,局部变量必须是final的
 *   6.局部内部类必须先定义后使用
 *     
 *  
 */
class Outer{
    int a = 8;
    void Outerfunc(){
        System.out.println("这是外部类的方法");
    }
    
    void func(){
        
        final int x = 5;//局部变量
                
        class Inner{//局部内部类
             int a = 88;
             void show(){
                 Outerfunc();
                 System.out.println("Outer.this.a = "+Outer.this.a);
                 System.out.println("局部变量 x = "+x);
                System.out.println("局部内部类的方法:");
            }
        }
        
        
        Inner inner = new Inner();//创建局部内部类的对象:使用局部内部类必须在类定义之后
        inner.show();
        
    
    }
}
public class InnerDemo3 {
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Outer outer = new Outer();
        outer.func();
    }
}

 

posted @ 2016-07-20 20:38  Epilogue  阅读(594)  评论(0编辑  收藏  举报