为什么要有内部类?
类内部里的类,称内部类。内部类是为了实现多重继承,通常是用于创建内部对象用的。
既然说是为了多重继承,那就先看继承:
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() {}。
匿名内部类为什么是这样的表现形式呢?
当一个新事物出现,需弄清楚三件事:
匿名内部类要满足什么样的条件?
必须继承一个类或实现一个接口
它是用来做什么的?
直接使用此类对象,并实现其中的方法
什么时候使用?
只需要调用一次对象的时候使用
表现形式:
- 新建一个类表现形式: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();