Closed. This question is opinion-based。它当前不接受答案。
                            
                        
                    
                
            
                    
                
                        
                            
                        
                    
                        
                            想改善这个问题吗?更新问题,以便editing this post用事实和引用来回答。
                        
                        4年前关闭。
                    
                
        

我在阅读《用Java思考》,了解为什么存在内部类以及它们有助于解决什么问题。

这本书试图给出的最有说服力的理由是:


  每个内部类都可以独立地从实现继承。
  因此,内部类不受外部类是否
  已经从实现继承。


请帮助回顾我的理解:

存在内部类是因为Java不支持多重继承。 (多个继承)可以在内部类中完成,这是Outer class可以具有多个内部类,并且每个内部类都可以从不同的类继承。因此,以这种方式,可以实现多重继承。我能想到的另一个原因是内部类满足OOP设计原则composition better than inheritance

更新

我发现的大多数解释与以下答案相同。例如,GUI框架中使用的Inner类来处理事件处理程序。没有提到书中引用的原因。我并不是说下面的答案不好。其实。我真的很感激他们(+1)。我只想知道这本书有什么问题吗?

最佳答案

在阅读了书中引述的最令人信服的理由后,为什么想到多重继承的想法有点令人困惑。当一个类(内部或非内部)想要从一个以上的具体实现中继承行为时,多重继承就会引起问题。因此,与某些其他语言不同,在Java中,您不能定义类似以下的类:

class Child extends Father, Mother {
   // Child wants to inherit some behavior from Father and some from Mother
}


如您所见,只有内部类才能做的事情无法直接纠正或解决此Java决策(不支持多重继承)。

那么它们为什么存在,您可能想知道!嗯,在Java中,每个类都是顶级或内部的(也称为嵌套的)。在另一个类中定义的任何类都是内部类,而并非如此的任何类都是顶级类。

自然,人们可能想知道为什么要在其他类中定义类(即行为)。顶级课程还不够吗?

答案是肯定的。 Java始终只能具有顶级类。但是这个想法(也许)是没有充分的理由限制类成为其他类的成员!就像任何预定义类型(例如IntegerString等)一样,它都可以成为类的成员:

class Person {
  private String name; // a field the models a Person's name
}


程序员应该能够在类中定义自己感兴趣的行为:

class Person {
  private String name; // a field the models a Person's name
  private Address address; // address is a type defined here
  static class Address {
    String street;
    String city;
  }
}


这里发生了很多事情,尤其是像privatestatic等这些被称为修饰符的东西。有关它们的技术细节很多,但让我们稍后再回来讨论。基本思想是能够将行为定义为另一类的一部分。能否将Address类定义为Person类之外的顶级类?当然。但是拥有此功能很方便。

现在,由于引入了此功能,因此它开始用于另一个目的,该目的称为提供代码作为数据。这就是设计模式的出现方式,直到大约10年前,人们才想到可以使用内部类以代码形式提供数据。也许这让您有些困惑。请考虑以下我几乎完全从JDK类中获取的代码:java.lang.String.java:

public static final Comparator<String> CASE_INSENSITIVE_ORDER
                                     = new CaseInsensitiveComparator();
private static class CaseInsensitiveComparator
        implements Comparator<String> {

    public int compare(String s1, String s2) {
        int n1 = s1.length();
        int n2 = s2.length();
        // details excluded for brevity
        // return -1, 0, 1 appropriately
    }
}


这里发生了什么?

我们需要一种将字符串与另一个字符串进行比较的方法,并且需要能够进行不区分大小写的比较。因此,我们在外部类内部创建了Comparator接口的实现:String!这不是方便吗?如果内部类不存在,则必须是:

public class String {
  // ... the whole String class implementation

}
class CaseInsensitiveComparator
            implements Comparator<String> {
   // implements the comparator method
}


本身并不是“坏”的东西,但这意味着很多类会污染名称空间。内部类将行为的范围限制在外部类上。您可能会看到,这很方便。在这种情况下,数据是Comparator接口的实现,并且代码是一样的,因为我们正在对定义的内部类进行更新。

直到Java 7为止,使用匿名内部类(尤其是在您希望代码充当数据的情况下)进一步利用了此功能,并且在Java 8中它们已被Lambda表达式有效地替换。如今,您可能看不到任何新代码使用匿名内部类(换句话说,语言在发展)。

关于java - 了解内部类(为什么存在内部类),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/35698953/

10-15 04:36