2011-07-14 44 views
12

Khi bạn ghi đè phương thức, bạn phải giữ chữ ký của phương thức và không thể giảm khả năng hiển thị của phương thức đó. Bây giờ tôi đã thử những gì vui vẻ khi tôi làm điều này với các thuộc tính. Tôi đã rất ngạc nhiên - IT WORKS! Nhìn bản thân:Ghi đè các thuộc tính

public class A { 

    public Integer myAttribute; 

} 

public class B extends A { 

    public String myAttribute; 

} 

public class Main { 

     public static void main(String[] args) { 
     B b = new B(); 
     b.myAttribute = "myString"; 
     ((A) b).myAttribute = 1337; 
     System.out.println(b.myAttribute); 
     System.out.println(((A)b).myAttribute); 
    } 

} 

Vì vậy, chúng ta có thể viết một thuộc tính trong một lớp con với tên attibute giống như trong lớp cha, nhưng bạn có thể sử dụng tầm nhìn khác nhau (sửa đổi) và loại. Vì vậy, tôi sẽ nói rằng các thuộc tính trong superclass và subclass gần như hoàn toàn độc lập với nhau.

Bây giờ nếu bạn thực sự sử dụng cùng một tên thuộc tính trong lớp cha và lớp con, bạn ẩn thuộc tính của lớp cha một cách hiệu quả. Khi truy cập thuộc tính bằng cách sử dụng lớp con, bạn sẽ nhận được thuộc tính của lớp con. Nhưng thuộc tính của siêu lớp cũng ở đó! Bạn phải thực hiện một diễn viên để truy cập thuộc tính của lớp cha từ bên ngoài. Từ bên trong từ khóa "siêu" phải hữu ích.

Câu hỏi 1: Về cơ bản, bạn có hai thuộc tính khác nhau có cùng tên. Điều này không vi phạm LSP?

Tại sao tôi đến chi tiết này là: Tôi đang thử nghiệm với một khuôn khổ bền vững tự viết. Tôi muốn đọc toàn bộ trạng thái bên trong của một đối tượng và duy trì trạng thái đó. Tôi đọc tất cả các giá trị của thuộc tính thông qua phản xạ, bắt đầu từ loại con và di chuyển qua các siêu lớp. Bây giờ nếu có hai thuộc tính có cùng tên trong lớp cha và lớp con, tôi phải nhớ lớp khai báo thuộc tính để có thể ánh xạ các giá trị thuộc tính tới đúng thuộc tính và khôi phục trạng thái của đối tượng.

Câu hỏi 2: Bất kỳ ý tưởng nào khác về cách giải quyết chi tiết này? Câu hỏi 3: Các khung công tác bền vững khác xử lý chi tiết này như thế nào?

Tôi chưa bao giờ thấy chi tiết này đang được sử dụng. Có thể viết hai thuộc tính có cùng tên là một chút xấu xí, nhưng có thể và bất kỳ khung kiên trì nào cũng có thể phải đối mặt với nó. Có thể có những tình huống mà kỹ thuật này có thể hữu ích.

Tạm dừng trước.

+0

Thx cho tất cả người trả lời. – anonymous

Trả lời

5

ORM thường sử dụng tiêu chuẩn javabeans xác định "thuộc tính". Các thuộc tính được định nghĩa bởi một đầu đọc và/hoặc phương thức ghi thay vì trường mà chúng đọc/ghi. Trong 99% các trường hợp thuộc tính là trường + getter & setter, nhưng nó không phải là trường hợp. Và ORM đọc các thuộc tính này, và chỉ phát hiện các trường có getters & setters. Vì các phương thức được ghi đè thay vì bị che khuất nên vấn đề đã biến mất.

Đây là vấn đề về đóng gói nhiều hơn là vi phạm LSP. Truy cập trường không bị ảnh hưởng bởi đa hình, vì vậy nếu bạn có Foo foo = new FooSubclas(); foo.field the value of the Trường Foo` sẽ được thực hiện, có nghĩa là hành vi sẽ không thay đổi.

+0

Tôi không muốn bị ràng buộc với đặc điểm kỹ thuật của đậu vì những hạn chế của nó. Đó là một trong những lý do tại sao tôi quyết định thử một khung kiên trì của riêng mình. Bây giờ tôi phải đối mặt với một số vấn đề mà các triển khai khác tránh được bằng cách duy trì đậu. Tôi nghĩ rằng tôi chỉ cần mở rộng mô hình meta của mình để đại diện cho thừa kế chính xác hơn. – anonymous

2

Câu hỏi 1: Nó không phá vỡ LSP, vì các biến thành viên không đa hình.

1

Câu hỏi 1: LSP là khoảng behavioral subtyping và tôi muốn nói có hai thành viên có cùng tên không thay đổi hành vi.

Câu hỏi 2: Phát hiện nó (bạn cần phải quét phân cấp lớp dù sao) và không cho phép.

1

Câu hỏi 2: Chỉ tuần tự hóa/deserialize thông qua getters/setters.

Câu hỏi 3: Xem câu trả lời 2.

1

Bạn không thể ghi đè thuộc tính, chỉ ẩn thuộc tính. Đây được gọi là các trường ẩn trong số tutorial. Thêm chi tiết về điều này blog.

Q1: Không, nó không phá vỡ LSP, bất kỳ tham chiếu nào đến A a = new B(); a.myAttribute vẫn sẽ tham chiếu đến A.myAttribute và không được B.myAttribute.

Q2: Tôi sẽ cố gắng tránh điều đó, nhưng nếu bạn phải, bạn vẫn có thể truy cập A.myAttribute từ B bằng cách sử dụng từ khóa super.myAttribute. Q3: Tôi nghĩ C# cho phép giống nhau, họ sử dụng base thay vì super, nhưng tôi không có trình biên dịch C# nào trong tầm tay, và tài liệu về ẩn trường trong C# là thưa thớt.

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