本文介绍了静态内部类与成员内部类之间的区别,以及他们的使用
静态内部类static inner class ( also called nested class )
成员内部类member inner class
局部内部类local inner class
匿名内部类anonymous inner class
普通类的class前面可以用public 、abstract 、 final修饰,其它的修饰符不可以,但是内部类可以使用类的访问修饰符 private protected,public ,还可以使用abstract、final、static修饰符。这里内部类与外围类的方法与成员属性是在同一个层次上,如果是局部内部类与匿名内部类是没有这些修饰符的
成员内部类创建的时候需要外围类的一个引用,而静态内部类则不需要这个引用
成员内部类不能有static的属性和方法,而静态内部类可以静态与非静态的属性和方法
静态内部类由于没有外围类的引用,所以不能访问外围类的非静态属性和方法,但是可以访问外围类的静态属性和方法。而成员内部类可以访问外围类的静态、非静态成员属性与方法。
代码片段
public class InnerClazz {
public Inner show() {
return new Inner();
}
public static Inner print() {
InnerClazz clzz = new InnerClazz();
return clzz. new Inner();
}
public class Inner {
public void print() {
System. out.println( "member inner class");
}
}
}
成员内部类在创建对象的时候需要一个外围类的引用,在外围类的非静态方法中,如show()里面创建内部类对象,直接new + 内部类类名即可,隐藏的为内部类传入一个外围类引用
在静态方法中 如print()方法,该静态方法可以由InnerClazz.print()调用,这里没有外围类的对象,而非静态内部类创建需要一个外围类的引用,所以,我们只能在静态方法内部创建一个外围类的对象,然后通过enclosingClassReference.new innerclass()创建内部类对象
代码片段
public class InnerClazz {
public StaticInner show() {
return new StaticInner();
}
public static StaticInner print() {
return new StaticInner();
}
public static class StaticInner {
public void print() {
System.out.println("nested inner class");
}
}
}
静态内部类创建不需要一个外围类引用,所以创建的时候无论是在静态方法还是非静态方法都可以使用 new + innerClass 类名的形式创建
内部类静态方法的调用和普通类中的静态方法调用时一样的,只需要innerClass类名 . 静态方法名,而且它的静态方法和普通类的静态方法一样,不能调用非静态的成员属性与方法,只可以使用静态成员属性与方法
代码片段
public class InnerClazz {
public void print() {
StaticInner.staticmethod();
}
public static class StaticInner {
public void print() {
System.out.println( "nested inner class");
}
public static void staticmethod() {
System.out.println( "static method");
}
}
}
在其他类调用的时候我们需要注意的是内部类的访问修饰符public protected private。 public可以在任何地方使用,private内部类除了外围类外其他地方都不能访问,protected只能在它的外围类,或者继承这个内部类的子类中访问
代码片段
public class InnerClazz {
public Inner getMemberClass() {
return new Inner();
}
public Static Inner getNestedClass() {
return new StaticInner();
}
/** 成员内部类 */
public class Inner {
public void print() {
System. out.println( "member inner class");
}
}
/** 静态内部类 */
public static class StaticInner {
public void print() {
System. out.println( "nested inner class");
}
public static void staticmethod() {
System. out.println( "static method");
}
}
}
在另外一个类中使用内部类
public final class OtherTest {
public static void main(String[] args) {
InnerClazz iclzz = new InnerClazz();
//OtherTest与InnerClazz是在同一个包下,所以不需要import InnerClazz所在的包
InnerClazz.Inner inner = iclzz.getMemberClass();
InnerClazz.StaticInner sInner = iclzz.getNestedClass();
//还可以用import指明内部类包路径的形式来表示
//import org.study.inner.InnerClazz.Inner;
//import org.study.inner.InnerClazz.StaticInner;
Inner oInner = iclzz.getMemberClass();
StaticInner si = iclzz.getNestedClass();
}
}
外围类返回内部类对象的方法使用接口来接收创建好的内部类对象,在其它类中,我们只需要接口来引用内部类对象即可,由于内部类设置为private修饰符,所以实现了对内部类的隐藏,在其它类中是无法使用该内部类类型的
代码片段
public class InnerClazz {
public Deal getMemberClass() {
return new Inner();
}
/** 成员内部类 */
private class Inner implements Deal {
public void print() {
System. out.println( "print member inner class");
}
public void show() {
System. out.println( "show member inner class");
}
}
}
interface Deal {
public void print();
public void show();
}
其它类中引用内部类对象
public final class OtherTest {
public static void main(String[] args) {
InnerClazz iclzz = new InnerClazz();
//向上转型,可以使用Deal接口来得到内部类对象
Deal deal = iclzz.getMemberClass();
deal.print();
deal.show();
}
}