使用内部类最吸引人的原因是:每个内部类都能独立地继承一个(接口的)实现,所以无论外围类是否已经继承了某个(接口的)实现,对于内部类都没有影响。
接口只是解决了部分问题,而内部类使得多重继承的解决方案变得更加完整。
public interface Father {
}
public interface Mother {
}
public class Son implements Father, Mother {
}
public class Daughter implements Father{
class Mother_ implements Mother{
}
}
如果Father、Mother不是接口,而是抽象类或者具体类呢?这个时候我们就只能使用内部类才能实现多重继承了。其实使用内部类最大的优点就在于它能够非常好的解决多重继承的问题
内部类带来如下特性(摘自《Think
in java》):
1、内部类可以用多个实例,每个实例都有自己的状态信息,并且与其他外围对象的信息相互独立。
2、在单个外围类中,可以让多个内部类以不同的方式实现同一个接口,或者继承同一个类。
3、创建内部类对象的时刻并不依赖于外围类对象的创建。
4、内部类并没有令人迷惑的“is-a”关系,他就是一个独立的实体。
5、内部类提供了更好的封装,除了该外围类,其他类都不能访问。
内部类基础
public class Outer {
private String name ;
private int age;
/**省略getter和setter方法**/
public class Inner{
public InnerClass(){
name = "gaosilin";
age = 30;
}
public void display(){
System.out.println("name:" + getName() +" ;age:" + getAge());
}
}
public static void main(String[] args) {
Outer outer = new Outer();
Outer.Inner inner = outer.new Inner();
inner.display();
}
}
--------------
Output:
name:gaosilin ;age:30
使用OuterClassName.this,产生一个正确引用外部类的引用public class Outer {
public void display(){
System.out.println("Outer");
}
public class Inner{
public Outer getOuter(){
return Outer.this;
}
}
public static void main(String[] args) {
Outer outer = new Outer();
Outer.Inner inner = outer.new Inner();
inner.getOuter().display();
}
}
-------------
Output:
Outer
这个性质也用于内部类引用外部类的同名成员变量成员内部类
第一:成员内部类中不能存在任何static的变量和方法;
第二:成员内部类是依附于外围类的,所以只有先创建了外围类才能够创建内部类。
public class OuterClass {
private String str;
public void outerDisplay(){
System.out.println("outer");
}
public class Inner{
public void innerDisplay(){
str = "gaosilin.";
System.out.println(str);
outerDisplay();
}
}
public Inner getInner(){
return new Inner();
}
public static void main(String[] args) {
Outer outer = new Outer();
Outer.Inner inner = outer.getInner();
inner.innerDisplay();
}
}
gaosilin
outer
//方法中
public class Parcel5 {
public Destionation destionation(String str){
class PDestionation implements Destionation{
private String label;
private PDestionation(String whereTo){
label = whereTo;
}
public String readLabel(){
return label;
}
}
return new PDestionation(str);
}
public static void main(String[] args) {
Parcel5 parcel5 = new Parcel5();
Destionation d = parcel5.destionation("chenssy");
}
}
//定义在作用域内
public class Parcel6 {
private void internalTracking(boolean b){
if(b){
class TrackingSlip{
private String id;
TrackingSlip(String s) {
id = s;
}
String getSlip(){
return id;
}
}
TrackingSlip ts = new TrackingSlip("chenssy");
String string = ts.getSlip();
}
}
public void track(){
internalTracking(true);
}
public static void main(String[] args) {
Parcel6 parcel6 = new Parcel6();
parcel6.track();
}
}
匿名内部类
public class Outer {
public Inner getInner(final int num,String str2){
return new Inner(){
int number = num + 3;
public int getNumber(){
return number;
}
};
}
public static void main(String[] args) {
Outer out = new Outer();
Inner inner = out.getInner(2, "gaosiling");
System.out.println(inner.getNumber());
}
}
interface Inner {
int getNumber();
}
1、 匿名内部类是没有访问修饰符的。
2、 new 匿名内部类,这个类首先是要存在的。如果我们将那个InnerClass接口注释掉,就会出现编译出错。
3、 注意getInnerClass()方法的形参,第一个形参是用final修饰的,方法的形参需要被匿名内部类使用,那么这个形参就必须为final。
4、 匿名内部类是没有构造方法的。
静态内部类静态内部类升级为外部类,否则不能定义任务静态方法和属性,随之内部类的一些特性也消失,比如获得外部类的引用将失败,再比如只能只用外部类的静态属性和方法而不是everything。