【成员内部类】
内部类:将一个类在另一个类中定义。
class Outer8{
class Inner{
}
}
Inner就是内部类。而编译后,会在目录中生成两个class文件
Outer8.class就是外部类。
Outer8$Inner.class就是Inner类在Outer8类中。
访问方式:
内部类可以访问外部类的所有成员,包括私有。
class Outer{
private int i=3;
class Inner{
int i2=i;
}
}
外部类若要访问内部类,内部类作为外部类的成员,所以应该先创建外部类的实例。
class Outer{
class Inner{
}
public Inner getInstance(){
return new Outer().new Inner();
}
}
非静态内部类中不允许定义静态成员,仅允许定义静态常量 static final
若要定义静态成员,内部类必须是静态成员。
【例子】
class Outer{
int num=3;
class Inner{
int num=4;
public void method(){
int num=5;
System.out.println(num);
System.out.println(this.num);
System.out.println(Outer.this.num);
}
}
}
如果什么都不加就是访问局部变量
如果要访问内部类当前对象的,则是this.num
如果要访问外部类成员,则是Outer.this.num
【局部内部类】
将类定义在方法区或是作用域中。
class Outer{
public void method(){
class Inner{}
}
}
局部内部类不允许被成员修饰符修饰,类似于public,static
局部内部类访问内部类中的成员,只允许访问被final修饰的局部变量
原因:
若假设可以访问。
1.main()压栈执行,实例化Outer对象。属性为obj。调用method()
2.method()压栈,显示初始化变量i,o=new Inner(),加载Inner类,调用构造函数,创建对象。i释放内存
3.method()弹栈,调用method3(), obj=new Inner()相当于Object obj=new Inner();多态
4.调用method2()中的方法需要输出打印i,i早已释放内存,怎么调用???
class Outer{
Object obj;
public void method(){
int i=3;
class Inner{
public void method2(){
System.out.println(i);
}
}
obj= new Inner();
}
public void method3(){
obj.method2():
}
}
class Demo{
public static void main(String[] args){
Outer o=new Outer();
o.show();
o.method3();
}
}
【匿名内部类】
内部类是可以继承父类和实现接口的。
interface B{
public abstract void method();
}
class A{
public void method2(){}
}
class Outer{
class Inner extends A implements B{
@override
public void method(){}
}
}
为了简化代码,就有了匿名内部类。
interface Inter{
public abstract void method();
}
class Outer{
public void method(){
new Inter(){
@override
public void method(){}
};
}
}
【匿名内部类代码体现】
父类/接口 引用变量=new 父类/接口();
【匿名内部类的条件、前提】
匿名内部类必须由继承父类或是实现接口
匿名内部类类似于匿名对象,然而一般匿名内部类是用来简写代码,不知道匿名内部类叫什么,所以通过多态的原理
利用父类创建对象,并且重写方法。
【例子】
class Outer{
//编译通过
new Object(){
public void show(){}
}.show();
//编译失败
Object o=new Object(){
public void show(){}
};//.show();
o.show();//报错
}
为什么一个能通过,另一个却不能通过呢?
前者是因为创建子类对象,却没有父类引用,所以对象本身重写方法,所以不报错。
而后者是因为创建子类对象,父类引用,而父类中并没有show()这个方法,一调用就会报错。
而如果不调用,是不会报错的。
【静态内部类】
静态内部类就是在成员内部类前加static,静态内部类不属于外部类。可以当成另一个外部类。因为不依赖于外部类。并且不能访问父类的非静态成员。
并且非静态内部类不能访问静态成员,可能编译器会通过。
考虑这么一个情况:如果非静态内部类还没被实例化,直接调用了静态成员。但是静态成员是随着类的加载而加载。却可以调用静态成员。矛盾
class Outer{
static int num=3;
int num2;
static void method2(){
System.out.println(num);
}
static class Inner{
void method(){
//可以访问外部类的静态成员,但不能访问外部类的非静态成员
System.out.println(num);//编译通过
System.out.println(num2);//报错
}
}
class Inner2{
method();//无法做到
}
}
外部进行访问静态内部类的方式
class Outer{
static class Inner{
public static void show(){}
public void show2(){}
}
}
class Demo{
public static void main(String[] args){
//调用静态内部类的静态方法
Outer.Inner.show();
//1.若要调用静态内部类的非静态方法,可以不依赖外部类直接创建实例并调用非静态方法
new Inner().show();
//2.或是先给引用变量
Outer.Inner i=new Inner();
i.show();
}
}