Java内部类知识点总结

内部类方法调用

有如下类:

public class Body {

    private String name;

    public class Heart{
        public void beat(){
            System.out.println("heart beats");
        }
    }

	//外部类调用内部类方法
    public void bodyMethod(){
        new Heart().beat();
    }
}

则有两种方法调用内部类Heart:

public class InnerClassDemo01 {
    public static void main(String[] args) {
        //用外部类方法调用内部类方法
        Body body = new Body();
        body.bodyMethod();
        System.out.println("------------------");
        //直接创建内部类对象
        Body.Heart heart = new Body().new Heart();
        heart.beat();
    }
}

内部类同名变量的访问

内部类同名变量访问方式如下:

public class Outer {

    int num = 10;

    public class Inner {
        int num = 20;

        public void innerMethod() {
            int num = 30;
            System.out.println(num);    //方法内局部变量
            System.out.println(this.num);   //内部类成员变
            System.out.println(Outer.this.num); //外部类成员变量
        }
    }
}

局部内部类

局部内部类和一般内部类的区别是:局部内部类是在方法里的。

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

    }

    public void outerMethod() {
        class Inner {    //局部内部类
            int num = 10;

            public void innerMethod() {
                System.out.println(num);
            }
        }
        Inner inner = new Inner();
        inner.innerMethod();
    }
}

要想调用局部内部类,只能调用外部类方法:

public class DemoMain {
    public static void main(String[] args) {
        Outer obj = new Outer();
        obj.outerMethod();
    }
}

权限修饰符小结

  1. 外部类:public / (default)
  2. 成员内部类:public / protected / (default) / private
  3. 局部内部类:什么都不能写

局部内部类final问题

局部内部类访问方法的局部变量,该局部变量必须是有效final的

/*
局部内部类,如果要访问所在方法的局部变量,该变量必须是“有效final的”
从Java 9开始,只要局部变量事实不变,那么final关键字可以省略
这与生命周期有关。
1.因为new生成的对象在堆内存中,而局部变量在栈内存中
2.方法运行结束之后出栈,局部变量消失
3.new出来的对象持续存在,直至垃圾回收
 */
public class MyOuter {
    public void outerMethod() {
        int num1 = 10;
        final int num2 = 20;
        int num3 = 30;
        num3++;
        class MyInner {
            public void method() {
                System.out.println(num1);
                System.out.println(num2);
//                System.out.println(num3); 报错
            }
        }
    }
}

匿名内部类

在内部类中用得最多,也是最重要的,是Lambda表达式的基础。
有接口如下:

public interface MyInterface {
    void method();
}

通常情况下,先在一个类中实现该接口,然后在该类调用接口的方法:

public class MyInterfaceImpl implements MyInterface{

    @Override
    public void method() {
        System.out.println("实现类覆盖重写方法!");
    }
}

匿名内部类的实现方法:

/*
如果接口的实现类,或父类的子类,只需要使用一次
这种情况下可以省略掉该类的定义,而改为匿名内部类,格式如下

接口/抽象类名称 对象名 = new 接口/抽象类名称(){
    //覆盖重写所有抽象方法
};

 */
public class DemoMain {
    public static void main(String[] args) {
        MyInterface obj1 = new MyInterfaceImpl();
        obj1.method();
        System.out.println("-----------------");
        //使用匿名内部类
        MyInterface obj2 = new MyInterface() {
            @Override
            public void method() {
                System.out.println("匿名内部类覆盖重写方法!");
            }
        };
        obj2.method();
    }
}

内部类使用示例

public interface Skill {
    public void use();
}
//Clone是英雄的一种技能
public class Clone implements Skill{
    @Override
    public void use() {
        System.out.println("Clone");
    }
}
public interface Weapon {
    public void use();
}
public class Hero {
    private String name;
    private Skill skill;
    private Weapon weapon;

    public Hero(String name) {
        this.name = name;
    }

    public Skill getSkill() {
        return skill;
    }

    public void setSkill(Skill skill) {
        this.skill = skill;
    }

    public Weapon getWeapon() {
        return weapon;
    }

    public void setWeapon(Weapon weapon) {
        this.weapon = weapon;
    }

    public void attack(){
        System.out.println(name + "attack with" + weapon);
    }

    public String getName() {
        return name;
    }
}
public class DemoGame {
    public static void main(String[] args) {
        Hero hero = new Hero("Ethan");
        //使用了匿名对象,Clone对象没有名字
        hero.setSkill(new Clone());

        //使用了匿名内部类,实现Skill接口的类没有名字
        Skill skill = new Skill() {
            @Override
            public void use() {
                System.out.println("anonymous skill");
            }
        };
        hero.setSkill(skill);

        //同时使用匿名对象和匿名内部类
        hero.setWeapon(new Weapon() {
            private String weaponName = "sword";
            @Override
            public void use() {
                System.out.println(hero.getName() + "use" + weaponName);
            }
        });

    }
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值