静态内部类与成员内部类

前言

本文介绍了静态内部类与成员内部类之间的区别,以及他们的使用

正文

内部类的种类

静态内部类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();
     }
}

你可能感兴趣的:(内部类)