内部类
一个类或者接口定义在另一个类后者接口的内部
public class A1{//外部类
class B1{}//内部类
interface C1{}//内部接口
}
将一个类定义置入另一个类定义中,这就叫作"内部类“
内部类之外的类称为外部类
内部类的名称必须区别于它所在的外部类,和其它类之间没有要求
//内部类的全名叫做[外部类名称$内部类名称]
public class A1 {
public class A1{} //语法报错
class B1{} 语法正确,默认编译的结果名称为A1$B1.class
}
class B1{}
内部类可以访问其外部类的所有变量和方法
public class A1 {//外部类的范围限定词只能是public或者默认package
private String name;
public class B1 { //内部类的范围限定词可以是4种
public void pp() {
System.out.println(name);
System.out.println(A1.this.name);//这里的A1.this用于表示A1类对象
A1.this.name="ffff";
// System.out.println(this.name);报错的原因是this用于指代当前类的对象,当 //前类B1中并没有属性name
pp();
A1.this.pp();
}
}
private void pp(){}
}
外部类不能直接访问内部类的实现细节
内部类比外部类多了private/protected/static三个修饰符,这三个修饰符不能用在外部类上
非静态内部类不能拥有静态成员
protected class B1 {
private int age = 99;
{ } //允许包含非静态代码块
private static String password="123456";//非静态内部类中不能包含静态属性
static{ }//非静态内部类中不允许包含静态代码块
public B1() {//允许定义构造器和析构器方法
}
//public static void hh(){} //非静态内部类中不允许包含静态方法
内部类作用
内部类提供更好的封装
内部类可以直接访问外部类的私有成员
外部类需构建内部类才能访问
内部类分类
在java中,可以将一个类定义在另一个类里面或一个方法里,这样的类称为内部类。广泛意义上内部类包括 成员、局部、匿名、静态内部类。
非静态内部类
public class A1{
protected class B1{}//静态内部类是protected static class B1{}
}
特点:
和其他类一样,它只是定义在外部类中的另一个完整的类结构
可以继承自己的想要继承的父类,实现自己想要实现的父接口们,和外部类的父类和父接口无关
可以在非静态内部类中声明属性、方法、构造器等结构,但是不允许声明静态成员,但是可以继承父类的静态成员,而且可以声明静态常量。
可以使用abstract修饰,因此它也可以被其他类继承
可以使用final修饰,表示不能被继承
编译后有自己的独立的字节码文件,只不过在内部类前面冠以外部类名和$符号。
和外部类不同的是,它可以允许public,protected,缺省,private
外部类只允许public或缺省的
局部内部类
可以将内部类定义在一个方法或者一个代码块内
public class A1 {
private int age = 123;
public static void main(String[] args) {
A1 aa = new A1();
}
public void pp() {
Date birth = new Date();
// B1 bb=new B1();语法错误,要求局部内部类必须先定义后使用
class B1 { // 局部内部类,只能在所在的{}范围中使用,具备内部类的范围限定词和临
//时变量一致,只能添加final或者abstract
public void ff() {
System.out.println(age);
A1.this.age = 555;// 可以直接访问外部类中的成员
System.out.println(birth);
// 语法报错,在局部内部类中使用外部的临时变量,则外部临时变量必须是
//final的,只是final可以省略
// birth = new Date();针对引用类型修改地址是不允许,但是可以修改属性
System.out.println("B1...ff()");
}
}
B1 bb = new B1();
}
}
特点
可以在局部内部类中声明属性、方法、构造器等结构,但不包括静态成员,除非是从父类继承 的或静态常量