1.内部类访问特点:
1.可以直接访问外部类的私有成员.
2.外部类想要访问内部类时,要在外面创建内部类的对象,进行调用.
1.2内部类什么时候使用呢?
一般用于类的设计.
分析事物时,发现该事物描述中还有事物,
而且这个事物还在访问被描述事物的内容,
这时就是还有的事物定义成内部类来描述.
例如:心脏要经常使用人体内部的其他器官,
所以心脏就是内部类,人就是外部类.
class Outer
{
private static int num = 4;
static class Inner
{
static void show()
{
System.out.println("show........"+num);
}
}
void method()
{
Inner in = new Inner();
in.show();
}
}
class innerClassDemo
{
public static void main(String[] args)
{
Outer o = new Outer();
o.method();
//直接访问外部类中的内部类
// Outer.Inner in = new Outer().new Inner();
// in.show();
//如果一个内部类是静态的,那么该类相当于一个外部类.
Outer.Inner i = new Outer.Inner();
i.show();
//Outer.Inner.show();
}
}
1.3为什么内部类能直接访问外部类中成员呢?
那是因为内部类持有了外部类的引用, 外部类名.this;
2.内部类可以存放在局部位置上.
内部类在局部位置上只能访问局部中被final修饰的局部变量.
class Outer
{
private int num = 2;
class Inner
{
private int num = 3;
void show()
{
int num = 4;
System.out.println(Outer.this.num);
}
}
void method()
{
new Inner().show();
}
//局部内部类
void method2()
{
final int x = 1;
class Inner2
{
void show()
{
System.out.println("show......."+x);
}
}
new Inner2().show();
}
}
class innerClassDemo3
{
public static void main(String[] args)
{
Outer o = new Outer();
o.method();
o.method2();
}
}
3.匿名内部类:
有前提:
内部类必须继承或者实现一个外部类或者接口.
匿名内部类:其实就是一个匿名子类对象.
格式: new 父类or接口() {子类内容}
abstract class Demo
{
abstract void show();
}
class Outer
{
int num = 4;
/* class
{
void show()
{
System.out.println("show....."+num);
}
}
*/
public void method()
{
new Demo()
{
void show()
{
System.out.println("show........");
}
void haha()
{
System.out.println("hah........");
}
}.haha();
}
}
class innerClassDemo4
{
public static void main (String[] args)
{
new Outer().method();
}
}
3.2 应用例子
interface Inter
{
public abstract void show1();
public abstract void show2();
}
class Outer
{
/* class Inner implements Inter
{
public void show1()
{
System.out.println("haha");
}
public void show2()
{
System.out.println("haha");
}
}
*/
public void method()
{
// new Inner().show1();
// new Inner().show2();
Inter in = new Inter()
{
public void show1()
{
System.out.println("haha");
}
public void show2()
{
System.out.println("haha");
}
};
in.show1();
in.show2();
}
}
/*
通常的使用场景之一:
当函数的参数是接口类型时,而且接口中的方法不超过三个.
可以用匿名内部类作为实际参数进行传递.
*/
class innerClassDemo5
{
public static void main(String[] args)
{
show(new Inter(){
public void show1()
{
System.out.println("haha");
}
public void show2()
{
System.out.println("haha");
}
});
}
public static void show(Inter in)
{
in.show1();
in.show2();
}
}
3.3举例
class Outer
{
/* void method()
{
new Object(){
void show()
{
System.out.println("show run");
}
}.show();
//这个编译可以通过,因为直接调用的是子类对象
*/
void method()
{
Object obj = new Object(){
void show()
{
System.out.println("show run");
}
};
obj.show();//编译时不能通过!
//因为匿名内部类这个子类对象被向上转型为了Object类型.
//这样就不能使用子类特有的方法了
}
}
class innerClassDemo6
{
public static void main(String[] args)
{
new Outer().method();
}
}
4.类的初始化过程
class Father
{
{
System.out.println("father construction block");
}
Father()
{
super();//object
//显示初始化
//构造代码块初始化
System.out.println("father constructor ");
show();
}
void show()
{
System.out.println("haha");
}
}
class Kid extends Father
{
int num = 8;//默认初始化 num = 0;
{
num = 9;
System.out.println("Kid construction block");
}
Kid()
{
super();//Father
//显示初始化
//构造代码块初始化
System.out.println("Kid constructor");
show();
}
void show()
{
System.out.println("show......."+num);
}
}
class intiProcess
{
public static void main(String[] args)
{
new Kid();
}
}
运行结果
综上可得:先默认初始化->通过super()跳到父类->父类默认初始化->父类构造函数块初始化->父类构造函数初始化->子类显示初始化->子类构造函数块初始化->子类构造函数初始化