上一篇讲解了是抽象类与抽象方法:
使用方式:第一步,通过继承抽象类,并实现抽象方法,产生新类(子类);第二步,实例化这个子类,完成应用需求。
这是前面介绍的抽象类的使用方式,但是这种使用手法不是唯一的,有更直接、更犀利的实现手段。
内部类
介绍:在一个类中,可以定义其他类,这些类成为内部类。
注意:在一个类中的意思是,在这个类定义过程的“{}”内。
内部类代码示例及相关使用介绍:
package com.mec.about_innerclasee;
/**
* 这个类展示内部类与外部类的关系
*/
public class Outerclass {
private int privateMember;
protected int protectedMember;
public int publicMember;
public Outerclass() {
privateMember = 1;
protectedMember = 1;
publicMember = 1;
}
//定义三种不同权限的修饰方法
private void privateFun(){
System.out.println("privateMember:" + privateMember);
}
protected void protectedFun(){
System.out.println("protectedMember:" + protectedMember);
}
public void publicFun(){
System.out.println("publicMember:" + publicMember);
}
/**
* 这是OuterClass的内部类
*/
public class InnerClass{
private int innerMember;
public InnerClass() {
innerMember = 4;
}
//在内部类的方法中,可以直接引用外部类的所有成员
//且,不受权限修饰符的约束。
private void innerFun(){
privateMember++;
protectedMember++;
publicMember++;
privateFun();
protectedFun();
publicFun();
System.out.println("innerMember:" + innerMember);
}
}
//外部类可以定义内部类对象的成员
private InnerClass innerObject;
public void fun(){
//可以实例化该成员
innerObject = new InnerClass();
//外部类的方法,可以通过内部类的对象,引用内部类的所有成员与方法
innerObject.innerFun();
System.out.println("innerObject.innerMember++:" + innerObject.innerMember++);
}
}
匿名内部类
介绍
匿名内部类(重点)
匿名:没有名字
匿名内部类:指的是没有名字的子类。
匿名内部类作用:简化代码
把定义子类继承父类,重写父类的方法,创建子类对象合成一步完成
把实现类实现接口,重写接口中的方法,创建实现类对象合成一步完成
格式:
new 父类|接口(){
重写父类|接口中的方法
};
匿名内部类演示代码
定义一个抽象类:Bird
package com.mec.about_abstract.core;
public abstract class Bird {
private String name;
public Bird(String name) {
this.name = name;
}
public abstract String cry();
public void print(){
System.out.println("(" + name + ")的叫声" + cry());
}
}
这个抽象类很典型,与前面给出的抽象类也和相似,且更简短。
对于这个抽象类,想现在不打算建立新的派生类,而是直接在演示类中对其进行“实例化”。
此“实例化”非直接创建对象,而是一种“非”直接实例化。
演示代码如下:
package com.mec.about_abstract.core;
public class Test {
public static void main(String[] args) {
Bird lark = new Bird("百灵鸟") {
@Override
public String cry() {
return "婉转,优美";
}
};
lark.print();
//上面的代码书写格式很独特
//new 抽象类构造方法(){
// 在这里实现这个抽象类的所有抽象方法
//};
//其本质上个也是生成了一个类,不过,这个类,没有机会命名。
//所以这个类就是匿名类;但是它会生成相应的类文件!
new Bird("乌鸦") {
@Override
public String cry() {
return "嘶哑,难听";
}
}.print();
//这里的写法,干脆连这个匿名类的对象名都省略了
//第26行的.print(),其实就是方法的调用。
//应该知道,new关键字返回类的实例的首地址,也就是对象
//所以,new的返回结果其实就是这个类的对象;
//当然就可以通过这个对象调用它的方法了
new Bird("是不是鸟已经无所谓了") {
public Bird fun(){
System.out.println("可以在这里定义方法!");
//注意这里的返回值类型是Bird
return this;
}
@Override
public String cry() {
return "叫声已经不重要了!";
}
}.fun().print();
//如果fun()的返回值不是Bird的话,
//我们就不能用这种方式继续调用其他方法了。
}
}
——————————————————————————————————————————————————————————————————————————————————-
(百灵鸟)的叫声婉转,优美
(乌鸦)的叫声嘶哑,难听
可以在这里定义方法!
(是不是鸟已经无所谓了)的叫声叫声已经不重要了!
这种方式的好处
1、不需要明确的生成派生类,对这个简单问题,明显提高变成效率;
2、在需要时临时产生匿名内部类,实现抽象方法,这样更灵活;
3、一个匿名内部类对应一种抽象方法的实现,这样更紧凑。