Bir sınıf alt sınıflarını bilmeli mi?


24

Bir sınıf alt sınıflarını bilmeli mi? Bir sınıf, örneğin belirli bir alt sınıf için özel olan bir şey yapmalı mı?

İçgüdülerim bana bunun kötü bir tasarım olduğunu, bir çeşit anti-patern gibi göründüğünü söylüyor.


6
Genellikle hayır, ama özel durumlarda faydalıdır.
KodlarInChaos

O ise "Liskov değiştirme Prensibi" veya bazen sadece LSP, bu konuda okuyun: Bir anti-desen olarak adlandırılan iyi bilinen bir en.wikipedia.org/wiki/Liskov_substitution_principle
Jimmy Hoffa

5
@JimmyHoffa - "Liskov Değiştirme Prensibi", bir anti-paternin adı değildir. Anti-patern LSP'yi ihlal edebilir, ancak bunun burada geçerli olacağı bile kesin değil. Bir tip alt tiplerini bilse bile, alt tiplerin ebeveynleri için kontrarians ve kovaryans ile ikame edilebilmesi mümkündür.
Matthew Flynn

4
@MatthewFlynn Belki LSP’yi biraz gevşek kullanıyorum, ama benim tanımımda, hepsinin LSP’ye uygun olan birbirlerini yerine getirmeleri gerçeği değil, sadece birbirleriyle aynı fikirde olacakları gibi bir ayrıştırmaya sahip olmaları da bir gerekliliktir. LSP'yi ihlal etmeyen başka bir alt sınıf uygulayabilirsiniz. Eğer hiyerarşi kendi kendini algılıyorsa, harici bir uygulama temel sınıfı değiştirmeden LSP ile görüşemez. Belki de bu kesinlikle LSP değil ama çok yakın. ve evet LSP ihlali anti-patern olduğunu söylemeliydim
Jimmy Hoffa

2
Bununla karşılaştığım birkaç kez, bu bilgiyi bir alt sınıfta geçersiz kılınabilecek bir yöntem haline getirdim (ya soyut ya da saf sanal hale getirerek ya da geçersiz kılınabilecek makul bir varsayılan uygulama sağlayarak).

Yanıtlar:


32

Sınıf kavramının ima ettiği cevap "hayır" dır.

Hangi eylem, veri veya ilişki ne olursa olsun, tüm alt sınıfların bir parçasıdır - daha sonra gerçek tip kontrol edilmeden üst sınıfta ele alınmalıdır. Ya da sadece bazı alt sınıflar için geçerlidir - o zaman doğru olanı yapmak için çalışma zamanı tipi kontroller yapmanız gerekirdi, başka biri ondan bir şey miras aldığında üst sınıfın değiştirilmesi gerekirdi (ya da sessizce yanlış olanı yapabilirdi), türetilmiş sınıflardaki değişiklikler, değişmemiş üst sınıfları vs. bozabilir.

Kısacası, bu tür çözümleri elden reddetmek için genellikle yeterince kötü olan bir dizi kötü sonuç elde edersiniz. Alt sınıflarınızın birçoğu aynı şeyi yaparsa ve kod çoğaltmasından kaçınmak istiyorsanız (pratikte her zaman iyi bir şey), daha iyi bir çözüm, tüm bu alt sınıfların kodu devralabildiği orta düzey bir sınıfı tanıtmaktır.


4
Bu kuralın bir istisnası: Sınıfın dokümantasyonu yerel alt sınıflarını kendi kütüphanesinde listelemelidir.
Kieveli

3
@Kieveli ... bu belgeler güncel olduğu sürece.
mouviciel

14
Kullanılabilir herhangi bir dokümantasyon aracı miras ağaçları çekebilmelidir ...
johannes

13
Bunun bir istisna olduğunu sanmıyorum. Sınıf hala hiçbir şey bilmiyor. Belgeler bilir.
Honza Brabec

4
@ Kieveli uhh tamamen katılmıyorum.
Jimmy Hoffa

16

Sadece gerektiğini bilemez, sadece yapamam ! Genellikle, bir sınıf her zaman, her yerde genişletilebilir. Yazıldığı zaman bile mevcut olmayan sınıflar tarafından genişletilebilir .

Bazı diller, genişletme sınıflarının üst sınıf tarafından kontrol edilmesine izin verir. Scala'da, bir sınıf olarak işaretlenebilir sealed; bu, yalnızca aynı derleme birimindeki (kaynak dosya) diğer sınıflar tarafından genişletilebileceği anlamına gelir. Bununla birlikte, bu alt sınıflar da olmadıkça sealedveya finalalt sınıflar daha sonra başka sınıflar tarafından da genişletilebilir.

Scala'da, kapalı cebirsel veri tiplerini modellemek için kullanılır, yani kanonik Haskell Listtipi:

data List a = Nil | Cons a (List a)

Scala'da şöyle modellenebilir:

sealed trait List[+A]

case object Nil extends List[Nothing]

final case class Cons[+A] extends List[A]

Ve bunu garanti edemez sadece çünkü o ikinin alt "sınıflar" var Listolduğunu sealedve bu nedenle dosyanın genişletilmiş dışında olamaz, Consolduğu finalve bu nedenle hiç uzatılamaz ve Nilbir olduğunu objectzaten uzatılamaz hangi.

Fakat bu özel bir kullanım durumudur (kalıtım yoluyla cebirsel veri türlerini modelleme) ve bu durumda bile, üst sınıf aslında alt sınıflarını bilmiyor. Daha bir garanti var kullanıcı ait Listtip olduğunu o vakası ayrımcılık yaparsa NilveCons arkasından çıkan başka bir alternatif olmayacağının .


Birçok dilde işe yarayan, bir çeşit abstract internalüye ekliyor .
KodlarInChaos

4

Basit cevap Hayır.

Kodu kırılganlaştırır ve nesne temelli programlamanın iki temel ilkesini harekete geçirir.

  • Liskov Değişim ilkesi
  • Açık Kapat prensibi

1

Evet bazen. Örneğin, sınırlı sayıda alt sınıf olduğunda. bir ziyaretçi kalıbı , bu yaklaşımın kullanışlılığının bir gösterimidir.

Örnek: Bazı iyi tanımlanmış gramerlerin soyut bir sözdizimi ağacı (AST) düğümlerinin Nodetümü, tüm düğüm tiplerini idare etmek için bir ziyaretçi kalıbı uygulayan tek bir sınıftan miras edilebilir .


9
Hayır, hayır ve hayır. Bu kullanışlı değildir ve asla iyi bir çözüm değildir.
Sulthan

@Çok sınıf dışında AST'lerle çalıştım ve Lorus'un soruyu tam olarak anlamadığını düşünüyorum. Ziyaretçi, AST üzerindeki bir düğüm tipi değildir, ayrı bir nesnedir. Dilbilgisi nesneleri hakkında bilgi sahibi olabilir ve bilmelidir. Ancak, yüksek seviyeli bir AST düğümü olmamalıdır.

1
@JohnGaughan "Bilir" terimi kafamı karıştırıyor. NodeTabii ki, temel sınıf, alt sınıflarına doğrudan referans içermez. Ancak parametresi acceptolan bir yöntem içerir Visitor. Ve her bir alt sınıf için Visitorbir visityöntem içerir . Dolayısıyla, Nodealt sınıflarına doğrudan atıfta bulunmamasına rağmen , onlar hakkında dolaylı olarak Visitorarayüz üzerinden "bilir" . Hepsi onunla birlikte birleştiler.
lorus

1
@Sulthan Asla asla deme. Seçenek tipi, üst sınıfın soyundan gelenleri bildiği durumlarda geçerli bir örnektir. Ancak Jorg'un dediği gibi mühürlü olarak işaretlenecekti.
Pavel Voronin

Öyleyse hemfikirsiniz: bir ziyaretçinin ne ziyaret ettiğini bilmesi gerekir.

1

Bir firma için bir bileşen yazarsam ve daha sonra, ayrıldıktan sonra, birisi kendi amaçları için genişletir, bu konuda bilgilendirilmeli miyim?

Yok hayır!

Sınıfları ile aynı. İçgüdülerine güven.


İş güvenliği???
altmış ayak basanları

Altmış ayağın yüksek, bu yüzden seninle tartışmayacağım :-) Ancak, umarım anlamım gittikten sonra başka bir iş buldum.
Daniel Hollinrake
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.