内部类的目的是什么?

60

我正在审查Java中的内部类的概念。目前为止,从我理解和应用的角度来看,Java内部类与其外部/封闭类的方法和字段有关或可访问。

我的问题:

  1. 在什么情况下应该创建或定义内部类?
  2. 内部类是否被认为是“帮助类”?
  3. 您制作内部类的指标是什么,它们的其他目的是什么?

看这个:https://dev59.com/rHE95IYBdhLWcg3wf-AF - Fritz
13个回答

0
假设你有一个类型,它是一个类,名为 OuterClass,在 com.custom.classes 包中。
那么这就是您需要开始需要内部类或静态类的方式:
情况1: 1. 你需要打包一组类。 2. 但同时也需要在该包级别上公开某些全局变量。 3. 您明白您不能使用包来实现这些功能,但是意识到您可以通过继承来实现,其中父类成员可以作为全局变量,从而对其所有子类实例可用。 4. 但是您不喜欢需要继承父类以及需要实例化子类以访问全局变量的想法。 这就像要购买咖啡店以喝咖啡一样。 5. 所以您意识到您可以创建一个具有静态成员的 OuterClass,并将所有类作为内部类或静态类放置在其中。 好了! OuterClass 的静态成员就变成了这些嵌套类的全局变量,即使您甚至可以在没有实例化的情况下访问它们。
以下代码应该更好地解释了这个过程。
public class InnerClassTester{
  public static void main(String []args){

    // without the need to instantiate any class
    // static class without instantiation
    System.out.println(OuterClass.NestedStaticClass1.incrGlobalNum()); // outputs 1

    // static class instantiated
    OuterClass.NestedStaticClass2 koolObj = new OuterClass.NestedStaticClass2();
    // works with instantiation as well
    System.out.println(koolObj.incrGlobalNum()); // outputs 2

    // inner classes always need to be instantiated
    // and they can only be instantiated from within an instance of outer class
    // think of them as instance member of outer class and this would make sense
    OuterClass.NestedInnerClass1 koolObj2 = new OuterClass().new NestedInnerClass1();
    // works with inner classes as well
    System.out.println(koolObj2.incrGlobalNum()); // outputs 3
 }
}

class OuterClass{
    // global variable thats only accessible for select classes (or nested classes)
    // we also learn a purpose for private static fields
    private static int privateGlobalValue = 0;

    // classes to be grouped
    // static class
    public static class NestedStaticClass1{
        // no need to instantiate this class to access/update the global value
        public static int incrGlobalNum(){
            return ++privateGlobalValue;
        }
    }

    public static class NestedStaticClass2{
        // instantiate and still manipulate the global value
        public int incrGlobalNum(){
            return ++privateGlobalValue;
        }
    }

    // inner class
    public class NestedInnerClass1{
        // instantiate and still manipulate the global value
        public int incrGlobalNum(){
            return ++privateGlobalValue;
        }
    }

}

这让你想起了JavaScript中的闭包吗? :)

大多数嵌套类的应用都是基于设计决策。这意味着,每个嵌套类的情况都可以用其他设计替换。

但是话虽如此,我们也可以用组合模式替换继承模式(最近正在获得动力),尽管当类之间的依赖关系非常复杂时,继承模式肯定更好,因为完全组合依赖关系会很丑陋。

案例2:

  1. 你需要在OuterClass上实现两个接口,IShark和IMosquito,拥有相同签名的公共bite方法。
  2. 但是你想要显示两个不同的消息,因为鲨鱼的咬伤与蚊子的咬伤有些不同。
  3. 然而你知道这是不可能的,因为只能实现一个bite方法。
  4. 你知道你可以在同一个包中创建两个不同的类,分别实现这两个接口,并且实现各自的bite方法,并将它们组合在OuterClass中。
  5. 但是你希望在OuterClass中完成这个任务,因为这是你的设计决策,将咬伤行为封装在其中,可能是因为类内部存在私有变量的依赖关系。
  6. 很快你意识到你可以通过私有静态内部类来实现这两个接口,并使外部世界看起来像是被组合在一起。

看一下这段代码:

// no additional classes in the package

public class InterfaceTester{

     public static void main(String []args){

        // same class returns 2 instances - both compliant to 
        // either interfaces and yet different output

        IShark shark = OuterClass.getSharkInstance();
        System.out.println(shark.bite()); // outputs "Die fast bosedk!"

        IMosquito mosquito = OuterClass.getMosquitoInstance();
        System.out.println(mosquito.bite()); // outputs "Die slow bosedk!"
     }

}

interface IShark{
    public String bite();
}

interface IMosquito{
    public String bite();
}

class OuterClass implements IShark{

    // dependency of inner class on private variable
    private static String dieSlow = "Die slow bosedk!";
    private static String dieFast = "Die fast bosedk!";

    private static OuterClass outerInst;
    private static InnerClass innerInst;

    // private constructor to stop regular instantiation
    private OuterClass(){}

    // get a shark !
    public static IShark getSharkInstance(){
        return outerInst != null ? outerInst : new OuterClass();
    }

    // get a mosquito !
    public static IMosquito getMosquitoInstance(){
        return innerInst != null ? innerInst : new InnerClass();
    }
    // an implementation of bite
    public String bite(){
        return dieFast;
    }

    // inner class that implements the second interface
    private static class InnerClass implements IMosquito{
        // different implementation of bite
        public String bite(){
            return dieSlow;
        }
    }

}

这种设计决策案例很多,以上所有答案都列举了几个这样的案例。因此,认为这个功能是作为一种新模式而不是作为一个功能或特性引入的并不是错误的。


-1

同时它也能增加封装性,因为内部类可以声明为私有的。


-1

我认为这只是语言的一个特性。如果我们采用OOD并遵守SOLID原则,我不建议使用它。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接