2012-01-12 48 views
8

Trong một vấn đề hiện tại tôi đang gặp phải (printing a file to a physical printer in Java) Tôi đã chạy qua mã như một người điên cố gắng nuốt bất kỳ thông tin bị bỏ lỡ hữu ích nào từ javadoc của mỗi lớp được sử dụng.Khởi tạo Giao diện?

Bây giờ, tôi đã lấy khá một chút mã này từ các câu hỏi trước nên có một chút công bằng mà tôi không viết. Vấn đề tôi nhận thấy là mã tôi lấy là khởi tạo một đối tượng, nói "SimpleDoc" mà thực hiện một giao diện (Doc) và gán nó vào giao diện đó ?!

Tiểu Đoạn mã:

Doc mydoc = new SimpleDoc(textStream, flavor, null); 

Bây giờ như xa như tôi được dẫn đến hiểu trong java chúng ta tạo ra các đối tượng. Tôi quen thuộc với sự thừa kế, và tôi đã quen với mẹo sử dụng các giao diện để cho phép một lớp "kế thừa" nhiều lớp siêu.

Nhưng điều này không đúng. Bạn có thể tạo một lớp mà thực hiện một giao diện, đó là tốt với tôi. Nhưng những gì đang xảy ra ở đây khi một giao diện được tạo ra và một đối tượng được giảm xuống giao diện của nó? Tôi đang truy cập những gì khi tôi tham khảo mydoc chính xác?

+2

mydoc là tham chiếu đến đối tượng triển khai giao diện 'Doc'. Trong tình huống này, giao diện được sử dụng để xác định các phương thức có thể được gọi thông qua biến tham chiếu mydoc. Lưu ý rằng biến (mydoc) vẫn là một tham chiếu đến một đối tượng. – DwB

Trả lời

5

Bí quyết là nhận ra rằng bạn không phải là "tạo", "khởi tạo" hoặc "khởi tạo" giao diện. Bạn chỉ đơn giản là xác định một biến như là một cái gì đó mà bạn biết thực hiện giao diện đó. Bạn đang cơ bản nói với các lập trình viên khác đang làm việc trên mã này cho phần còn lại của phương pháp này, bạn chỉ quan tâm đến thực tế là myDoc là một Doc (tức là, cái gì đó thỏa mãn giao diện Doc). Điều này có thể làm cho lập trình đơn giản hơn vì quá trình tự động hoàn thành của IDE giờ đây sẽ chỉ hiển thị cho bạn các phương thức được xác định bởi giao diện này, chứ không phải mọi thứ mà SimpleDoc có khả năng làm.

Hãy tưởng tượng rằng trong tương lai bạn muốn mở rộng chức năng của mình để có thể triển khai các Tài liệu khác nhau tùy thuộc vào một số đầu vào. Thay vì tạo ra SimpleDoc một cách rõ ràng, bạn nói:

Doc mydoc = docFactory.getByType(inputType); 

Các docFactory có thể sản xuất bất kỳ loại Doc, và phương pháp này không thực sự quan tâm loại được instantiated, bởi vì nó sẽ đối xử với nó như một Doc không phân biệt.

+0

Một lợi thế lớn hơn nữa. Nếu bạn quyết định, trong tương lai, để sử dụng một ComplexDoc hoặc MySuperOptimizedDoc, bạn chỉ cần thay đổi phía bên phải của một dòng mã. – user949300

+0

@ user949300: Vâng, được cho là thay đổi bên phải * và bên trái * của một dòng mã không khó hơn nhiều. Nhưng bằng cách lập trình cho một giao diện ở nơi đầu tiên, bạn không mời các nhà phát triển bắt đầu gọi các phương thức trên 'SimpleDoc' mà không thể được thực hiện trên mọi loại' Doc' khác. Như bạn đã chỉ ra, điều này giúp giảm số lượng tái cấu trúc bạn cần thực hiện nếu loại Tài liệu thay đổi. – StriplingWarrior

+0

Cảm ơn bạn, giờ đây rõ ràng hơn rất nhiều! Tôi rất thích những kiến ​​thức về cách thức thực hành này giúp làm cho việc sử dụng một đối tượng rõ ràng hơn, điều đó thực sự giúp xác định lý do tại sao lại sử dụng các thực hành nhất định như thế này. – Alex

4

Bạn không thể tạo giao diện, những gì bạn làm ở đây là bạn tạo một đối tượng mydoc của lớp SimpleDoc thực hiện giao diện Doc. Vì lớp thực hiện giao diện này, bạn được phép xử lý mydoc như thể nó là một thể hiện của giao diện đó. Điều này cho phép bạn truy cập vào tất cả các phương pháp khai báo trong giao diện, mà được thực hiện trong lớp SimpleDoc

Nếu, ví dụ, Doc-Interface của bạn sẽ trông như thế này:

public interface Doc { 
    void print(); 
} 

và lớp SimpleDoc của bạn sẽ trông như thế này:

public class SimpleDoc implements Doc { 

    public void clear() { ... } 

    @Override 
    public void print() { ... } 

} 

... thì bạn chỉ có thể truy cập print() -method của bạn mydoc -object. Nhưng bạn cũng có thể nói:

SimpleDoc mydoc = new SimpleDoc(); 

...và sau đó bạn cũng có thể gọi clear()

Các vấn đề liên quan