外部类:包含内部类的类。
内部类: 把一个类放在另一个类的内部。
形式: public class 外部类{
【修饰符】【访问控制符】class 【类名】{
}
}
作用: 1。内部类提供了更好的封装,可以把内部类隐藏在外部类之内,不允许同一个包中的其他类访问该类。
2。内部类成员可以直接访问外部类的私有数据,因为内部类被当成其外部类成员,同一个类的成员之间可以互相访问。
public class Out{
private int a= 12;
public class Int{
public void say(){
System.out.println(a);//直接访问外部类私有属性
}
}
public void test(){
Int i = new Int();//外部类不能直接访问非静态内部类的实例属性,必须显式创建内部类对象
i.say();
}
public static void main(String[] args){
Out o = new Out();//只是创建了外部类,还未创建内部类对象
o.test();
}
}
PS:非静态内部类对象中保留外部类对象的引用。
非静态内部类不能有静态方法,静态属性,静态初始化块。
非静态内部类的对象必须寄存在外部类的对象里,因此创建非静态内部类之前,必须先创建其外部类的对象。
静态内部类可以包含静态成员,也可以包含非静态成员。静态内部类不能访问外部类的实例变量,只能访问外部类的类成员。即使静态内部类的实例方法也不能访问外部类的实例成员。
静态内部类是外部类的类相关,而不是外部类的对象相关的,也就是说,静态内部类的对象不是寄存在外部类对象里的,而是寄存在外部类的类本身中。当一个静态内部类的对象存在时,并不存在一个被它寄存的外部类对象,静态内部类的对象里只有外部类的类引用,没有外部类对象的引用。
3。 匿名内部类适合用于创建那些仅需要一次使用的类。
外部类以外定义内部类: Outclass.Inclass var;
外部类以外创建内部类实例:Outclass.new Inclass();
class Out
{
//定义一个非静态内部类,不使用访问控制符,即同一个包中其他类可访问该内部类
class In
{
public In(String msg)
{
System.out.println(msg);
}
}
}
public class CreateInnerInstance
{
public static void main(String[] args)
{
Out.In in = new Out().new In("测试信息");
/*
上面代码可改为如下三行代码:
使用OutterClass.InnerClass的形式定义内部类变量
Out.In in;
创建外部类实例,非静态内部类实例将寄存在该实例中
Out out = new Out();
通过外部类实例和new来调用内部类构造器创建非静态内部类实例
in = out.new In("测试信息");
*/
}
}
非静态内部类的构造器必须使用外部类对象来调用
public class SubClass extends Out.In
{
//显示定义SubClass的构造器
public SubClass(Out out)
{
//通过传入的Out对象显式调用In的构造器
out.super("hello");
}
}
匿名内部类: 创建匿名内部类时会立即创建一个该类的实例。 1 不能是抽象类 2 不能定义构造器 3 可以定义实例初始化块
new 父类构造器(实参列表) |实现接口()
{
//匿名内部类的类体部分
}
匿名内部类必须继承一个父类,或实现一个接口,但最多只能继承一个父类或实现一个接口。
最常用的创建匿名内部类的方式是 :需要创建某个接口类型的对象。
interface Product //接口
{
public double getPrice();
public String getName();
}
public class TestAnonymous
{
public void test(Product p)
{
System.out.println("购买了一个" + p.getName() + ",花掉了" + p.getPrice());
}
public static void main(String[] args)
{
TestAnonymous ta = new TestAnonymous();
//调用test方法时,需要传入一个Product参数,此处传入其匿名实现类的实例
ta.test(
new Product()
{
public double getPrice()
{
return 567.8;
}
public String getName()
{
return "AGP显卡";
}
});
}
}