在一个类中,可以定义其它类,这些类称为内部类。内部类所在的类称为“外部类”。内部类可以直接引用外部类的成员和方法,无需收到权限修饰符的限制。
内部类的分类:
- 成员内部类(在成员内部类中能访问外部类中所有静态成员、非静态成员,但不可以定义静态方法 )
- 静态内部类( 在静态内部类中只能访问外部类的静态成员,可以定义静态方法)
- 局部内部类
- 匿名内部类
(当满足如下2个条件时可以选择应用匿名内部类:
局部内部类可能就需要创建一个对象
局部内部类需要实现外部接口,或者继承某些父类 )
来看个例子:
public class OuterClass
{
private int privateMember;
protected int protectedMember;
public int publicMember;
public OuterClass()
{
privateMember=1;
protectedMember=2;
publicMember=3;
}
private void privateFun()
{
System.out.println("privateMember:" + privateMember);
}
private void protectedFun()
{
privateFun();
System.out.println("privateMember:" + privateMember);
}
public void publicFun()
{
privateFun();
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++);
}
}
通过以上的代码,相信读者已经对内部类有了一定的认识。这就可以开始我们的匿名内部类技术的讲述了。
首先给出一个抽象类Bird.java
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());
}
}
众所周知,抽象类不能直接实例化。但是我们可以通过匿名内部类技术“非”直接实例化!!!
public class Test
{
public static void main(String[] args)
{
new Bird("百灵鸟")
{
@Override
public String cry()
{
return "婉转";
}
}.print();
}
}
上面的代码书写格式:
new 抽象类的构造方法() {
在这里要实现该操作类的所有抽象方法
}
其本质上是生成了一个类,不过,这个类没有机会命名。所以,这个类就是匿名类,但是他会生成相应的类文件。
执行结果如下:
Java8其中一个很重要的新特性就是lambda表达式。Java8发布以后,lambda表达式将大量替代匿名内部类的使用,简化代码的同时,更突出了原来匿名内部类中最重要的那部分包含真正逻辑的代码。
but…需要确保接口中有且仅有一个抽象方法,Java中的Lambda才能顺利地进行。
给个接口
public interface Action
{
public abstract void study(String name);
}
public class Test1
{
private static void t(Action Activist)
{
Activist.study("honey");
}
public static void main(String[] args)
{
t((name) -> System.out.println(name + " 正在学习呢"));
}
}
最后我们用Thread做一个对比,希望给读者留下深的印象