JAVA'da kalıtımı neden dikkatli kullanmalısınız?

Bu makalenin teması, mirasın kullanımını teşvik etmek değil, yalnızca mirasın kullanımından kaynaklanan sorunlardan, miras mekanizmasının iyi olmayan kısımlarını tartışmak, böylece olası tuzaklardan kaçınmak için kullanırken dikkatlice seçim yapmaktır.

JAVA'da kalıtım kullanıldığında kaçınılmaz iki eksiklik vardır:

  • Kapsüllemeyi bozan alt sınıf, süper sınıfın uygulama ayrıntılarına bağlıdır ve üst sınıfla birleştirilir.
  • Süper sınıf güncellemesi hatalara neden olabilir.
  • Kalıtım kapsüllemeyi bozar

    Bu noktada, aşağıdaki ayrıntılı bir örnek (Etkili Java Makalesi 16'dan)

    genel sınıf MyHashSet < E > HashSet'i genişletir < E > { private int addCount = 0; public int getAddCount () { addCount döndür; } @Override public boolean add (E e) { addCount ++; return super.add (e); } @Override public boolean addAll (Koleksiyon < ? E uzatır > c) { addCount + = c.size (); super.addAll (c) döndür; } }

    Bir HashSet burada özelleştirilir ve iki yöntem yeniden yazılır.Bununla süper sınıf arasındaki tek fark, kaç öğenin eklendiğini saymak için bir sayaç eklemesidir.

    Bu yeni özelliğin çalışıp çalışmadığını test etmek için bir test yazın:

    public class MyHashSetTest { özel MyHashSet < Tamsayı > myHashSet = yeni MyHashSet < Tamsayı > (); @Ölçek public void testi () { myHashSet.addAll (Arrays.asList (1,2,3)); System.out.println (myHashSet.getAddCount ()); } }

    Çalıştırdıktan sonra, 3 eleman ekledikten sonra sayacın çıkış değerinin 6 olduğunu göreceksiniz.

    Üst sınıfa addAll () yöntemini girin ve hatanın nedenini bulacaksınız: dahili olarak add () yöntemini çağırır. Dolayısıyla bu testte, alt sınıfın addAll () yöntemine girilirken, sayaç 3 artırılır ve ardından üst sınıfın addAll () öğesi çağrılır. Üst sınıfın addAll () öğesi, alt sınıfın add () öğesini üç kez ve ardından sayacı çağırır Üç tane daha eklenecek.

    Sorunun kökü

    Bu durumu özetleyerek, hatanın üst sınıfın geçersiz kılınabilen yöntemlerinin varlığından kaynaklandığını görebilirsiniz. Kendi kendine kullanım (Yani, süper sınıftaki geçersiz kılınabilen yöntem diğer geçersiz kılınabilen yöntemleri çağırır.) Şu anda, alt sınıf bu yöntemlerden bazılarının üzerine yazarsa, hatalara neden olabilir.

    Örneğin, yukarıdaki resimde, Baba sınıfında geçersiz kılınabilen A ve B yöntemleri vardır ve A, B'yi çağırır. Son alt sınıfı, B yöntemini yeniden yazar. Şu anda, alt sınıf miras alınan A yöntemini çağırırsa, A yöntemi artık Father.B () öğesini değil, alt sınıfta Son.B () yöntemini çağıracaktır. Programın doğruluğu Father.B () 'deki bazı işlemlere bağlıysa ve Son.B () bu işlemleri yeniden yazarsa, hatalara neden olma olasılığı yüksektir.

    Kilit nokta, alt sınıfın yazılmasının yüzeyde bir sorun gibi görünmeyebileceğidir, ancak bu, geliştiricileri süper sınıfın uygulama ayrıntılarını anlamaya zorlar, böylece nesneye yönelik kapsüllemeyi bozar, çünkü kapsülleme gizleme gerektirir. Uygulama ayrıntıları. Daha tehlikeli olan ise, hataların kolayca tespit edilememesidir.Geliştirici, üst sınıfın uygulama ayrıntılarını anlamaz ve onu yeniden yazarsa, gizli tehlikeler ekilebilir.

    Süper sınıf güncellendiğinde bir hata meydana gelebilir

    Bunu anlamak daha kolaydır ve esas olarak aşağıdaki olasılıklar vardır:

    • Üst sınıf, mevcut bir yöntemin imzasını değiştirdi. Derleme hatalarına neden olur.
    • Süper sınıfın yeni yöntemleri vardır:
    • Alt sınıfın mevcut yönteminin imzası aynıdır ancak dönüş türü farklıdır ve bu bir derleme hatasına neden olur.
    • Alt sınıfın mevcut yöntem imzasıyla aynı şey, alt sınıfın istemeden üzerine yazmasına ve ilk duruma geri dönmesine neden olur.
    • Alt sınıfla herhangi bir çakışma yoktur, ancak programın doğruluğunu etkileyebilir. Örneğin, alt sınıftaki öğeler, koleksiyona eklenecek belirli koşulları karşılamalıdır.Şu anda, üst sınıf, öğeleri algılama olmaksızın doğrudan ekleyebilen bir yöntem eklerse, programın doğruluğu tehdit edilir.

    Devralınabilir sınıflar tasarlayın

    Miras alınabilecek sınıfları tasarlarken şunlara dikkat etmelisiniz:

    • Kendi kendine kullanılabilen geçersiz kılınabilir yöntemler için, arama ayrıntılarını doğru bir şekilde tanımlamak için dokümantasyon kullanılmalıdır.
    • Korunan üyeleri olabildiğince az açığa çıkarın, aksi takdirde çok fazla uygulama detayı açığa çıkacaktır.
    • Yapıcı, geçersiz kılınabilen yöntemleri çağırmamalıdır.

    Üçüncü noktayı ayrıntılı olarak açıklayın. Aslında Devralma Sonları Kapsülleme'de tartışılan konuya çok benzer. Şu kodu varsayalım:

    public class Father { genel Baba () { someMethod (); } public void someMethod () { } } public class Oğlu, Baba'yı genişletir { özel Tarih tarihi; genel Oğlu () { this.date = new Date (); } @Override public void someMethod () { System.out.println ("Time =" + date.getTime ()); } }

    Yukarıdaki kod, testi çalıştırırken bir NullPointerException oluşturacaktır:

    public class SonTest { özel Oğul oğul = yeni Oğul (); @Ölçek public void testi () { son.someMethod (); } }

    Üst sınıfın kurucusu alt sınıfın yapıcısından önce çalışacağından, burada üst sınıfın kurucusu someMethod () 'a bağlıdır ve someMethod () geçersiz kılınır, bu nedenle üst sınıfın yapıcısına yapılan çağrı Son.someMethod () ve alt sınıf şu anda başlatılmamıştır, bu nedenle date.getTime () tarihine kadar çalıştığında boş bir işaretçi istisnası atılır.

    Bu nedenle, üst sınıfın yapıcısında geçersiz kılınabilen yönteme bağımlılık varsa, devralma sırasında hatalar oluşabilir.

    sonuç olarak

    Kalıtımın birçok avantajı vardır, ancak kalıtımı kullanırken dikkatli olmalı ve bunu dikkate almalısınız. Ayrıca kodun yeniden kullanımını sağlamak için kullanılır karmaşık , Miras ve kompozisyon kullanıyorsanız (Bu öncüldür) , Daha sonra kompozisyon ilk olarak kullanılmalıdır, çünkü kompozisyon üst sınıfın uygulama detaylarını korumasını sağlayabilir ve yukarıdaki kalıtım eksiklikleri kompozisyon ile önlenebilir. Bu aynı zamanda Kompozisyon, kalıtıma göre önceliklidir .

    Miras kullanıyorsanız, üst sınıfta kendi kendine kullanılabilen geçersiz kılınabilen yöntemleri yeniden yazmanın hatalara neden olabileceğinin farkında olmalısınız.Yeniden yazmasanız bile, üst sınıf güncellendiğinde hatalar ortaya çıkabilir. Aynı zamanda, üst sınıf, birbiri olarak adlandırılabilecek geçersiz kılınabilen yöntemler için ayrıntılı belgeler sağlamak üzere dikkatlice tasarlanmalıdır.

    Temettüler tükendi, oyun bölündü ve canlı yayın yanıtları orta saha savaşına giriyor
    önceki
    Klasik Amerikan draması "The Charmed" yeniden başlıyor! Üç cadı kahramanı seçildi
    Sonraki
    Bıçak çemberinde iki veya üç şey var: B Tanrı isteksizce çay takımının 4 maçlık mağlubiyet serisini açıklıyor, RNG Rise of Foreign War Lien Chan VP Liquid
    190316 Wang Junkai bugün işe gidiyor Reuters Canlandırıcı, ferahlatıcı, güneşli çocuk işe başladı
    "Summer of Bubbles" ın finali: Ou Chen, yere düşen Xia Mo'dan ayrılır ve onu Luo Xi'ye emanet eder.
    34 elektrik kontrol bağlantı şemaları, elektronik bileşenlerin çalışma prensibi şemaları
    Pandora Pandora, aşkla çiçek açan ilk Çin dizisi "Man Man Peach Blossom" u başlattı.
    LOL: Griffin Gen.G ile tekrar savaşacak, geçen yıl köpüren maçın intikamını alma zamanı geldi
    "GOT7" "Paylaşım" 190316 Yeongdeungpo İmza Toplantısı Yemek Çekimi Önizlemesi JUS2 Grubu Kendine Meydan Okuyan İşe Çıktı
    "Love Apartment" promosyon şarkısı MV çevrimiçi, netizenler: Bitmemiş randevunuza gitmek için on yıl gençlik harcıyorum
    Amerikan dizisi Göreceli Evren de başka bir siz varsa, onunla hayat değiş tokuşu yapmak ister misiniz?
    OPPO, Find X'i elinde tutuyor, geleceğin kapısını çalıyor
    terör! Elektrik dağıtım odasındaki üç kişi patladı ve anında pisliğe dönüştü 8 gizli tehlikeyi kontrol ettiniz mi?
    DOTA2 aksesuarlarının takdiri: bu çapa oyuncularının en iyi aksesuarları
    To Top