Java中的四种内部类(成员内部类、局部内部类、静态内部类、匿名内部类)

 

目录

 

1.成员内部类(定义在类中,与类中的成员变量一起)成员内部类中不能有静态变量,但是可以有静态常量,用static final 修饰的常量。 

2.局部内部类(定义在方法中的内部类,局部内部类前面不能加private或public,其范围就是方法的范围)

3.静态内部类(静态内部类的对象可以直接生成 外部类.内部类 in=new 外部类.内部类()  )

4.匿名内部类


1.成员内部类(定义在类中,与类中的成员变量一起)成员内部类中不能有静态变量,但是可以有静态常量,用static final 修饰的常量。 

(在外部类中访问局部内部类,创建对象 Outer.Inner in=new Outer().new Inner()  )

//成员内部类不能有静态变量,但可以访问外部类的所有成员
public class Outer {
    private int i=10;
    private static int j=20;
    private int k=30;
    public static void outerF1(){

    }
    public  void outerF2(){

    }
    //成员内部类
    class Inner {
        private int i=40; //内部类中可以和外部类的实例变量共存
        static int n=50; //用静态修饰的变量是不允许的
        static final int m=60;//用静态修饰的常量允许
        void inner01(){
            System.out.println(i);    //访问内部类中的i
            System.out.println(this.i); //访问内部类中的i
            System.out.println(Outer.this.i);  //访问外部类中的i
            System.out.println(j);//内部类和外部类变量没同名,可以直接访问外部类变量
            System.out.println(k);
        }
        
    }
    //外部类的非静态方法访问内部类
    public void test01(){
        Inner inner=new Inner();   //直接创建内部类的对象
        inner.inner01();

    }
    //外部类静态方法访问内部类
    public static void main(String[] args) {
        Outer outer=new Outer();       //1.先创建外部类对象
        Inner inner=outer.new Inner(); //2.通过外部类对象创建内部类对象
        inner.inner01();               //3.引用方法
        Outer.outerF1();
        outer.outerF2();
        

    }
}

java的成员内部类中为什么不能有静态变量?

Java的成员内部类是一个嵌套在另一个类中的类,它可以访问外部类的成员和方法。由于成员内部类依赖于外部类的实例,因此不能包含静态成员或静态方法。具体来说,成员内部类的实例始终与外部类的实例相关联。因此,在成员内部类中声明静态变量会导致矛盾:它们无法区分哪个外部类的实例应该包含该静态变量。同样,成员内部类中的静态方法也无法访问外部类的实例变量,因为它们是静态的并且不依赖于外部类的实例。但是,成员内部类可以有静态常量(即使用final修饰的变量)。这是因为静态常量的值在编译时就已经确定,并且与外部类实例无关。静态常量在成员内部类和外部类之间共享,并且可以通过外部类名访问,如Outer.Inner.CONSTANT。由于成员内部类实例与外部类实例相关联,因此它们不能包含静态成员或静态方法,但可以包含静态常量。

成员内部类优点:

1.内部类作为外部类的成员可以访问外部类的私有成员和属性

2.内部类中定义外部类不可访问的属性(私有属性),这样就有了比外部类的private更小的访问权限。

这两个类编译成功之后会出现Outer.class和Outer$Inner.class的这样两个编译文件。

2.局部内部类(定义在方法中的内部类,局部内部类前面不能加private或public,其范围就是方法的范围)

(我们想创建一个类解决问题,但是又不想让这个类公开,所以就有了局部内部类)

局部内部类中不能定义静态变量,可以访问外部类的局部变量(方法中定义的变量),但必须是用final修饰的。

public class Outer01 {
    private int i=10;
    private int a=20;
    private void m2(){}

    public void ml01(){
        //局部内部类
        final class Inner01{        //局部内部类不能被private和public修饰符修饰,但是可以被final修饰
            private int a=30;      //可以定义和父类相同的变量
            public void f1(){
                m2();     //可以直接调用父类的方法
                //如果外部类和内部类的成员重名,默认使用就近原则,如果想访问外部类的成员采用(外部类.this.成员)
                System.out.println(i);
                System.out.println(a);
                System.out.println(Outer01.this.a);
            }
        }
        //如果外部类想访问局部内部类,只能在内部类所在的这个方法中创建对象
        Inner01 inner01=new Inner01();
        inner01.f1();
    }

    public static void main(String[] args) {
        Outer01 outer01=new Outer01();
        outer01.ml01();
    }
}

3.静态内部类(静态内部类的对象可以直接生成 外部类.内部类 in=new 外部类.内部类()  )
 

public class Outer02 {
    private static int i=10;
    private int j=20;

    public static void outerF1(){}
    private void outerF2(){}

    //静态内部类可以用private、public、protected修饰
    //静态内部类可以定义静态和非静态成员
     static class Inner02{
        private int m=20;
        private static int n=30;

        void InnerTest(){     //静态内部类只能访问外部类的静态成员和静态方法
            System.out.println(i);
            outerF1();
        }
    }
    public void outerF3(){
        //外部类访问内部类的静态成员: 内部类.成员
        System.out.println(Inner02.n);
        //外部类访问内部类的非静态成员  通过实例化内部类来访问内部类的非静态成员
        Inner02 inner02=new Inner02();
        System.out.println(inner02.m);
    }

    public static void main(String[] args) {
        Outer02 outer02=new Outer02();
        outer02.outerF3();
        //生成静态内部类不需要通过外部类对象生成,这是静态内部类和成员内部类的区别
        Outer02.Inner02 inner02=new Outer02.Inner02();
        inner02.InnerTest();
    }
}

4.匿名内部类

匿名内部类是没有类名的特殊内部类,适合创建只使用一次。匿名内部类需要继承一个已有的父类或实现一个接口。由于匿名类本身没有名字,也不存在构造方法,也不能包含静态成员。

new 父类名/接口名( ) { }

public class Test04 {
    public static void main(String[] args) {
        //这个整体实现接口就是匿名内部类
        MyInterface mi=new MyInterface() {
            @Override
            public void say() {
                System.out.println("实习接口问好");
            }
        };
        //这个整体也是匿名内部类
        MyClass01 mc=new MyClass01(){
            public void hello(){
                System.out.println("匿名子类"+age);
            }
        };
        mc.age=20;
        mc.hello();
    }
}

interface MyInterface{
    void say();
        }
class MyClass01 {
    public int age;
    public void hello(){
        System.out.println("父类方法");
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值