内部类
内部类是指在一个外部类的内部再定义一个类。类名不需要和文件夹相同。内部类可以是静态static的,也可用public,default,protected和private修饰。(而外部顶级类即类名和文件名相同的只能使用public和default)。
为什么要使用内部类?在《Think in java》中有这样一句话:使用内部类最吸引人的原因是:每个内部类都能独立地继承一个(接口的)实现,所以无论外围类是否已经继承了某个(接口的)实现,对于内部类都没有影响。
在我们程序设计中有时候会存在一些使用接口很难解决的问题,这个时候我们可以利用内部类提供的、可以继承多个具体的或者抽象的类的能力来解决这些程序设计问题。可以这样说,接口只是解决了部分问题,而内部类使得多重继承的解决方案变得更加完整。
内部类主要有如下几个作用:
- 内部类提供了更好的封装,不允许外部类同一个包下的其他类访问该类。
- 内部类成员可以直接访问外部类的私有数据,因为内部类被当做外部类的成员。但外部类不能访问内部类的实现细节,例如内部类的成员变量。
- 匿名内部类适合用于那些创建那些仅需要使用一次的类
与外部类的区别
- 内部类可以是静态static的,也可用public,default,protected和private修饰
- 非静态内部类不能拥有静态成员
1、成员内部类
定义内部类在一个类的内部定义,“类内部”包括类中的任何位置,甚至可以在方法中定义。
成员内部类分为两种:静态内部类和非静态内部类,以static修饰符界定
非静态内部类
- 当非静态内部类的方法访问某变量时,先找方法内是否有改变量,再内部类中找,再外部类中找,如果还找不到,则系统出现编译错误。
- 当非静态内部类的成员可访问外部类的private成员,反之不成立,如果外部类想访问内部类的成员,则必须显式创建非静态内部类的对象调用其方法访问。
静态内部类
如果使用static来修饰一个内部类,则这个内部类就属于外部类本身,也称类内部类,也称静态内部类。
静态内部类可以包含静态成员,也可以包含非静态成员
静态内部类不可以访问外部类的实例对象,只能访问外部类的类成员。即使是静态内部类的实例方法也不能访问外部类的实例对象,只能访问外部类的静态成员
因为静态内部类是外部类的一个静态成员,所以外部类的所有方法,初始化块都可以使用静态内部类来定义变量、创建对象等。
接口中可以定义内部类,但只能是静态内部类,默认用public static修饰。
2、局部内部类
如果内部类在方法内定义,那这个内部类就是一个局部内部类,局部内部类仅在该方法里有效。因为局部内部类不能在方法外使用,所以不能使用访问控制符合static修饰符修饰。
public class A{
public void add(){
class InnerBase
{
int a;
}
}
}
3、匿名内部类
匿名内部类适合只需要使用一次的类
//格式
new 实现接口||父类(){
}
//例子
interface Person {
public void eat();
}
public class Demo {
public static void main(String[] args) {
Person p = new Person() {
public void eat() {
System.out.println("eat something");
}
};
p.eat();
}
}
规则:
- 匿名内部类不能是抽象类
- 匿名内部类不能定义构造器,但可以定义初始化块,可以通过实例化初始化块来完成构造器需要完成的事。
4、使用内部类
在外部类内部使用
和平常使用类无太大区别,需要注意的是不要在外部类的静态成员内部使用非静态内部类。
在外部类以外使用非静态内部类
如果想使用的话,内部类不能用private修饰
- 省略修饰符的内部类,只能被外部类同一个包中的其他类访问
- protected修饰,可被外部类同一个包中的其他类和外部类的子类访问
- public修饰,可在任何地方被访问
在外部类以外使用静态内部类
语法:
new A.Inner()