Java中的内部类

内部类:顾名思义,在外部类中定义的类就是内部类。
内部类可以分为有名内部类匿名内部类静态内部类非静态内部类 (本篇不讨论静态内部类 )

有名内部类

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);
				}
		}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值