为什么使用内部类?存在即合理!(洗这么解释吧,详细解释看文末)
在java中,可以将一个类定义在另一个类的内部或方法体中,这样的类我们称之为内部类
通常情况下,内部类包括这四种:
静态内部类,成员内部类,局部内部类,匿名内部类,
一、静态内部类
静态内部类可以访问外部类的静态变量(包括private),但无法访问外部类的成员变量
/**
* Created by yan on 2019/1/18.
*/
public class Outer { //创建一个外部类Outer
private static int i = 0;
public static int j = 1;
//静态内部类
static class Inner { //创建一个静态内部类Inner
public void innerFun(){
System.out.println(i);
System.out.println(j);
}
}
}
静态内部类对象的创建方式是
外部类.内部类 对象 = new 外部类.内部类()
Outer.Inner demo = new Outer.Inner();
二、成员内部类
1、成员内部类是最普通的内部类,它定义在另一个类的内部
声明在类内部,方法外部
没有static修饰
不能包含静态属性和静态方法(静态常量除外,final static int i = 0;)
在拥有外部类对象之前是不能拥有内部类对象的
在外部类对象创建内部类的同时,内部类自动拥有一个外部类的引用,可以访问外部类对象的所有成员,包括private
外部类无法直接访问成员内部类的方法和属性,需要通过内部类的一个实例来访问
/**
* Created by yan on 2019/1/18.
*/
public class Outer {
private static int i = 0;
public static int j = 1;
//成员内部类
class Inner {
public void InnerFun(){
System.out.println(i);
System.out.println(j);
}
}
}
成员内部类创建对象的方式
Outer outer = new Outer(); //创建外部类对象
Outer.Inner inner = outer.new Inner(); //创建成员内部类对象
当成员内部类拥有和外部类相同属性时,内部类默认访问内部类中的属性,
若要访问外部类中的属性需要:
Outer.this.变量
/**
* Created by yan on 2019/1/18.
*/
public class Outer {
private static int i = 0;
public static int j = 1;
//成员内部类
class Inner {
private int i = 10;
int j = 11;
public void InnerFun(){
System.out.println(i); //10
System.out.println(j); //11
System.out.println(Outer.this.i); //0
System.out.println(Outer.this.j); //1
}
}
}
输出结果:
三、局部内部类
局部内部类是定义在方法中的
1.若定义在static方法中,仅可以访问静态的变量
2.若定义在成员方法中,可以访问外部类的所有变量(Outer.this.变量 )
3.局部内部类就像是方法里面的一个局部变量一样,是不能有public、protected、private以及static修饰符的。
/**
* Created by yan on 2019/1/18.
*/
public class Outer {
private static int i = 0;
int j = 1;
public static void main(String[] args) {
int y = 20; //JDK1.8之前需要用final修饰,局部内部类才可以访问
//局部内部类 定义在静态方法中的局部内部类是无法访问外部类的非静态的变量
class Inner{
public void innerFun(){
System.out.println(i);
System.out.println(y);
}
}
Inner inner = new Inner();
inner.innerFun();
}
}
四、匿名内部类(稍后补上)
匿名内部类是没有类名的,而且只可以创建唯一次对象
五、为什么使用内部类
1.封装和隐藏
在内部类中可以对一系列相关属性进行封装,当把内部的权限修饰为private,那么这样就会使得封装的信息完全与外界隔绝,内部类时不可以被覆盖的,所以可以对业务逻辑进行很好的保护,而不至于担心被重写
2.多继承解决方案
是的没错,java为了摒弃c++中多继承的痛点,采用了单继承。虽然这样会安全很多,但是无疑会在某些情境下感觉限制。那么内部类就可以解决问题,这使得java的继承变得更加完整
NOTE: 有以下几点需要注意的地方
1)这里的继承是指内部类继承其他类,与前面介绍的其他类继承内部类不一样
2)多继承,不是指,内部类可以打破java的单继承定律,一个内部类可以继承多个类,这是错误的理解方式。
这里是指可以在外部类中定义多个内部类分别继承不同的类
内部类可以任意的实现一个接口或者继承一个类,与外部类是否实现接口和继承该类没有任何关系,那么在这种情况下,在外部类中就可以任意创建多少个内部类来继承或者实现你想要的接口,而不会对外部类产生任何的影响。继而在外部类中可以通过内部类获取到继承的类或接口中的属性和方法。
3.并且可以访问外部类信息
内部类除了包含自己的信息外,也包含了外部类的信息,对于成员内部类来说,它会自动拥有一个外部类的引用,可以访问外部类所有的非静态的属性和方法,包括private