内部类
一、概述
1、定义:一个类的内部有的类。
2、形象理解:
孙悟空进了铁杉公主的肚子里,孙悟空能访问她的心肝脾胃肾,而铁杉公主要访问就必须先找到孙悟空。
3、内部类的访问特点:
(1)内部类可以直接访问外部类的成员。
(2)外部类要访问内部类就必须先建立内部类对象。
4、内部类的应用场景:
一般用于类的设计,发现该事物描述中还有事物,而且这个事物还在访问被描述事物的内容,这时这个事务就要定义成内部类。
例如:人是一个类,人中的心脏也定义成一类,心脏可以访问人体的很多的成员。
二、内部类的访问(1):放在成员位置上
1、内部类定义在外部类的成员位置,就可以被成员修饰符修饰。例如:publi/static/private
2、直接访问外部类中的内部类(成员)。
(1)内部类被public和默认的修饰符的情况:
Outer.Inner in = new Outer().new Inner();
备注:不常用,加入内部类设计成private的话,就不能访问了,因为内部类就被当成成员了,要按成员的修饰属性来操作。
(2)内部类被static修饰的情况:
说明:外部类被加载的时候就产生了内部类,相当于外部类。
例如:static clss Inner{}
Outer.Inner in = new Outer.Inner();//不需要建立外部类对象,直接建立内部类就可以了。
(3)如果内部类是静态的方法是静态的不需要创建对象就可以使用方法。
static clsss Inner{
static void function(){…}
}
Outer.Inner.function();
(4)如果内部类中有静态方法,该内部类也必须是静态的。
3、问题:内部类能直接访问外部类中的成员?
答案:因为内部类持有外部类的引用。格式:外部类.this
4、实例代码如下:
class Outer
{
private static int number =10;
static class Inner
{
void show()
{
//内部类直接访问外部类成员
System.out.println("show run ..."+number);
}
static void function()
{
System.out.println("你调用了内部类的静态成员!");
}
}
//访问内部类:
public void method()
{
Inner in = new Inner();
in.show();
}
}
//测试用类
class InnerClassDemo
{
public static void main(String []args)
{
Outer out = new Outer();
out.method();
//直接访问外部类中的内部类成员
//Outer.Inner in = new Outer().new Inner();
//static修饰内部类的调用:
Outer.Inner in = new Outer.Inner();
in.show();
//直接访问被内部类的静态成员
Outer.Inner.function();
}
}
三、内部类细节
问题:外部类、内部类和方法中都有的变量的时候该访问哪个变量呢?
回答:用“类.this.变量”来控制,其中方法的变量就直接写上就可以了。
实例代码:
class Outer
{
int num = 3;
class Inner
{
int num = 4;
void show()
{
int num = 5;
System.out.println(num);//本方法中的
System.out.println(this.num);//内部类中的
System.out.println(Outer.this.num);//外部类中的
}
}
void method()
{
new Inner().show();
}
}
//测试用类:
class InnerClassDemo2
{
public static void main(String []args)
{
System.out.println("Hello,InnerClass!");
new Outer().method();
}
}
四、内部的访问(2):放在局部位置上
1、从内部类中访问局部变量,局部变量要声明成final类型。
实例代码如下:
class Outer
{
int num = 3;//全局变量num
void method()
{
final int x = 9;//局部变量,如果内部类要访问,就必须声明成final类型的
class Inner
{
void show()
{
System.out.println("show >>"+num);
System.out.println("show >>"+x);
}
}
Inner in = new Inner();
in.show();
}
}
//测试用类:
class InnerClassDemo3
{
public static void main(String []args)
{
System.out.println("hello,world!");
Outer out = new Outer();
out.method();
}
}
五、匿名内部类(内部类没名字)
1、实质:就是内部类的简写格式。
2、匿名内部类前提:内部类必须继承或实现一个外部类或接口。因为匿名内部类没名字,但是没名字你new什么对象呢,所以就要继承或实现一个外部类或接口。
3、实际设计举例:
abstract class Demo{
abstract void show();
}
class Outer{
int num = 10;
//匿名内部类:创建的是父类的子类的对象,这里同时就在创建对象的时候加上方法的定义。
new Demo{
void show(){
System.out.println(“你调用了匿名内部类了。。。”);
}
}.show();
}
4、总结:内部类的设计格式:new 父类 or 接口(){子类内容}
5、匿名内部类的应用场景之一:
当函数是接口类型时,而且接口中的方法不超过三个,可以使用匿名内部类作为实际参数进行传递。
举例:
class InnerClassDemo5
{
public static void main(String[] args)
{
System.out.println("Hello World!");
Outer out = new Outer();
out.method();
//匿名内部类做为实际参数传递
show(new Inter()
{
public void show1(){System.out.println("调用了show1()方法!");}
public void show2(){System.out.println("调用了show2()方法!");}
});
}
//匿名内部类使用场景之一:当函数是接口类型时,而且接口的中的方法不超过三个,可以使用匿名内部类
//做为实际参数来传递,相当于自定在传递的时候把方法传进去了
public static void show(Inter in){
in.show1();
in.show2();
}
}
6、涉及到的知识:在静态方法中不能使用this,内部类当成类的成员的时候要注意这点。
7、匿名内部类使用细节:
用Object来创建匿名对象的时候,创建的子类的对象的方法能在直接使用,因为匿名内部类这个子类对象被上转型为了Object类型,这样就不能在使用子类特有的方法。