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.
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.
Yanıtlar:
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.
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 sealed
veya final
alt 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 List
tipi:
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 List
olduğunu sealed
ve bu nedenle dosyanın genişletilmiş dışında olamaz, Cons
olduğu final
ve bu nedenle hiç uzatılamaz ve Nil
bir olduğunu object
zaten 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 List
tip olduğunu o vakası ayrımcılık yaparsa Nil
veCons
arkasından çıkan başka bir alternatif olmayacağının .
abstract internal
üye ekliyor .
Basit cevap Hayır.
Kodu kırılganlaştırır ve nesne temelli programlamanın iki temel ilkesini harekete geçirir.
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 Node
tümü, tüm düğüm tiplerini idare etmek için bir ziyaretçi kalıbı uygulayan tek bir sınıftan miras edilebilir .
Node
Tabii ki, temel sınıf, alt sınıflarına doğrudan referans içermez. Ancak parametresi accept
olan bir yöntem içerir Visitor
. Ve her bir alt sınıf için Visitor
bir visit
yöntem içerir . Dolayısıyla, Node
alt sınıflarına doğrudan atıfta bulunmamasına rağmen , onlar hakkında dolaylı olarak Visitor
arayüz üzerinden "bilir" . Hepsi onunla birlikte birleştiler.
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.