09 为什么要有内部类?匿名内部类表现形式由来?

为什么要有内部类?

类内部里的类,称内部类内部类是为了实现多重继承,通常是用于创建内部对象用的。

既然说是为了多重继承,那就先看继承:

package com.junc.test;

public class Test1 {
public static void main(String[] args) {
    Father father = new Father();
    System.out.println(father.money); //输出10

    Son son = new Son();
    System.out.println(son.money); //输出10
    }
}

class Father {
    int money = 10;
}

class Son extends Father {
}

通过继承关系,我们可以由son来继承father的money。

只有这一种方法么?


还有一种方式,那就是内部类,所以说,内部类具备继承特性。

看如下代码:

package com.junc.test;

public class Test2 {

    public static void main(String[] args) {
        Father father = new Father();
        Father.Son son = father.new Son();//若想从外部类读取内部类,必须创建对象
        son.shopping(); //输出10  
    }
}

class Father {
    int money = 10;
    class Son { //内部类
        public void shopping() {
            System.out.println(money); //内部类可直接读取外部类的成员变量money
        }
    }
}

如果总是写Father.Son这样的代码,实在是很麻烦,怎么办呢?

如果可以直接从Father类调用就好了,如果能father.shopping()是不是会更好呢?

当然可以这样子,看如下代码:

package com.junc.test;

public class Test2 {
    public static void main(String[] args) {
        Father father = new Father();
        father.shopping(); //输出10
    }
}

class Father {
    int money = 10;
    class Son {
        public void shopping() {
            System.out.println(money);
        }
    }

    public void shopping() { //我们在Father类中创建shopping()方法
        Son son = new Son();
        son.shopping();
    }
}

Father希望买东西,他有很多Son,但他不想知道是哪个Son去的,只要东西买回来的就可以了.

所以,我们可以将Son匿名,并抽象化,既然匿名了,就取名为匿名内部类

package com.junc.test;

public class Test2 {

    public static void main(String[] args) {
        Father father = new Father();
        father.fatherShopping();
    }
}

abstract class Son { //提取Son抽象
    public abstract void sonShopping();
}

class Father {
    int money = 10;

    public void fatherShopping() {
        Son son = new Son(){ //匿名内部类
            public void sonShopping(){
                System.out.println(money);
            }
        };
        son.sonShopping();
    }
}

这就会奇怪了,son是abstract的,不能被实例化呀,也就是说,不能new Son()。

那么看仔细了哦,看仔细了,看仔细了。

注意: 这里写的是new Son() {}。


匿名内部类为什么是这样的表现形式呢?

当一个新事物出现,需弄清楚三件事:

  1. 匿名内部类要满足什么样的条件?

    必须继承一个类或实现一个接口

  2. 它是用来做什么的?

    直接使用此类对象,并实现其中的方法

  3. 什么时候使用?

    只需要调用一次对象的时候使用

表现形式:

  • 新建一个类表现形式:new Son();
  • 实现方法的表现形式:{};
    既要使用类,又实现方法的表现形式(将上面两种表现形式合并为一种):new Son() {};

而在实际开发中,我们希望的表现形式是直接看到代码就可以知道我们想要做什么,Father要fatherShopping就指派某个儿子去sonShopping()。用代码表示为:Father.fatherShopping().sonShopping();

分析一下这行代码,如果Father类直接调用fatherShopping()方法,代表着fatherShopping()方法必然是静态的,只有静态的才可以直接由类调用。后面的sonShopping()方法必然是由一个对象所调用的,那么,我们就应该return返回一个Son对象,但我们不一定非要创建,正如前面所说,我们可以由匿名类直接跳过创建。

那么,整体代码又将如何实现呢?

package com.junc.test;

public class Test2 {

    public static void main(String[] args) {
        Father.fatherShopping().sonShopping(); //输出go shooping
    }
}

abstract class Son {
    public abstract void sonShopping();
}

class Father {      
    public static Son fatherShopping() {
        return new Son(){
            public void sonShopping(){
                System.out.println("go shopping");
            }
        };
    }
}

是否发现,下面这行代码: Father.fatherShopping().sonShopping();

有一种熟悉的味道: System.out.println();

  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值