Java内部类

什么是内部类?

关于内部类,其实就是在一个类或者一个方法里面在创建一个新的类,内部的类,就叫做内部类。嵌套在内部的类就叫做内部类,不在内部的就叫做外部类。内部类也是封装的一种体现。

一般的结构类型:

class OuterClass{

        /...../

        class InnerClass{

                /...../

        }

}

只有在class花括号内的创建的类,才叫做内部类。而且内部类与外部类虽然共用同一个java源文件,但是经过编译后,内部类会形成单独的字节码文件。

内部类一般分为几种:成员内部类,局部内部类,匿名内部类。

1.成员内部类

在外部类中,内部类定义位置与外部类成员所处的位置相同,因此称为成员内部类。而成员内部类又有两种不同的定义方法,分别是实例内部类和静态内部类。

1.1实例内部类

即未被static修饰的成员内部类

class OutClass{
    public int data1 = 10;
    private int data2 = 20;

    class InnerClass{
        public int data3 = 30;
        public int data4 = 40;
        }
        public void testInner(){
        System.out.println(data1); //10
        System.out.println(data2); //20
        System.out.println(data3); //30
        }
    }
}
public class Test {
    public static void main(String[] args) {
        OutClass outClass =new OutClass();
        OutClass.InnerClass innerClass = outClass.new InnerClass();
        System.out.println(outClass.data1);
        //System.out.println(outClass.data2);error
        innerClass.testInner();
    }
}

1.想要调用内部类里的变量,就要先通过实例外部类,再实例内部类,我们才能拿到内部类的变量与方法。实例内部类对象必须在先有外部类对象前提下才能创建

2.内部类可以直接对外部类的变量与方法进行访问,但是再main方法中需要先实例对象,而且在实例内部类所处的位置与外部类成员位置相同,因此也受publicprivate等访问限定符的约束。

3.实例内部类的非静态方法中包含了一个指向外部类对象的引用,在实例内部类方法中访问同名的成员时,优先访问自己的,如果要访问外部类同名的成员,必须:外部类名称.this.同名成员来访问。,如

class OutClass{

        public int data1 = 10;

        private int data2 = 20;

        public int data3 = 300;

        

        class InnerClass{

                public int data3 = 30;

                public int data4 = 40; }
                public void testInner(){
                        System.out.println(data1); //10
                        System.out.println(data2); //20
                        System.out.println(data3); //30

                        System.out.println(this.data3); //30

                        System.out.println(OuterClass.this.data3); //300
        }

4.外部类中,不能直接访问实例内部类中的成员,如果要访问必须先要创建内部类的对象。

class OutClass{

        public int data1 = 10;

        private int data2 = 20;

        public int data3 = 300;

        

        class InnerClass{

                public int data3 = 30;

                public int data4 = 40;

        }

public void InnerTest(){

        InnerClass innerClass = new InnerClass();

        iSystem.out.println(InnerClass.data4); //40

}

5.实例内部类中不能含有直接被static修饰的成员,需要加上final与static一起修饰才能正常运行。

实例内部类的缺点在于每次想要实例内部类时,总需要先实例一个外部类对象,才能对内部类进行实例 。

 1.2静态内部类

即被static修饰的内部类成员

class OuterClass2{

    static class InnerClass2{
       
        public void testInner() {
            System.out.println("静态内部类!!!");
        }
    }
}
public class Test2 {
    public static void main(String[] args) {
        OuterClass2.InnerClass2 innerClass2 =new OuterClass2.InnerClass2();
        innerClass2.testInner();
    }
}

运行结果:

而使用静态内部类的好处就在于不用先实例化外部类才能使用内部类,可以直接将静态内部类实例化并且使用。所以我们创建静态内部类对象时,不需要先创建外部类对象

 但是,在静态内部类中只能直接访问外部类中的静态成员,而我们如果想访问其它非静态成员,就必须在静态内部类中先将外部类实例化,再用“外部类名.+访问对象”的方式对外部类成员进行访问。

class OuterClass2{
    public int data1 = 10;
    private int data2 = 20;
    public int data3 = 30;
    static class InnerClass2{
        public int data3 = 300;
        private int data4 = 40;

        public void testInner() {
            System.out.println("静态内部类!!!");
            OuterClass2 outerClass2 = new OuterClass2();
            System.out.println(outerClass2.data1);
            System.out.println(outerClass2.data2);
            System.out.println(outerClass2.data3);
            System.out.println(data3);
            System.out.println(data4);
        }
    }
}
public class Test2 {
    public static void main(String[] args) {
        OuterClass2.InnerClass2 innerClass2 =new OuterClass2.InnerClass2();
        innerClass2.testInner();
    }
}

运行结果:

2.局部内部类

定义在外部类的方法体或者 {} 中,该种内部类只能在其定义的位置使用。一般使用得非常少。
class OuterClass3{
    public void test() {
        class InnerClass {
            public int data1 = 10;
        }
        InnerClass innerClass = new InnerClass();
        System.out.println(innerClass.data1);
    }
}
public class Test3 {
    public static void main(String[] args) {
        OuterClass3 outerClass3 = new OuterClass3();
        outerClass3.test();
    }
}

运行结果:

这种局部内部类几乎很少被使用到。

1.局部内部类只能在所定义的方法体内部使用。
2.局部内部类不能被public,static等修饰符修饰。

3.匿名内部类

        其实就是一种没有名字的内部类,其作用可以使代码更加简化。当我们在代码中想要用到某一个类或接口时,需要创建一个新的实现类。如果我们只希望这个类实现一次,那么我们如果创建一个新的类,就会有点麻烦。但是如果我们用匿名内部类的话,就可以直接进行重写,不需要创建新的类。

interface Innerclass{
    void show();
}
public class Test4 {
    public static void main(String[] args) {
        new Innerclass(){
            @Override
            public void show() {
                System.out.println("匿名内部类!");
            }
        }.show();
    }
}

还需要注意的是,在匿名内部类当中,访问的变量是不能改变的。

比如:

interface Innerclass{
    void show();
}
public class Test4 {
    public static void main(String[] args) {
        int a = 10;
        new Innerclass(){
            @Override
            public void show() {
                a = 99; //error
                System.out.println("匿名内部类!" + a);
            }
        }.show();
    }
}

关于匿名内部类,会在后面的多线程学习会使用很多匿名内部类的语法格式。 而匿名内部类不仅可以用于自己创建的接口,还可以用于编译器本身自带的接口。Comparable接口

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值