内部类
为什么要声明内部类?
- 当一个事物的内部,还有一个部分需要一个完整的结构进行描述,而这个内部的完整的结构又只为外部事物提供服务,不在其他地方单独使用,那么整个内部的完整结构最好使用内部类
内部类的形式
非静态成员内部类
- 编译后有自己独立的字节码文件,不过在内部类名前面冠以外部类名和$符号
- 可以在非静态 内部类中声明属性、方法、构造器等结构
- 不允许声明静态成员,但是可以继承父类的静态成员,而且可以声明静态常量
- 可以继承自己想要继承的父类,实现自己想要实现的父接口们,和外部类的父类和父接口无关
- 可以使用abstract修饰
- 可以使用final修饰
- 可以使用四种权限修饰符(外部类只允许使用public或缺省的)
- 可以使用外部类的所有成员,包括私有的
- 外部类的静态成员中不可以使用非静态内部类
- 外部类必须通过外部类的对象才能创建非静态内部类的对象
示例
public class TestInner{
public static void main(String[] args){
Outer out = new Outer();
Outer.Inner in= out.new Inner();
in.inMethod();
Outer.Inner inner = out.getInner();
inner.inMethod();
}
}
class Father{
protected static int c = 3;
}
class Outer{
private static int a = 1;
private int b = 2;
protected class Inner extends Father{
// static int d = 4;//错误
int b = 5;
void inMethod(){
System.out.println("out.a = " + a);
System.out.println("out.b = " + Outer.this.b);
System.out.println("in.b = " + b);
System.out.println("father.c = " + c);
}
}
public static void outMethod(){
// Inner in = new Inner();//错误的
}
public Inner getInner(){
return new Inner();
}
}
静态成员内部类
- 只可以在静态内部类中使用外部类的静态成员,哪怕是私有的
- 在外部类的外面不需要通过外部类的对象就可以创建静态内部类的对象
public class TestInner{
public static void main(String[] args){
Outer.Inner in= new Outer.Inner();
in.inMethod();
Outer.Inner.inTest();
}
}
class Outer{
private static int a = 1;
private int b = 2;
protected static class Inner{
static int d = 4;//可以
void inMethod(){
System.out.println("out.a = " + a);
// System.out.println("out.b = " + b);//错误的
}
static void inTest(){
System.out.println("out.a = " + a);
}
}
}
局部内部类
- 前面不能有权限修饰符
- 有作用域
- 可以使用所在方法的局部常量,即用final声明的局部变量
class Outer{
private static int a = 1;
private int b = 2;
public static void outMethod(){
final int c = 3;
class Inner{
public void inMethod(){
System.out.println("out.a = " + a);
// System.out.println("out.b = " + b);//错误的,因为outMethod是静态的
System.out.println("out.local.c = " + c);
}
}
Inner in = new Inner();
in.inMethod();
}
public void outTest(){
final int c = 3;
class Inner{
public void inMethod(){
System.out.println("out.a = " + a);
System.out.println("out.b = " + b);//可以,因为outTest是非静态的
System.out.println("method.c = " + c);
}
}
Inner in = new Inner();
in.inMethod();
}
}
枚举
public class TestEnum {
public static void main(String[] args) {
Season spring = Season.SPRING;
System.out.println(spring);
}
}
enum Season{
SPRING,SUMMER,AUTUMN,WINTER
}
public class TestEnum {
public static void main(String[] args) {
Season spring = Season.SPRING;
System.out.println(spring);
}
}
enum Season{
SPRING("春"),SUMMER("夏"),AUTUMN("秋"),WINTER("冬");
private String description;
private Season(String description){
this.description = description;
}
public String toString(){//需要手动编写,无法使用Generate toString()...
return description;
}
}
public class TestEnum {
public static void main(String[] args) {
Season[] values = Season.values();
for (int i = 0; i < values.length; i++) {
switch(values[i]){
case SPRING:
System.out.println(values[i]+":春暖花开,万物复苏");
break;
case SUMMER:
System.out.println(values[i]+":百花争艳,郁郁葱葱");
break;
case AUTUMN:
System.out.println(values[i]+":菊桂飘香,百树凋零");
break;
case WINTER:
System.out.println(values[i]+":梅花独开,大地一色");
break;
}
}
}
}
enum Season{
SPRING,SUMMER,AUTUMN,WINTER
}
注解
@Override
- 用于检测被修饰的方法为有效的重写方法,如果不是,则报编译错误,只能标记在方法上