内部类提供了更好的封装,可以把内部类隐藏在外部类之内,不允许同一个包内的其他类访问该类。假设需要创建一个Cow类,Cow类需要组合一个CowL对象,CowLeg类只有在Cow类里才有效,离开Cow类之后没有任何意义。在这种情况下就可以把CowLeg定义成Cow的内部类,不允许其他类访问CowLeg
内部类成员可以访问外部类的私有数据,因为内部类当作外部类的类成员,类成员之间可以互相访问,但是外部类不能访问内部类的实现细节,例如内部类的成员变量
匿名内部类适合用于创建那些仅仅需要一次使用的类
非静态内部类
public class Cow
{
private double weight;
public Cow(){}
public Cow(double weight)
{
this.weight=weight;
}
private class CowLeg
{
private double length;
private String color;
public CowLeg(double length,String color)
{
this.length=length;
this.color=color;
}
public void setLength(double length)
{
this.length=length;
}
public double getLength()
{
return this.length;
}
public void setColor(String color)
{
this.color=color;
}
public String getColor()
{
return this.color;
}
public void info()
{
System.out.println("当前牛的颜色"+color+",高:"+length);
System.out.println("本牛腿所在奶牛重:"+weight);
}
}
public void test()
{
CowLeg cl=new CowLeg(1.12,"黑白相间");
cl.info();
}
public static void main(String[] args)
{
Cow cow=new Cow(378.9);
cow.test();
}
}
当调用非静态内部类的实例方法时,必须有一个非静态内部类实例,而非静态内部类实例必须寄存在外部类实例里
静态内部类
一个内部类用static修饰,这个内部类就是静态内部类,这个静态内部类属于外部类本身,而不属于外部类的对象。静态内部类是外部类的一个静态成员,因此外部类的静态方法,静态初始化块可以使用静态内部类来定义变量,创建对象。外部类依然不能直接访问静态内部类的成员,但可以使用内部类的类名作为调用者来访问静态内部类的类成员,也可以使用静态内部类对象作为调用者来访问静态内部类的实例成员
使用内部类
1.在外部类内部使用内部类
在外部类内部使用内部类时,与平常使用普通类没有太大的区别
2.在外部类以外使用非静态内部类
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("测试信息");
}
}
3.在外部类以外使用静态内部类
class StaticOut
{
static class StaticIn
{
public StaticIn()
{
System.out.println("静态内部类的构造器");
}
}
}
public class CreateStaticInnerInstance
{
public static void main(String[] args)
{
StaticOut.StaticIn in=new StaticOut.StaticIn();
}
}
匿名内部类
匿名内部类必须继承一个父类或实现一个接口,但最多只能继承一个父类,或实现一个接口。匿名内部类不能使抽象类,匿名内部类不能定义构造器,因为匿名内部类没有类名,但是匿名内部类可以定义实例初始化块,通过实例初始化块来完成构造器需要完成的事情。最常用的创建匿名内部类的方式是需要创建某个接口类型的对象
interface ChanPin
{
public double getPrice();
public String getName();
}
public class AnonymousTest
{
public void test(ChanPin p)
{
System.out.println("购买了一个"+p.getName()+",花掉了"+p.getPrice());
}
public static void main(String[] args)
{
AnonymousTest ta=new AnonymousTest();
ta.test(new ChanPin()
{
public double getPrice()
{
return 567.8;
}
public String getName()
{
return "AGP显卡";
}
});
}
}