内部类:顾名思义,在外部类中定义的类就是内部类。
内部类可以分为:有名内部类和匿名内部类;静态内部类和非静态内部类 (本篇不讨论静态内部类 )
有名内部类
public class Body{
class Heart{
public void beat(){
System.out.println("心脏在跳动");
}
}
}
如上代码:在Body类中,定义了一个有名内部类Heart;
匿名内部类
匿名内部类由于没有类名,所以要通过创建对象的方法来实现类的定义。
Body body = new Body();//创建一个对象(本句供对比参考理解)
语法:
new 父类构造器([参数列表])|接口(){
匿名内部类类体
}
例:
Body body = new Body(){
};//定义一个匿名内部类,且此类为Body的子类
匿名内部类的特点:
①匿名内部类是普通类的子类(上转型对象)
public class Father{
public void way(){
System.out.println("父类");
}
}
public class Test{
public static void main(String [] args){
Father father = new Father(){
@Override
public void way(){
System.out.println("子类");
}//重写父类方法
};//完成匿名内部类创建,此类为Father类子类
father.way();//出现多态现象,执行的为重写后的way方法;运行结果:子类
}
}
②匿名内部类可以是抽象类的子类(如果还存在抽象方法,那么要在内部类中实现)
把①中方法改为抽象方法
public abstract class Father{
public abstract void way();
}
public class Test{
public static void main(String [] args){
Father father = new Father(){
@Override
public void way(){
System.out.println("方法已实现");
}//重写实现父类方法
};//完成匿名内部类创建,此类为抽象类Father子类
father.way();//运行结果:方法已实现
}
}
③匿名内部类可以是接口的实现类(同上理解)
把②中抽象类改为接口
public interface Father{
void way();
}
public class Test{
public static void main(String [] args){
Father father = new Father(){
@Override
public void way(){
System.out.println("接口已被实现");
}//重写实现接口方法
};//完成匿名内部类创建,此类为接口Father实现类
father.way();//运行结果:接口已被实现
}
}
④匿名内部类为抽象类子类或接口实现类时,要保证所有抽象方法都被实现的原因:匿名内部类没有类名,无法再由子类继承实现未实现的抽象方法,且匿名内部类本身也不能是抽象类。
总结:
1、无论是匿名内部类还是有名内部类,编译后都会产生一个独立的class文件:
①如果该内部类为有名内部类,则有名内部类字节码文件名为外部类的类名+ $ +内部类类名;
②如果为匿名内部类,则匿名内部类字节码文件名为外部类类名+ $ +数字;
2、外部类或外部接口 public 默认的;但是直接在类中定义的内部类,public 默认、protected、private均可使用(对比成员变量的用法)
public class Test{
private class Way{
public void func(){
System.out.println("私有内部类方法");
}
}//直接在类中定义的内部类,可以类似于成员变量的作用范围
public static void main(String [] args){
Way way = new Test().new Way();
way.func();//private修饰的内部类可以在本类中使用
}
}
3、我们知道,局部变量的作用范围只在其定义后至所在代码块结束,所以局部变量是没有访问权限一说的。如果在内部类中使用局部变量的值,则:JDK8.0及+可以不适用final修饰,8.0以前必须使用fianl
public void way(final String name) {//若为JDK8.0及以后则,final可以不写
class Test{
{
System.out.println(name);
}
}
}