愤怒的小鸟大战内部类【java内部类详解】

古人云:胜负兵家之常,善用兵者能因败为成。

内部类分类:

1.实例(成员)内部类

基本格式:

class OuterClass{
    ///
    class InnerClass{
        ///
    }
}

实例内部类和正常类的使用并没有什么大的不同
如何使用:1.

错误使用:InnerClass demo=new InnerClass();
正确使用:OuterClass out=new OuterClass();
         OuterClass.InnerClass in=out.new InnerClass();

为什么需要先创建外部类对象呢?顾名思义,实例内部类,相当于外部类的实例成员,当然依赖外部对象。
2.外部类提供访问内部类的接口(更推荐,就像老板和秘书的感觉):
在外部类的内部进行实例内部类的实例化。

注意事项:1.实例内部类中不能有stati修饰的变量或者方法

原因:可以这么理解,假设实例内部类可以定义static修饰的变量或者方法--->
我们知道static修饰的方法或者变量可以直接通过类名.的方式来调用,而内部类
不可以通过这种方式调用,即Out.In.num,因为实例内部类只是class,而未被
static修饰,所以无法再未定义外部类的情况下Out.In的,在这一步就已经断了。

2.(1)外部类和实例内部类的普通变量重名:

优先使用实例内部类的变量
想要访问外部的采用:Out.this.name

(2)外部类的静态变量和实例内部类的普通变量重名:

依然优先使用实例内部类的变量
想要访问外部的采用:Out.name

在这里插入图片描述

如果一个内部类,想要不依赖外部对象就可以使用,那就得static出马了

2.静态内部类

即在实例内部类的基础上多了一个static修饰。
我在实例内部类中经常提到它,那么它究竟特殊在哪呢?
使用方法:

不需要先创建外部类对象,就可实例化。
Out.In in=new Out.In(); 

注意事项:1.和静态方法一样,不能再该类中使用外部类非静态的方法或者变量,因为它不在依赖对象。

3.本地(方法)内部类【不重要】

即外部类方法中定义的类

注意事项:1.该类不可被public等权限修饰符和static修饰
在这里插入图片描述

2.类内部不可以使用所在方法中非final修饰的变量【目的:改变变量的生命周期原因:因为方法栈帧时随着方法调用结束而释放,而方法内部类对象是靠jvm回收的,这样就可能出现方法调用结束了对象还在清况】,但是
在这里插入图片描述
如果你使用了,也能正常使用,这是jdk的1.8版本后做出的改进,会帮你把那个默认改成final的类型。不过如果你对那个变量进行操作的话,就不会默认了,如图:
在这里插入图片描述
报错了。
3.只可在所在方法内部实例化,如果在方法外实例化就会这样
在这里插入图片描述

4.匿名内部类

顾名思义,没有名字的内部类。
使用方法:
1.继承式:
用一个匿名的类继承一个抽象类/类,并重写它的抽象方法/方法;
抽象类举例,格式:(假设Dog类是抽象类)
Dog dog=new Dog(){
//重写Dog内的方法
}
普通类同上。
这可不是实例化抽象类,希望大家不要弄混了!!!

public class AnonymousClassDemo {
    public static void main(String[] args) {
        new Outer().test();
    }
}
class Outer{
    public void test(){
        Dog dog=new Dog() {//重点
            @Override
            protected void eat() {
                System.out.println("二狗在干饭");
            }
        };
        dog.eat();
    }
}
abstract class Dog{
    protected abstract void eat();
}

2.接口式
和继承式大差不差。
格式:假设Cat是接口
Cat cat=new Cat(){
//实现接口Cat内的方法
}

public class AnonymousClassDemo {
    public static void main(String[] args) {
        new Outer1().test();
    }
}
class Outer1{
    public void test(){
        Cat cat=new Cat() {
            @Override
            public void run() {
                System.out.println("小黑在跑!!");
            }
        };
        cat.run();
    }
}
interface Cat{
     void run();
}

同样,这可不是实例化接口,希望大家不要弄混了!!!
3.方法参数式:
即在给方法传入参数时使用:

public class AnonymousClassDemo {
    public static void main(String[] args) {
        new Outer1().test(new Cat() {//传入时使用
            @Override
            public void run() {
                System.out.println("迪奥娜在逃跑!!!");
            }
        });
    }
}
class Outer1{
    public void test(Cat cat){
        cat.run();
    }
}
interface Cat{
     void run();
}

注意事项:

1.{}内不能存在构造方法,这个很容易看出来,毕竟匿名内部类没有名字,何来的构造方法呢。
2.匿名内部类中不能定义静态方法和属性。
3.匿名内部类是局部的,所有局部(本地/方法)内部类的限制对他也有效,这也就能解释了第二条了。
4.有且只能使用一次,只能在创建时使用【不过如果你定义在类的属性位置,类的其他地方也能用】。

public class AnonymousClassDemo {
    public static void main(String[] args) {
        new Outer2().test();
        new Outer2().test2();
    }
}
class Outer2{
    Bird bird=new Bird(){//使其称为Outer2类的一个属性
        @Override
        public void fly() {
            System.out.println("凤飞飞");
        }
    };
    public void test(){
        bird.fly();
    }
    public void test2(){
        bird.fly();
    }
}

abstract class Bird{
    public abstract  void fly();
}

内部类的使用

目前我也在学习阶段,没有遇到什么需要内部类的地方,我只能给大家转述一下别人的说法:
我们知道继承只能单继承,内部类也可以继承,这样就可以间接的实现了类的多继承。
那么更推荐哪种类呢?这里推荐静态内部类,主要还是他不依赖对象,不容易出现外部类释放了,内部类还没释放等而导致的内存泄漏

那么内部类就攻略到这里了!!!感谢阅读!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值