内部类

目录

1. 成员内部类

2. 方法内部类

3. 匿名内部类

4. 静态内部类


内部类,把一个类定义到另一个类的内部,就叫内部类

1. 成员内部类

可以把成员内部类当做  (class)类型的成员变量或者方法。

1 .内部类可以无条件访问外部类的所有成员方法和成员变量,静态变量,方法。构造方法不行。

2. 在1的前提下,如果当内部类拥有和外部类重名的方法或者变量时,会发生隐藏现象。在内部类直接使用时,只会使用内部类中的方法和变量,如果想要使用外部的方法或变量,需要 外部类.this.变量(方法)

例如:

System.out.println(Demo.this.name);
Demo.this.show();

3. 内部可以无条件访问外部类,但是外部是不能直接访问内部的。需要创建内部类对象去方法。

由于内部类是外部类的成员内部类,可以说该类是属于外部类的对象的。所以要想创建内部类,需要先创建外部类对象

例如:

Demo demo = new Demo();
Demo.DemoInner demoInner = demo.new DemoInner();
package com.mark.java.innerClass;

public class Demo {


    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }


    public void show(){
        System.out.println("我是Demo");
    }

    class DemoInner{

        private String name;

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public void showInner(){
            System.out.println("我是InnerDemo");
        }

        public void show(){
            System.out.println("我是和外部类同名的方法show");
        }

        public void test(){
            System.out.println(name);
            System.out.println(this.name);
            System.out.println(Demo.this.name);
            Demo.this.show();
        }
    }

}
package com.mark.java.innerClass;

public class Main {

    public static void main(String[] args) {

        Demo demo = new Demo();
        Demo.DemoInner demoInner = demo.new DemoInner();
        demo.setName("zhangsan");

        demoInner.showInner();
        demoInner.setName("lisi");

        demoInner.test();

    }
}

2. 方法内部类

1. 一个类在另一个类的方法的内部。

2. 方法内部类,是局部内部类,只在该方法内部有意义,所以外部是无法创建该类的对象的,所以该类只能在方法内部使用。

package com.mark.java.innerClass;

public class Demo2 {

    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void show(Demo2 demo2){

        System.out.println("show");

        //方法内部类,是局部内部类,只在该方法内部有意义,所以外部是无法创建该类的对象的,所以该类只能在方法内部使用。
        class Demo2Inner{

            private String name;

            public void show(){
                System.out.println(this.name);
                System.out.println(Demo2.this.name);
                System.out.println(demo2.getName());
            }
        }
        Demo2Inner demo2Inner = new Demo2Inner();
        demo2Inner.name = "bbbbb";
        demo2Inner.show();
    }
}

package com.mark.java.innerClass;

public class Main2 {

    public static void main(String[] args) {
        Demo2 demo2 = new Demo2();
        demo2.setName("aaaa");
        demo2.show(demo2);
    }
}

3. 匿名内部类

1. 不知道内部类的名称,叫匿名内部类。

2. 匿名内部类适合只使用一次的类,一般来说,匿名内部类用于继承其他类或是实现接口,并不需要增加额外的方法,只是对继承方法的实现或是重写。

3. 匿名内部类在编译后会默认生成一个Outter$1.class,匿名内部类时唯一没有构造方法的类。

4. 匿名内部类可以修改为成员内部类。帮助理解。

 

package com.mark.java.innerClass;

import org.springframework.aop.ThrowsAdvice;

public class Demo3{

    public void aaa(){
        //不知道内部类的名称,叫匿名内部类。
        //2. 匿名内部类适合只使用一次的类,一般来说,匿名内部类用于继承其他类或是实现接口,并不需要增加额外的方法,只是对继承方法的实现或是重写。
        //3. 匿名内部类在编译后会默认生成一个Outter$1.class,匿名内部类时唯一没有构造方法的类。
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("匿名内部类开始了");
            }
        }).start();

        //同时可以写成成员变量的写法。这里起了名字一个类A。
        new Thread(new A()).start();
    }

    class A implements Runnable{

        @Override
        public void run() {
            System.out.println("不是匿名内部类的方式");
        }
    }
}

4. 静态内部类

1. 在内部类前面加一个static

2. 静态内部类不能访问外部类非静态的方法和属性,只能访问外部类静态的方法和属性

3. 外部类方法静态内部类,由于是静态类,所以该类是属于外部类的,而不是外部类对象的,所以创建静态内部类对象

Demo4.Demo4Inner demo4Inner = new Demo4.Demo4Inner();

 

package com.mark.java.innerClass;

public class Demo4 {

    private String name;

    private static int age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void show(){
        System.out.println("show");
    }

    public static void add(){
        System.out.println("add");
    }

    static class Demo4Inner{


        private String name;

        private static int age;

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public void show(){
            System.out.println("inner show");

            //内部类方法外部类
            System.out.println(Demo4.age);
            //静态内部类不能访问外部类非静态的方法和属性。这个是错的
            System.out.println(Demo4.this.name);
            Demo4.add();
        }
    }
}
package com.mark.java.innerClass;

public class Main4 {

    public static void main(String[] args) {

        Demo4.Demo4Inner demo4Inner = new Demo4.Demo4Inner();
        demo4Inner.show();
    }
}

为什么内部类可以访问外部类呢

可以这样想,将内部类当做方法来想。

如果是成员内部类,就当成员方法,在成员方法中,可以访问该类的所有属性和方法。

如果是静态内部类,就当做静态方法,同理在静态方法中只能访问该类的静态变量和静态方法。

为什么局部内部类和匿名内部类只能访问局部final变量?

在之前,如下:,如果局部内部类和匿名内部类访问局部变量,局部变量必须是final修饰,现在不需要了

package com.mark.java.innerClass;

import org.springframework.aop.ThrowsAdvice;

public class Demo3{

    public void aaa(final int a){
        //不知道内部类的名称,叫匿名内部类。
        //2. 匿名内部类适合只使用一次的类,一般来说,匿名内部类用于继承其他类或是实现接口,并不需要增加额外的方法,只是对继承方法的实现或是重写。
        //3. 匿名内部类在编译后会默认生成一个Outter$1.class,匿名内部类时唯一没有构造方法的类。
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("匿名内部类开始了"+a);
            }
        }).start();

       
    }
}

 

内部类的使用场景和好处 

  • 1.每个内部类都能独立的继承一个接口的实现,所以无论外部类是否已经继承了某个(接口的)实现,对于内部类都没有影响。内部类使得多继承的解决方案变得完整。
  • 2.方便将存在一定逻辑关系的类组织在一起,又可以对外界隐藏。
  • 3.方便编写事件驱动程序。
  • 4.方便编写线程代码。 

参考:https://www.runoob.com/w3cnote/java-inner-class-intro.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值