2010-08-03 35 views
10

1) Tại sao trong các tệp có trong gói Java, tôi viết "điều" gói trong nó ?, nó không gián tiếp giả định rằng nếu nó nằm trong thư mục, thì nó nằm trong gói ?.Tại sao từ khóa "gói" và .h?

2) Tôi đến từ thế giới C++. Tôi luôn nhập khẩu .h của các lớp mà tôi cần từ các tệp khác sử dụng lớp đó (ý tôi là, tôi chỉ muốn "hiển thị" tiêu đề, chứ không phải là triển khai). Nhưng bây giờ tôi là một chút nhầm lẫn về việc nhập khẩu trong Java. Làm thế nào điều này được thực hiện trong Java?

Cảm ơn

Trả lời

7
  1. không, đó không phải là giả định. Xét cho cùng, gói của tôi gọi com.mypackage.stuff? là gì? s rc.com.mypackage.stuff? myproject.com.mypackage.stuff? C.Users.makakko.workspace.myproject.src.com.mypackage.stuff?

    Nếu bạn chỉ căn cứ vào gói của các thư mục, nó có liên quan đến gốc ổ đĩa không? Điều gì xảy ra nếu dự án được phát triển trên một ký tự ổ đĩa khác trên một máy khác? Có liên quan đến vị trí của javac.exe không? Một lần nữa, những thư mục cài đặt khác nhau thì sao? Còn thư mục làm việc khi chạy javac thì sao? Nhưng bạn có thể chỉ định một vị trí cho javac để tìm các tệp nguồn của bạn. Nếu bạn muốn làm một chương trình thử nghiệm đơn giản, hoặc dạy một người Java chưa từng lập trình trước đó; bạn có phải sử dụng/giải thích toàn bộ khái niệm về cấu trúc gói?

    Nếu bạn bỏ qua thông số package, thì bạn vẫn đang ở trong gói. Nó chỉ là "gói mặc định", không có tên.

  2. Tệp tiêu đề có nhiều phần tạo tác từ cách C cần được biên dịch hơn là cách để ẩn thông tin. Trong C, một phương thức phải được xác định trước khi nó có thể được tham chiếu. Nếu bạn muốn có một số phương pháp liên quan đến một phương pháp khác, bạn phải định nghĩa tất cả các phương thức đó trước khi sử dụng bất kỳ phương thức nào trong số chúng, do đó có tiêu đề. Các tiêu đề trong C++ mang lại từ đó, nhưng thay đổi trong C++ thay đổi sự cần thiết của các tiêu đề.

    Trong Java, trình biên dịch sẽ xem xét tất cả các phương thức và chữ ký lớp học của bạn trước khi thực hiện bất kỳ thứ gì yêu cầu phương thức/lớp. Chức năng được phục vụ bởi các tiêu đề được đưa vào trình biên dịch.Bạn không thể phụ thuộc vào các tiêu đề cho ẩn thông tin của bạn, bởi vì

    1. Mã có thể được đặt trong một tập tin header

    2. Trừ khi bạn sử dụng thông tin thật ẩn như một thư viện riêng biệt, một lập trình viên có thể đi tìm tệp c/cpp khớp với tiêu đề không có vấn đề

    Tương tự trong Java, bạn chỉ có thể ẩn thông tin thực bằng cách xóa nguồn. Khi bạn đã tạo nguồn không thể truy cập được, bạn sẽ hiển thị API với các lớp, các enums và các giao diện công cộng/được bảo vệ. Đối với điểm thưởng, hãy viết chú giải JavaDoc giải thích cho mọi thứ và chạy javadoc.exe trên nguồn của bạn để tạo tài liệu riêng cho bất kỳ ai sẽ sử dụng (các) gói của bạn.

+0

AFAIK tên gói luôn luôn thừa. Chỉ cần cố gắng thay đổi 'com.mypackage.stuff' thành * mọi thứ * khác và làm cho nó được biên dịch mà không thay đổi' CLASSPATH'. – maaartinus

5

1) Tuyên bố package phải khớp với hệ thống phân cấp thư mục trên dự án.

Nếu tôi sử dụng package com.stackoverflow.bakkal; trong Car.java thì phân cấp sau được mong đợi.

com/ 
|-- stackoverflow/ 
| `-- bakkal/ 
|  |-- Car.java 

2) Nếu bạn muốn ẩn một thực hiện, bạn có thể sử dụng interface trong Java thay vì một class. Sau đó phân phối các triển khai thực tế trong các tệp .class hoặc các tệp JAR.

Mmm nhưng một giao diện không thể instantiated ...

Giao diện hoạt động như một nguyên mẫu trong C++ chừng mực nào đó. Bạn có hợp đồng, sau đó thực hiện thực tế đến từ nơi khác.

Tôi muốn thuyết minh một lớp, nhưng mà không đưa việc thực hiện, chỉ nguyên mẫu

Đó là không thể thậm chí C++, làm thế nào bạn có thể nhanh chóng một cái gì đó mà không cần phải thực hiện thực tế của nó? Trong C++ bạn vẫn cần phải liên kết đến các tệp đối tượng. Trong Java, bạn sử dụng các tệp .class.

+1

1) Câu hỏi của tôi là lý do tại sao nó không được giả định? : S 2) Mmm nhưng một giao diện không thể được instanciated ... Tôi muốn instanciate một lớp học, nhưng không đưa ra việc thực hiện, chỉ có nguyên mẫu. – makakko

+0

@makakko: Miễn là tệp .java có sẵn, việc triển khai sẽ luôn sẵn có. Giai đoạn. Nếu bạn muốn ẩn việc triển khai, chỉ cần cung cấp cho người dùng/lập trình viên/chỉ các tệp .class (hoặc .jar chứa .class). Hãy chắc chắn rằng bạn bao gồm tài liệu, mặc dù. –

+0

Cảm ơn Brian, tôi hiểu rồi. :). BTW, các .class có thể được đảo ngược trong một cách "đẹp" ?, Tôi có nghĩa là, khôi phục lại "tên" biến/chức năng ban đầu? Bởi vì tôi đoán rằng máy ảo Java không xử lý "offsets" cho các thành viên lớp hoặc chức năng ... – makakko

3

Các gói không được giả định vì triết lý của Java là tốt hơn là rõ ràng hơn là ngầm định/giả định.

Tính năng này cung cấp cho bạn khả năng truy cập mọi thứ trong gói hiện tại của bạn, nhưng mọi thứ bên ngoài cần phải được nhập một cách rõ ràng. (Tôi tin rằng Java.lang là ngoại lệ vì có chứa rất nhiều chức năng cơ sở như String sẽ không có một gói duy nhất không sử dụng nó).

Đây cũng là lý do tại sao bạn có xu hướng xem:

import java.util.ArrayList; 
import java.util.LinkedList; 

thay vì:

import java.util.*; 

này có thể dường như gây phiền nhiễu cho đến khi một ngày bạn đang cố gắng tìm ra mã elses ai đó và nó chạm bạn sẽ khó khăn hơn thế nào nếu mọi thứ bị ẩn/ngụ ý.

Nếu bạn sử dụng Eclipse, Netbeans hoặc IntelliJ, bạn thậm chí sẽ không bao giờ nhận thấy vì hai tính năng.

Trước hết, nếu bạn nhấn ctrl-space ở giữa việc gõ tên lớp, nó sẽ không chỉ hoàn thành tên lớp cho bạn mà còn tự động thêm nó vào danh sách nhập.Thứ hai, nếu bạn đã từng đến nơi nhập khẩu là "Sai" hoặc bạn không sử dụng mở rộng không gian ctrl, bạn có thể chỉ cần gõ ctrl-shift-o (nhật thực) để có nó "Sửa nhập khẩu". Thao tác này sẽ tự động nhập những thứ cần nhập và xóa các mục nhập bạn không còn cần nữa. Tùy thuộc vào cài đặt của bạn, nó cũng sẽ mở rộng hoặc thu gọn *.

Một khi bạn có được một hệ thống xuống bạn thậm chí không bao giờ xem xét nhập khẩu.

1

Gói chỉ định đường dẫn đến lớp. Nó phải khớp với thư mục trên đĩa hoặc trong bình (zip). Vị trí có liên quan đến một vị trí trên đường dẫn lớp. Quyền truy cập được bảo vệ bị hạn chế đối với các lớp trong cùng một gói.

Một số điều bạn có thể làm trong tệp .h được thực hiện trong định nghĩa lớp. Các hằng số thuộc về một lớp và có thể hiển thị công khai. Trong một .h các hằng số phải được hiển thị công khai.

Nhập tương đương với bao gồm a .h, nhưng giúp giải quyết các vấn đề về định nghĩa xung đột cùng tên. Bạn chỉ có thể bao gồm một mục hoặc tất cả các mục hiển thị từ một lớp. Nó cũng có thể bỏ qua việc nhập khẩu và sử dụng tên gói để tiền tố lớp bạn đang truy cập một cái gì đó từ đó.

Việc triển khai thực sự không thực sự nhìn thấy được thông qua một lần nhập (ít nhất là không vượt quá điều đó được cung cấp bởi lớp được biên dịch. Có thể thấy được là các phương thức và dữ liệu công khai của giao diện hiển thị. Các phương thức và các biến được bảo vệ được hiển thị cho các lớp con của lớp .h Các tệp .h có thể sử dụng được mà không cung cấp tệp nguồn hoặc đối tượng. chỉ gồm các hằng số, mặc dù điều đó sẽ được thiết kế kém.)

+0

quyền truy cập 'được bảo vệ' có nghĩa là các lớp con, không phải cùng một gói. Truy cập gói (cũng "truy cập mặc định") được chỉ định bằng cách bỏ qua bất kỳ từ khóa truy cập nào (công khai/được bảo vệ/riêng tư). –

+0

Câu trả lời đã được sửa chữa. – BillThor

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