当A类中的内容要被B类直接访问,而A类还需要创建B的对象,访问B的内容时,
这时,可以将B类定义到A类的内部。这样访问更为便捷。
将B称之为内部类(内置类,嵌套类)。
访问方式:
内部类可以直接访问外部类中的所有成员,包含私有的。
而外部类要想访问内部类中的成员,必须创建内部类的对象。
当描述事物时,事物的内部还有事物,这个内部的事物还在访问外部事物中的内容。
这时就将这个事物通过内部类来描述。
【内部类被访问的方式】
情况一:内部类在成员位置上的被访问方式。
成员是可以被指定的修饰符所修饰的。
public:不多见:因为更多的时候,内部类已经被封装到了外部类中,不直接对外提供。
static:
class Outer//外部类。
{
private static int num = 4;
public class Inner//内部类。
{
void show()
{
System.out.println("num="+num);
}
// static void show1(){}//非静态内部类中不允许定义静态成员。仅允许在非静态内部类中定义 静态常量 static final。
// 如果想要在内部类中定义静态成员,必须内部类也要被静态修饰。
}
/*
内部类被静态修饰后,随着Outer的加载而加载。可以把一个静态内部类理解为就是一个外部类。
*/
static class Inner2
{
void show2()
{
System.out.println("Inner2 show2 run..."+num);
}
static void staticShow()
{
System.out.println("Inner2 staticShow run");
}
}
void method()
{
/*Outer.*/Inner in = new /*Outer.*/Inner();
in.show();
}
}
class InnerClassDemo
{
public static void main(String[] args)
{
// Outer out = new Outer();
// out.method();
//测试情况一:直接访问Outer中的Inner内部类的非静态成员。
//创建内部类的对象就哦了。内部类作为成员,应该先有外部类对象,再有内部类对象。
// Outer.Inner in = new Outer().new Inner();
// in.show();
//测试情况二:对静态内部类中的非静态成员进行调用。
//因为内部类是静态,所以不需要创建Outer的对象。直接创建内部类对象就哦了。
// Outer.Inner2 in = new Outer.Inner2();
// in.show2();
// 如果静态内部类有静态成员,该如何访问呢?既然静态内部类已随外部类加载,而且静态成员随着类的加载而加载,
// 就不需要对象,直接用类名调用即可。
// Outer.Inner2.staticShow();
}
}
为什么内部类就能直接访问外部类中的成员呢?
那是因为内部类其实持有了外部类的引用 外部类.this
对于静态内部类不持有 外部类.this 而是直接使用 外部类名。
/*
内部类其实也可以定义在外部类的局部位置上。
内部类定义在局部时,只能访问被final修饰的局部变量。
为啥呢?因为编译生产的class中直接操作那个最终数值了。
为什么不能访问非最终的局部变量呢?
生命周期太短了
*/
class Outer
{
int num = 3;
void method()
{
final int x = 10;
// final int x = 5;//局部变量。
int y = 2;
class Inner//局部内部类。不能被成员修饰符修饰。
{
void show()
{
// System.out.println("y="+y);//访问失败。y的生命周期太短了。
System.out.println("x="+x);
System.out.println("inner show run........"+num);
}
}
new Inner().show();
}
}
/*
class Outer2
{
Object obj;
public void method()
{
int y = 9;
class Inner //extends Object
{
//覆盖了toString方法。
public String toString()
{
return "tostring:"+y;//假设可以访问y。
}
}
obj = new Inner();//给obj复制一个Inner对象。
}
public void function()
{
System.out.println(obj.toString());
}
}
*/
class InnerClassDemo3
{
public static void main(String[] args)
{
Outer out = new Outer();
out.method();
}
}