内部类

3.7 内部类

3.7.1 内部类概念

将一个类定义在另一个类的里面,里面那个类就称为内部类(内置类,嵌套类)。为什么要定义内部类呢?类是用于描述事物的,而事物中如果还有具体的事物,而且这个内部的事物访问着所属事物中的内容。这时这个内部的事物,也需要用到类来描述。这个类就是内部类。
3.7.2 内部类访问特点
(1)内部类可以直接访问外部类中的成员,包括私有成员。
为什么内部类可以直接访问外部类中的成员呢?因为内部类都持有一个外部类的引用:“外部类名.this”。
(2)外部类要访问内部类中的成员必须要建立内部类的对象。

public class Outer {
    int num = 4;
    //内部类,可看成Outer的一个成员
    class Inner
    {
        int num = 5;//Inner的成员变量
        void method()
        {
            int num = 6;//Inner的局部变量
            //内部类可以直接访问外部类中的成员。
            //调用的是局部变量:6
            System.out.println("method run1 .."+num);
            //使用this,调用的是Inner类的成员变量:5
            System.out.println("method run2 .."+this.num);
            //使用外部类名.this,调用的是Outer类的成员变量:4
            System.out.println("method run3 .."+Outer.this.num);
        }
    }   
    //可以将Outer类中看成有3个成员,一是成员变量num,二是类Inner,三是成员方法show()。
    //外部类要访问内部类Inner中的成员必须创建内部类的对象。
    public void show()
    {
        Inner in = new Inner();
        in.method();
    }
}

public class InnerClassDemo {
    public static void main(String[] args) {
        // TODO 自动生成的方法存根
        new Outer().show();
    }
}

运行结果如下:
这里写图片描述

内部类在文件中的存在形式:
这里写图片描述

3.7.3 内部类修饰符
当内部类定义在外部类的成员位置上时,可以使用成员的修饰符来进行内部类的修饰,
(1)权限修饰符。
内部类权限修饰符是默认或者公有public:可以直接这样访问内部类。
外部类名.内部类名 变量名 = new 外部类对象.new 内部类对象;
例如:Outer.Inter in=new Outer().new Inter();
私有:是不可以直接在外部访问。

public class Outer {
    int num=10;
    class Inter{
            void method(){
            System.out.println("method run1 .."+num);
        }
    }
    public void show(){ 
        System.out.println("method run2 .."+num);   
    }
}

public class InnerClassDemo2 {
    public static void main(String[] args) {
        //使用匿名对象的方式调用方法
        new Outer().show();//method run2 ..10
        //直接创建名对象再调用方法
        Outer outer =new Outer();
        outer.show();//method run2 ..10
        //直接在其他类中,访问一个类的内部类。
        //可以这么理解:内部类是外部类的一个成员,外部类要调用自己的成员自然要
        //创建对象,而内部类本身又是一个类,要调用自己的成员自然要创建自己的对象
        Outer.Inter in=new Outer().new Inter();
        in.method();//method run1 ..10
    }
} 

运行结果如下:
这里写图片描述
(2)static修饰符。
①内部类被静态修饰,出现访问局限性,只能访问外部类中的静态成员。

public class Outer {
    //int num=10;被静态修饰的内部类访问不到该普通成员变量
    static int num=10;
    //内部类被静态修饰,只能访问外部类中的静态成员
    //静态内部类
    static class Inter{
            void method(){
            System.out.println("method run1 .."+num);
        }
    }
    public void show(){ 
        System.out.println("method run2 .."+num);   
    }
}
②内部类被静态后,会随着外部类的加载而加载。而内部类若是没有被静态修饰,没有使用到内部类时,内部类不会进入内存。

a.访问静态内部类中的非静态成员:直接创建内部类对象。 
外部类名.内部类名 变量名 = new 外部类名.内部类名();

例如:

Outer.Inter in = new Outer.Inter();
in.method();
b.访问静态内部类中的静态成员:不需要对象。
外部类名.内部类名.内部类的静态成员

例如:Outer.Inter.fun();
③如果内部类中定义了静态成员,该内部类必须被静态修饰。
因为若内部类不是静态的,那么访问内部类中的成员时需要创建内部类对象才可以。而内部类中定义了静态成员,该静态成员是随着内部类的加载而加载的,优先于对象存在。这就矛盾了!

public class Outer {
    //int num=10;
    static int num=10; //静态成员变量
    //静态内部类
    static class Inter{
            void method(){
            System.out.println("method run1 .."+num);
        }
    //静态内部类中静态方法
    static void fun(){
            System.out.println("fun run3 .."+num);
            }
    }
    public void show(){ 
        System.out.println("method run2 .."+num);   
    }
}

public class InnerClassDemo2 {
    public static void main(String[] args) {
        //直接new 内部类,因为内部类被静态后,会随着外部类的加载而加载
        //调用内部类中的非静态方法
        new Outer.Inter().method();
       //访问静态内部类中的静态成员。不需要对象。
       //使用:外部类名.内部类名.内部类的静态成员
        Outer.Inter.fun();
    }
}

运行结果:
这里写图片描述
其实只需记住一句话:静态随着类的加载而加载,随着类的消失而消失。
可以这么理解:内部类是外部类的一个成员,外部类要调用自己的成员自然要创建对象,而内部类本身又是一个类,要调用自己的成员自然要创建自己的对象。所以,可使用“new 外部类名().内部类名();”创建内部类的对象。而内部类被静态修饰时,随着外部类的加载而加载,所以无需创建外部类的对象调用内部类中的成员。所以可使用“new 外部类名.内部类名();”创建内部类的对象。若静态内部类中有静态成员,静态成员会随着外部类和静态内部类的加载而加载,所以无需创建对象调用该静态成员,所以可使用“外部类名.内部类名.内部类的静态成员”直接访问。
记住:内部类只有定义在外部类的成员位置上,才具备这些修饰符。
内部类定义在局部位置上,不允许访问局部中变量。只能访问被final修饰的局部常量。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值