Kalıtım hiyerarşisinde Liskov ikame ilkesi nasıl doğrulanır?


14

Bu yanıttan ilham alındı :

Liskov İkame İlkesi şunu gerektirir :

  • Bir alt tipte önkoşullar güçlendirilemez.
  • Alt koşullar bir alt türde zayıflatılamaz.
  • Süpertipin değişmezleri bir alt tipte korunmalıdır.
  • Geçmiş kısıtı ("geçmiş kuralı"). Nesneler yalnızca yöntemleri (kapsülleme) yoluyla değiştirilebilir olarak kabul edilir. Alt tipler, üst tipte bulunmayan yöntemler getirebileceğinden, bu yöntemlerin eklenmesi, alt tipte üst tipte izin verilmeyen durum değişikliklerine izin verebilir. Tarih kısıtı bunu yasaklar.

Birinin bu 4 noktayı ihlal eden bir sınıf hiyerarşisi yayınlayıp yayınlamayacağını ve bunları nasıl çözeceğini umuyordum.
Hiyerarşideki 4 noktanın her birini nasıl tanımlayacağınız ve düzeltmenin en iyi yolu hakkında eğitim amaçlı ayrıntılı bir açıklama arıyorum.

Not:
İnsanların üzerinde çalışması için bir kod örneği göndermeyi umuyordum, ancak sorunun kendisi hiyerarşilerin nasıl tanımlanacağıyla ilgili :)


Yanıtlar:


17

Bu alıntıyı ses çıkardığından çok daha basit, olduğu gibi doğru.

Bir miras hiyerarşisine baktığınızda, temel sınıfın bir nesnesini alan bir yöntem düşünün. Şimdi kendinize sorun, bu yöntemi düzenleyen birinin o sınıf için geçersiz olacağı varsayımları var mı?

Örneğin ( aslen Bob Amca'nın sitesinde görülür ):

public class Square : Rectangle
{
    public Square(double width) : base(width, width)
    {
    }

    public override double Width
    {
        set
        {
            base.Width = value;
            base.Height = value;
        }
        get
        {
            return base.Width;
        }
    }

    public override double Height
    {
        set
        {
            base.Width = value;
            base.Height = value;
        }
        get
        {
            return base.Height;
        }
    }
}

Yeterince adil görünüyor değil mi? Square adında, Genişliğin her zaman Yüksekliğe eşit olması gerektiğini savunan özel bir tür Dikdörtgen oluşturdum. Kare bir dikdörtgendir, bu yüzden OO ilkelerine uyar, değil mi?

Ama bekleyin, biri şimdi bu yöntemi yazarsa:

public void Enlarge(Rectangle rect, double factor)
{
    rect.Width *= factor;
    rect.Height *= factor;
}

Hiç hoş değil. Ancak bu yöntemin yazarının potansiyel bir sorun olabileceğini bilmesi için hiçbir neden yoktur.

Bir sınıfı diğerinden türettiğiniz her seferinde, temel sınıfı ve insanların bu konuda ne alabileceğini düşünün (örneğin, "bir Genişliği ve Yüksekliği vardır ve ikisi de bağımsız olacaktır"). O zaman "bu varsayımlar alt sınıfımda geçerliliğini koruyor mu?" Diye düşünün. Değilse, tasarımınızı yeniden düşünün.


Çok iyi ve ince bir örnek. +1. Yapabileceğiniz şey, Entange'ı Rectangle sınıfının bir yöntemini yapmak ve Square sınıfında geçersiz kılmaktır.
marco-fiset

@ marco-fiset: Kare ve Dikdörtgenin ayrıştırılmasını, yalnızca bir boyutta Kare olmasını, ancak her birinin IResizable uygulamasını tercih ederim. Bir Draw yöntemi varsa, onlar benzer olurdu, ancak daha sonra her ikisi de ortak kodu içeren bir RectangleDrawer sınıfı kapsüllemek istiyorum doğrudur.
pdr

1
Bunun iyi bir örnek olduğunu düşünmüyorum. Sorun şu ki, bir karenin genişliği veya yüksekliği yoktur. Sadece kenarlarının bir uzunluğu var. Genişlik ve yükseklik yalnızca okunabilir olsaydı sorun olmazdı, ancak bu durumda yazılabilirlerdi. Değiştirilebilir durum sunarken LSP'yi korumak her zaman çok daha zordur.
SpaceTrucker

@pdr Örnek için teşekkürler, ancak yazımda bahsettiğim 4 koşulla ilgili olarak Squaresınıfın hangi kısmı onları ihlal ediyor?
Songo

1
@Songo: Tarih Kısıtlaması. Burada daha iyi açıklanmıştır: blackwasp.co.uk/LSP.aspx "Doğası gereği, alt sınıflar, üst sınıflarının tüm yöntemlerini ve özelliklerini içerir. Ayrıca başka üyeler de ekleyebilirler. Geçmiş kısıtı, yeni veya değiştirilmiş üyelerin temel sınıf izin olmaz bir şekilde bir nesnenin durumunu temel sınıfı, bir sabit boyutta bir nesneyi temsil eden, eğer. Örneğin, alt modifiye edilmesi, bu boyut olanak sağlamaması gerekmektedir."
pdr
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.