2011-12-21 13 views
5

phép nói rằng chúng tôi có điều này các lớp học thực sự tầm thường:Liskov thay nguyên tắc - phương pháp trọng dụ

class A 
{ 
    virtual int Function(int number) 
    { 
     return number; 
    } 
} 

class B : A 
{ 
    override int Function(int number) 
    { 
     return number + 1; 
    } 
} 

class UseExample 
{ 
    void Foo(A obj) 
    { 
     A.Function(1); 
    } 
} 

Sẽ là ví dụ này vi phạm các LSP ?. Nếu vậy, bạn có thể cho tôi một ví dụ không phá vỡ nguyên tắc và sử dụng một triển khai khác không?

gì về điều này một:

class B : A 
{ 
    int variable; 

    override int Function(int number) 
    { 
     return number + variable; 
    } 
} 

Theo như tôi hiểu việc sử dụng các biến "biến" gây ra một điều kiện tiên quyết mạnh mẽ hơn và do đó nó vi phạm các LSP. Nhưng tôi không hoàn toàn chắc chắn làm thế nào để làm theo LSP khi sử dụng Đa hình.

+1

chức năng của bạn không có hợp đồng trong đó đặt tên hoặc triển vọng nào, việc thực hiện trả về một giá trị tùy ý do đó hoàn toàn có thể chấp nhận được. Bạn sẽ nhận được trong một vùng màu xám tuy nhiên nếu bạn chỉ định một hợp đồng trong tên của hàm, như: int Add1ToArgument (int argument) {...} – Polity

+0

Chính trị, ngụ ý ngữ nghĩa từ đặt tên phương thức không thực sự đi vào nó. Đó là từ định nghĩa kiểu. –

+0

Nếu ngữ nghĩa không liên quan gì đến nguyên tắc, bạn có thể giải thích cho tôi ví dụ về hình chữ nhật/hình vuông không ?. Thị trưởng phàn nàn về điều này mà tôi đã tìm thấy cho đến nay là nếu bạn sử dụng một hình chữ nhật obj = new Square() và gán chiều cao một chiều rộng mà không có kiến ​​thức trước đó rằng đối tượng là một Square, bạn sẽ nhận được một kết quả bất ngờ của hàm getArea() chỉ vì bạn nghĩ rằng một hình chữ nhật có 2 giá trị khác nhau cho Chiều cao và Chiều rộng. Cảm ơn trước – BizTuk

Trả lời

2

Đó là hợp lệ, trong cả hai trường hợp không phá vỡ nguyên tắc. B có thể được thay thế cho A. Nó chỉ có chức năng khác nhau.

một cách đơn giản để phá vỡ hợp đồng sẽ được ném một ngoại lệ trong Bs ghi đè nếu số == 23 hoặc một cái gì đó :)

+0

Trong ví dụ thứ hai, giả sử chúng ta gọi hàm A.Function (1) và biến "biến" không được khởi tạo. Trong trường hợp này, chúng tôi có lỗi thời gian chạy (nếu tôi không nhầm), do đó chúng tôi đã vi phạm LSP. Tôi tin rằng bạn không thể trao đổi B/A vì A không có định nghĩa cho "biến" – BizTuk

+0

một int được khởi tạo theo mặc định, nó không thể được khởi tạo (mặc dù không có ngôn ngữ được chỉ định ở đây, tôi giả sử C# ish). Bs xây dựng có thể hoàn toàn khác với xây dựng, miễn là nó có thể được sử dụng như một A một lần xây dựng. ngoại lệ là nhiều khả năng những điều có thể xảy ra mà khéo léo phá vỡ LSP. Nhưng nếu bạn giới thiệu ý tưởng rằng A. Chức năng có thể ném ngoại lệ, bạn bao gồm ass của bạn :) –

+0

Lỗi của tôi với khởi tạo int.Bạn có thể làm việc xung quanh ví dụ và sử dụng một đối tượng của một lớp C mà không có một hàm tạo mặc định và giữ một số ma thuật được sử dụng trong phương trình của phương thức B. Bằng cách đó bạn có thể mong đợi một ngoại lệ được ném bởi A.Function() (nên được obj.Function() thay vào đó, xấu của tôi). Cảm ơn bạn đã trả lời: P – BizTuk

0

Từ sự hiểu biết của tôi về nó, tôi sẽ nói rằng cả hai ví dụ của bạn vi phạm LSP như subclass không thể được thay thế bởi superclass của nó. Hãy xem xét những điều sau:

class UseExample { 
    void Foo(A& obj, int number) { 
     int retNumber = obj.Function(number); 
     assert(retNumber==number); 
    } 
} 

Nếu bạn chuyển một tham chiếu đến đối tượng B vào Foo, xác nhận sẽ không thành công. B.Function đang thay đổi poscondition của A.Function. Mã khách hàng Foo không cần phải biết về các kiểu con có thể phá vỡ mã của chúng.