JAVA基础(二十四)——内部类

一、目录

  • 内部类介绍
  • 内部类分类
  • 局部内部类
  • 匿名内部类
  • 成员内部类
  • 静态内部类

二、内部类介绍

一个类的内部又完整的嵌套了另一个类结构。被嵌套的类称为内部类(inner class),嵌套其他类的类称为外部类(outer class)。是类的第五大成员(属性、方法、代码块、构造器、内部类)。内部类最大的特点就是可以直接访问私有属性,并且可以体现类与类的包含关系。

基本语法:

class Outer{
    class Inner{
        ...
    }
    ...
}

三、内部类的分类

  • 定义在外部类局部位置上(比如说方法或代码块内):
    1. 局部内部类(有类名)
    2. 匿名内部类(无类名)
  • 定义在外部类的成员位置上:
    1. 成员内部类(没用static修饰)
    2. 静态内部类(使用static修饰)

四、局部内部类

局部内部类是定义在外部类的局部位置,比如方法或者代码块中,并且有类名。

  1. 可以直接访问外部类的所有成员,包含私有的。
  2. 局部内部类如果要用修饰符,只能使用final修饰。
  3. 作用域:仅仅在定义它的方法或代码块中。
  4. 局部内部类如果要访问外部类的成员,可直接访问。
  5. 外部类如果要访问局部内部类的成员,需要先创建对象再访问,而且必须在作用域内。
  6. 外部其他类不能访问局部内部类。
  7. 如果外部类和局部内部类的成员重名时,默认遵循就近原则,如果想访问外部类的成员,则可以使用:外部类名.this.成员 的方式去访问。

五、匿名内部类

匿名内部类是定义在外部类的局部位置,比如方法或代码块中,并且没有类名。

  • 匿名内部类语法
    new 类或接口(参数列表){类体};

匿名内部类的细节:

匿名内部类既是一个类,同时也是一个对象。因此可以用下面两种方式去调用匿名内部类的方法:

new A(){
    public void cry(){
        ....
    }
}.cry();
A a = new A(){
    public void cry(){
        ....
    }
};
a.cry();

六、成员内部类

成员内部类是定义在外部类的成员位置,并且没有static修饰。

  1. 成员内部类可以直接访问外部类的所有成员,包括私有。
  2. 可以添加任意的访问修饰符。
class Outer{
    private n = 100;
    class Innter{
        public void say(){...}
    }
}
  1. 作用域,和外部类的其他成员一样。
  2. 成员内部类访问外部类,可直接访问。
  3. 外部类访问成员内部类,需要先创建对象,再访问。
  4. 外部其他类访问成员内部类有两种方法。
package com.innerclass;

public class MemberInnerClass {
    public static void main(String[] args) {

        //1. 外部其他类调用成员内部类的第一种方法    
        OuterClass outerClass = new OuterClass();
        OuterClass.InnerClass innerClass = outerClass.new InnerClass();
        innerClass.eat();
    }
}


class OuterClass{
    private int n = 100;
    public void say(){
        System.out.println("Hello, Inner Class");
    }

    class InnerClass{
        public void eat(){
            System.out.println(n);
        }

    }

}

package com.innerclass;

public class MemberInnerClass {
    public static void main(String[] args) {

        //2. 外部其他类调用成员内部类的第二种方法
        OuterClass outerClass = new OuterClass();
        OuterClass.InnerClass innerClass = outerClass.UseInnerClass();
        innerClass.eat();

    }
}


class OuterClass{
    private int n = 100;
    public void say(){
        System.out.println("Hello, Inner Class");
    }

    class InnerClass{
        public void eat(){
            System.out.println(n);
        }

    }

    public InnerClass UseInnerClass(){
        return new InnerClass();
    }

}

  1. 如果外部类和内部类的成员重名时,内部类访问的话,默认遵循就近原则,如果想访问外部类的成员,则可以使用 外部类名.this.成员 去访问。
package com.innerclass;

public class MemberInnerClass {
    public static void main(String[] args) {

        OuterClass outerClass = new OuterClass();
        OuterClass.InnerClass innerClass = outerClass.new InnerClass();
        innerClass.eat();
    }
}


class OuterClass{
    private int n = 100;
    public void say(){
        System.out.println("Hello, Inner Class");
    }

    class InnerClass{
        private int n = 900;
        public void eat(){
            System.out.println(n);
            System.out.println(OuterClass.this.n);
        }

    }

}

//900
//100

七、静态内部类

静态内部类是定义在外部类的成员位置,并且有static修饰。

  1. 可以直接访问外部类的所有静态成员,包括私有的,但不能直接访问非静态成员。
  2. 可以添加任意访问修饰符。
  3. 作用域和其他成员一样,整个类体。
  4. 静态内部类访问外部类的静态成员,可直接访问。
  5. 外部类访问静态内部类,需要先创建对象再访问。
  6. 外部其他类访问静态内部类有两种方法。
package com.innerclass;

public class StaticInnerClass {
    public static void main(String[] args) {
        //外部其他类访问静态内部类的第一种方式
        //因为是静态内部类,所以可以通过外部类.静态内部类的方式创建对象
        OuterClassA.InnerClassA innerClassA = new OuterClassA.InnerClassA();
        innerClassA.say();
    }
}

class OuterClassA{
    private static int n = 100;
    private String name = "Mike";

    static class InnerClassA{
        public void say(){
            System.out.println(n);
        }
    }
}

package com.innerclass;

public class StaticInnerClass {
    public static void main(String[] args) {
        //外部其他类访问静态内部类的第二种方式
        //调用一个返回静态内部类的方法,来获取这个静态内部类的对象
        OuterClassA outclassa = new OuterClassA();
        OuterClassA.InnerClassA innerClass = outclassa.getInnerClass();
        innerClass.say();
    }
}

class OuterClassA{
    private static int n = 100;
    private String name = "Mike";

    static class InnerClassA{
        public void say(){
            System.out.println(n);
        }
    }

    public InnerClassA getInnerClass(){
        return new InnerClassA();
    }
}

如果我们创建的这个getInnerClass()方法是一个静态方法的话,那么就产生了第三种调用静态内部类的方法,也就是通过类名直接访问这个访问,直接跳过了创建对象。

package com.innerclass;

public class StaticInnerClass {
    public static void main(String[] args) {
        //外部其他类访问静态内部类的第三种方式

        OuterClassA.InnerClassA innerClass = OuterClassA.getInnerClass();
        innerClass.say();

    }
}

class OuterClassA{
    private static int n = 100;
    private String name = "Mike";

    static class InnerClassA{
        public void say(){
            System.out.println(n);
        }
    }

    public static InnerClassA getInnerClass(){
        return new InnerClassA();
    }
}

  1. 如果外部类和静态内部类的成员重名时,静态内部类访问的时候,默认遵循就近原则,如果想访问外部类的成员,则可以使用 外部类名.成员 去访问。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值