2015-08-10 25 views
5

Theo phần "8.1.1.1" của JLS ta có:thừa kế các phương pháp trừu tượng với truy cập gói

Một lớp C có phương pháp trừu tượng nếu một trong hai điều sau đây là đúng:

• Bất cứ các phương pháp thành viên (§8.2) của C - được tuyên bố hoặc thừa kế - là tóm tắt.

• Bất cứ superclasses C đã là một phương pháp trừu tượng khai báo với truy cập gói, và có tồn tại không có phương pháp đó sẽ ghi đè các phương pháp trừu tượng từ C hoặc từ một lớp cha của C

Thật là thú vị, tại sao chúng ta có tùy chọn thứ hai ở đây. Đặc biệt, tại sao chúng ta có chính xác "quyền truy cập gói". Còn phương pháp "công khai" hoặc "được bảo vệ" thì sao?

+0

Về cơ bản, lớp học của bạn trừu tượng cho đến khi bạn cung cấp các triển khai cụ thể cho tất cả các phương thức trừu tượng của mình (các phương thức rõ ràng trong lớp của bạn hoặc ẩn từ các lớp cha). Hãy nhớ rằng: "phạm vi gói" là khi bạn * không * chỉ định "công khai" hoặc "được bảo vệ" hoặc "riêng tư"; nó có thể nhìn thấy ở bất cứ nơi nào bên trong gói và không hiển thị bên ngoài gói. – paulsm4

Trả lời

3

Từ trật tự của hầu hết các cá nhân đối với hầu hết mở, bổ java đi:

  • tin
  • gói
  • bảo vệ
  • công

lớp Child không thể kế thừa phương pháp gói của một lớp cha trong một gói khác. Vì vậy, một lớp kế thừa từ một phụ huynh như vậy sẽ không trừu tượng theo quy tắc 1. Vì vậy, quy tắc thứ 2 tồn tại để giải quyết tình huống mà lớp con thừa kế từ một phụ huynh trừu tượng và không thể cung cấp một phương thức gói trừu tượng.

Đó là một tình huống vô nghĩa, và tôi sẽ không bao giờ mong đợi thấy điều này trong bất kỳ chương trình nào ở bất kỳ đâu. Nhưng ngôn ngữ phải được xác định đầy đủ hoặc bạn có thể kết thúc với một lỗi kỳ lạ cho phép một lớp học với các phương thức không xác định được khởi tạo.

0

Ý nghĩa có thể là protectedpublic cũng là các khai báo cung cấp quyền truy cập gói. private phương pháp không, và chúng cũng không thể trừu tượng.

0

Vâng, tôi nghĩ bạn đúng. Tùy chọn thứ hai chỉ liên quan đến một trường hợp cụ thể: phân lớp cụ thể nằm trong một gói khác với gói siêu lớp của nó.

Ví dụ,

package superpackage; 

public abstract class SuperFoo { 
    abstract void foo(); 
} 


package subpackage; 

import superpackage.SuperFoo; 

public abstract class SubFoo extends SuperFoo {} 

Xin lưu ý rằng lớp này cần được khai báo trừu tượng, nếu không chúng tôi có lỗi biên dịch.

Trong trường hợp cụ thể này, chúng tôi không có "kế thừa phương pháp foo" vì kế thừa yêu cầu lớp SubFoo nằm trong cùng gói với SuperFoo. xem phần 8.4.8 trong JLS để biết thêm chi tiết.

Tuy nhiên, lớp này vẫn chứa phương pháp "foo" (theo định nghĩa) và do đó nên được đánh dấu với từ khóa trừu tượng.

Hơn nữa, chúng ta có thể mở rộng lớp SubFoo của chúng tôi bằng một lớp bê tông thuộc về "superpackage" gói.

Ví dụ,

package subclass; 

import subpackage.SubFoo; 

public class SecondSubFoo extends SubFoo { 
    @Override 
    void foo() {} 
} 

Lưu ý:

1) Thực tế là phương pháp công cộng và bảo vệ rơi vào mục đầu tiên của định nghĩa khi chúng được kế thừa và không cần mục thứ hai của định nghĩa cho chúng.

2) Các phương thức truy cập gói cũng rơi vào mục đầu tiên của định nghĩa nếu chúng nằm trong cùng một gói và do đó không cần mục thứ hai của định nghĩa cho chúng nữa. Mặt khác, các phương thức truy cập gói nằm trong gói khác không rơi vào mục đầu tiên của định nghĩa vì chúng không được kế thừa (xem định nghĩa về thừa kế các phương thức trừu tượng trong phần 8.4.8 của JSL). và do đó chúng được yêu cầu mục thứ hai của định nghĩa.

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