<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                ## Chapter 9. General Programming(通用程序設計) ### Item 64: Refer to objects by their interfaces(通過接口引用對象) Item 51 says that you should use interfaces rather than classes as parameter types. More generally, you should favor the use of interfaces over classes to refer to objects. **If appropriate interface types exist, then parameters, return values, variables, and fields should all be declared using interface types.** The only time you really need to refer to an object’s class is when you’re creating it with a constructor. To make this concrete, consider the case of LinkedHashSet, which is an implementation of the Set interface. Get in the habit of typing this: [Item-51](/Chapter-8/Chapter-8-Item-51-Design-method-signatures-carefully.md) 指出,應該使用接口而不是類作為參數類型。更一般地說,你應該優先使用接口而不是類來引用對象。**如果存在合適的接口類型,那么應該使用接口類型聲明參數、返回值、變量和字段。** 惟一真正需要引用對象的類的時候是使用構造函數創建它的時候。為了具體說明這一點,考慮 LinkedHashSet 的情況,它是 Set 接口的一個實現。聲明時應養成這樣的習慣: ``` // Good - uses interface as type Set<Son> sonSet = new LinkedHashSet<>(); ``` not this: 而不是這樣: ``` // Bad - uses class as type! LinkedHashSet<Son> sonSet = new LinkedHashSet<>(); ``` **If you get into the habit of using interfaces as types, your program will be much more flexible.** If you decide that you want to switch implementations, all you have to do is change the class name in the constructor (or use a different static factory). For example, the first declaration could be changed to read: **如果你養成了使用接口作為類型的習慣,那么你的程序將更加靈活。** 如果你決定要切換實現,只需在構造函數中更改類名(或使用不同的靜態工廠)。例如,第一個聲明可以改為: ``` Set<Son> sonSet = new HashSet<>(); ``` and all of the surrounding code would continue to work. The surrounding code was unaware of the old implementation type, so it would be oblivious to the change. 所有的代碼都會繼續工作。周圍的代碼不知道舊的實現類型,所以它不會在意更改。 There is one caveat: if the original implementation offered some special functionality not required by the general contract of the interface and the code depended on that functionality, then it is critical that the new implementation provide the same functionality. For example, if the code surrounding the first declaration depended on LinkedHashSet’s ordering policy, then it would be incorrect to substitute HashSet for LinkedHashSet in the declaration, because HashSet makes no guarantee concerning iteration order. 有一點值得注意:如果原實現提供了接口的通用約定不需要的一些特殊功能,并且代碼依賴于該功能,那么新實現提供相同的功能就非常重要。例如,如果圍繞第一個聲明的代碼依賴于 LinkedHashSet 的排序策略,那么在聲明中將 HashSet 替換為 LinkedHashSet 將是不正確的,因為 HashSet 不保證迭代順序。 So why would you want to change an implementation type? Because the second implementation offers better performance than the original, or because it offers desirable functionality that the original implementation lacks. For example, suppose a field contains a HashMap instance. Changing it to an EnumMap will provide better performance and iteration order consistent with the natural order of the keys, but you can only use an EnumMap if the key type is an enum type. Changing the HashMap to a LinkedHashMap will provide predictable iteration order with performance comparable to that of HashMap, without making any special demands on the key type. 那么,為什么要更改實現類型呢?因為第二個實現比原來的實現提供了更好的性能,或者因為它提供了原來的實現所缺乏的理想功能。例如,假設一個字段包含一個 HashMap 實例。將其更改為 EnumMap 將為迭代提供更好的性能和與鍵的自然順序,但是你只能在鍵類型為 enum 類型的情況下使用 EnumMap。將 HashMap 更改為 LinkedHashMap 將提供可預測的迭代順序,性能與 HashMap 相當,而不需要對鍵類型作出任何特殊要求。 You might think it’s OK to declare a variable using its implementation type, because you can change the declaration type and the implementation type at the same time, but there is no guarantee that this change will result in a program that compiles. If the client code used methods on the original implementation type that are not also present on its replacement or if the client code passed the instance to a method that requires the original implementation type, then the code will no longer compile after making this change. Declaring the variable with the interface type keeps you honest. 你可能認為使用變量的實現類型聲明變量是可以的,因為你可以同時更改聲明類型和實現類型,但是不能保證這種更改會正確編譯程序。如果客戶端代碼對原實現類型使用了替換時不存在的方法,或者客戶端代碼將實例傳遞給需要原實現類型的方法,那么在進行此更改之后,代碼將不再編譯。使用接口類型聲明變量可以保持一致。 **It is entirely appropriate to refer to an object by a class rather than an interface if no appropriate interface exists.** For example, consider value classes, such as String and BigInteger. Value classes are rarely written with multiple implementations in mind. They are often final and rarely have corresponding interfaces. It is perfectly appropriate to use such a value class as a parameter, variable, field, or return type. **如果沒有合適的接口存在,那么用類引用對象是完全合適的。** 例如,考慮值類,如 String 和 BigInteger。值類很少在編寫時考慮到多個實現。它們通常是 final 的,很少有相應的接口。使用這樣的值類作為參數、變量、字段或返回類型非常合適。 A second case in which there is no appropriate interface type is that of objects belonging to a framework whose fundamental types are classes rather than interfaces. If an object belongs to such a class-based framework, it is preferable to refer to it by the relevant base class, which is often abstract, rather than by its implementation class. Many java.io classes such as OutputStream fall into this category. 沒有合適接口類型的第二種情況是屬于框架的對象,框架的基本類型是類而不是接口。如果一個對象屬于這樣一個基于類的框架,那么最好使用相關的基類來引用它,這通常是抽象的,而不是使用它的實現類。在 java.io 類中許多諸如 OutputStream 之類的就屬于這種情況。 A final case in which there is no appropriate interface type is that of classes that implement an interface but also provide extra methods not found in the interface—for example, PriorityQueue has a comparator method that is not present on the Queue interface. Such a class should be used to refer to its instances only if the program relies on the extra methods, and this should be very rare. 沒有合適接口類型的最后一種情況是,實現接口但同時提供接口中不存在的額外方法的類,例如,PriorityQueue 有一個在 Queue 接口上不存在的比較器方法。只有當程序依賴于額外的方法時,才應該使用這樣的類來引用它的實例,這種情況應該非常少見。 These three cases are not meant to be exhaustive but merely to convey the flavor of situations where it is appropriate to refer to an object by its class. In practice, it should be apparent whether a given object has an appropriate interface. If it does, your program will be more flexible and stylish if you use the interface to refer to the object. **If there is no appropriate interface, just use the least specific class in the class hierarchy that provides the required functionality.** 這三種情況并不是面面俱到的,而僅僅是為了傳達適合通過類引用對象的情況。在實際應用中,給定對象是否具有適當的接口應該是顯而易見的。如果是這樣,如果使用接口引用對象,程序將更加靈活和流行。**如果沒有合適的接口,就使用類層次結構中提供所需功能的最底層的類** --- **[Back to contents of the chapter(返回章節目錄)](/Chapter-9/Chapter-9-Introduction.md)** - **Previous Item(上一條目):[Item 63: Beware the performance of string concatenation(當心字符串連接引起的性能問題)](/Chapter-9/Chapter-9-Item-63-Beware-the-performance-of-string-concatenation.md)** - **Next Item(下一條目):[Item 65: Prefer interfaces to reflection(接口優于反射)](/Chapter-9/Chapter-9-Item-65-Prefer-interfaces-to-reflection.md)**
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看