java中内部类的写法非常奇怪,个人觉得也不好理解,只需要了解一下它的语法就行。
概念:
1)在类的内部在定义一个类,类名不需要和文件相同
2)内部类一旦通过编译为生成两个独立的字节码文件
3)内部类可以访问外部类的私有成员而不破坏封装
分类
1.成员内部类
1)成员内部类不能有static属性和方法
2)必须先有外部类才能使用成员内部类
3)语法:
Outer out = new Outer();
Outer.Inner in = out.new Inner();
public class MyOutClazz {
private int value = 100;
class InnerClazz{
public void m(){
System.out.println(value);
}
}
public MyOutClazz(int value) {
this.value = value;
}
/**
* 返回 #{bare_field_comment}
*
* @return #{bare_field_comment}
*/
public int getValue() {
return value;
}
/**
* 设置 #{bare_field_comment}
*
* @param value
* #{bare_field_comment}
*/
public void setValue(int value) {
this.value = value;
}
public void f(){
InnerClazz innerClazz = new InnerClazz();
innerClazz.m();
}
}
public static void main(String[] args) {
MyOutClazz myOutClazz1 = new MyOutClazz(100);
myOutClazz1.new InnerClazz().m();;
MyOutClazz myOutClazz2 = new MyOutClazz(200);
myOutClazz2.new InnerClazz().m();;
}
运行结果
100
200
2.静态内部类
1)不依赖外部类对象,可直接创建内部类对象
2)只能直接访问外部类的静态成员
3)语法:
Out.Inner inner = new Out.Inner();
我们看下面的例子,给MyOutClazz 增加一个静态成员属性 和 静态内部类
static class InnerClazz2{
public void m(){
System.out.println(value2);
}
}
private static int value2 = 200;
public static void main(String[] args) {
MyOutClazz myOutClazz1 = new MyOutClazz(100);
// 1.创建成员内部类
MyOutClazz.InnerClazz innerClazz = myOutClazz1.new InnerClazz();
innerClazz.m();
// 2.创建静态内部类
MyOutClazz.InnerClazz2 innerClazz2 = new MyOutClazz.InnerClazz2();
innerClazz2.m();
}
运行结果
100
200
3.局部内部类
定义下方法内部,作用范围和创建对象的范围仅在方法主体中
我们看下面的例子
public interface Teacher {
public void teach();
}
public class TeachSystem {
public static void main(String[] args) {
Teacher teachSys = getTeachSys(1);
teachSys.teach();
}
public static Teacher getTeachSys(int val){
class EnglishT implements Teacher{
@Override
public void teach() {
System.out.println("English teacher");
}
}
class MathT implements Teacher{
@Override
public void teach() {
System.out.println("Math teacher");
}
}
if(val <= 10) {
return new EnglishT();
}else {
return new MathT();
}
}
}
我们可以将TeachSystem 的main 方法当成一个简单的 选课系统 传入参数val 根据一定的规则,选择课程是英语还是数学,这样设计我们很好的隐藏了内部的实现细节
运行结果
English teacher
而如果我们不使用部内部类,重新新建两个 English和 math的类 ,一个学生要选课话,都能不运行我们这个系统,不调getTeachSys这个方法
Teacher tea = new EnglishT();
tea.teach();
这样直接自己来选择课程了;
4.匿名内部类
匿名内部类是一种特殊的局部内部类,如果一个内部类满足如下两个特点,就可以改写为匿名内部类
1)该内部类继承自某个类或者实现某个接口
2)该内部类在整个方法,整个生命周期中只创建了一个对象
它的语法算java里比较有特色的了,刚我们设计的那个选课系统就可以改为匿名内部类
public class TeachSystem {
public static void main(String[] args) {
Teacher teachSys = getTeachSys(1);
teachSys.teach();
}
public static Teacher getTeachSys(int val){
if(val <= 10) {
// 返回 math
return new Teacher() {
@Override
public void teach() {
System.out.println("math teacher");
}
};
}else {
// 返回 English
return new Teacher() {
@Override
public void teach() {
System.out.println("english teacher");
}
};
}
}
}
运行结果
math teacher