内部类是在一个类中定义的类。
内部类的主要作用有以下几点:
1.内部类可以很好的被隐藏;
2.内部类拥有外部类所有成员的访问权限;
3.内部类可以间接实现多继承;
4.可以避免继承和实现接口出现同名方法冲突;
一.隐藏效果
普通的类的访问修饰符只有public
,abstract
,final
,不允许private
,protect
等修饰,但是内部类中可以,例如:
public class OutsideClass{
private class InsideClass{
public void test(){
System.out.println("Test");
}
}
public InsideClass getInside(){
return new InsideClass();
}
}
public class Test{
public static void main(String[] args){
OutsideClass out = new OutsideClass();
out.getInside.test();
}
}
对于外部来说类InsideClass完全被隐藏,看不到代码实现甚至连类名都无法知道。
二.访问外围类的成员
public class OutsideClass{
private String name = "XC";
private int age = "18";
private class InsideClass{
public String getName(){
return name;
}
}
public InsideClass getInside(){
return new InsideClass();
}
}
public class Test{
public static void main(String[] args){
OutsideClass out = new OutsideClass();
String name = out.getInside.getName();
}
}
尽管name属性是OutsideClass的私有成员,但是在InsideClass中可以无条件访问。
三.实现多继承
个人认为这是内部类存在最重要的一点。因为java类只能单继承,尽管避免了多继承导致的耦合度高,子类成员冗余等问题,但是在某些场合需要多继承实现,使用接口有很多不便的情况,所以用内部类实现多继承是一个很好的实现。例如:
//父亲类
public class Father{
//父亲发色是黑色的
private String hair = "black";
public String getHairColor(){
return hair;
}
}
//母亲类
public class Mother{
//母亲眼珠是蓝色的
private String eyes = "blue";
public String getEyesColor(){
return eyes;
}
}
//儿子
public class Son{
private String hair;
private String eyes;
//儿子发色继承父亲
private class InheritHair extend Father{
public String getHair(){
return super.getHairColor();
}
}
//儿子瞳色继承母亲
private class InheritEyes extend Mother{
public String getEyes(){
return super.getEyesColor();
}
}
public String getHair(){
this.hair = new InheritHair().getHair();
return this.hair ;
}
public String getEyes(){
this.eyes= new InheritEyes().getEyes();
return this.eyes;
}
}
public class Test{
public static void main(String[] args){
Son son= new Son();
String hair = son.getHair();//black
String eyes = son.getEyes();//blue
}
}
儿子Son中有两个内部类InheritHair
和InheritEyes
,分别继承了父亲的getHairColor方法和black发色,继承了母亲getEyesColor方法和blue瞳色,所以在类Son中就同时有了Father和Mother的属性和方法,间接实现多继承。
四.避免接口和继承类中同名方法
如果一个类继承了一个父类但是又实现了一个接口,但是有同名方法的时候该怎么办,如何区分它们?例如:
//定义接口
public interface Flying{
void fly();
}
//定义父类
public class Bird{
public void fly(){
System.out.println("I can fly");
}
}
//飞机继承Bird类 实现Flying接口(飞机会飞是跟鸟学的吗?)
public class Plane extend Bird implements Flying{
@overwrite
public void fly(){};//我从哪里来??是重写父类的方法还是接口方法
}
用内部类来解决这个问题
public class Plane extend Bird{
private class InsidePlane implements Flying{
@overwrite
public void fly(){
System.out.println("Interface fly");
};
}
public void fly1(){
return super.fly();
}
public void fly2(){
return new InsidePlane().fly();
}
}
用外部类去继承父类,用内部类去实现接口,这样两个fly方法就不会冲突了。