Gerçekten şablon şablonunu kullanıyorsunuz. Bu can yansıma ile bu korumaların geçmiş yollarını zorbalık belirlenen hacker
Access Levels
Modifier | Class | Package | Subclass | World |
--------------------------------------------------
public | Y | Y | Y | Y |
protected | Y | Y | Y | N |
no modifier | Y | Y | N | N |
private | Y | N | N | N |
Short:
1) access modifiers anlayın: Eğer dışındaki kullanıcılardan "gizlemeye" ayrıntıları yapabileceği iki şey vardır Sıradan kodlayıcıları yanlışlıkla yollarından uzak tutulan yöntemleri çağırmaktan korur. Kodlayıcılar bunu takdir edecektir. Kimse karmaşık bir API kullanmak istemiyor.
Şu anda b.doWork()
protected
'dir. senin main()
, (bu değil) sınıfında A
içinde alt sınıf B
(bu değil) veya aynı paketi (net değil de, sen lar (paketine ilişkin herhangi bir ipucu gönderilmeyen) ise Yani sadece senin main()
içinde görülmeye devam ediyor kodunuzda bulunur).
Bu, b.doWork()
'u görmekten korunmaya çalıştığınız soruyu akla getiriyor? Oluşturduğunuz paket sadece bir şey geliştiriyorsanız, o kadar da kötü olmayabilir. Pek çok kişi bu pakette birçok başka sınıfla uğraşmaktan hoşlanıyorsa, muhtemelen A
ve B
sınıflarına aşina olacaklardır. Herkesin görebileceği yerde takılmak istemediğiniz durumlar budur. Burada sadece sınıf ve alt sınıfa erişime izin vermek güzel olurdu. Ancak paket erişimine de izin vermeden alt sınıf erişimine izin veren bir düzenleyici yoktur. Alt sınıfta olduğunuz sürece protected
yapabileceğiniz en iyi şeydir. Bu düşünceyle, çok sayıda sınıf içeren paketler oluşturmaya gitmeyin. Paketleri sıkı ve odaklı tutun. Bu şekilde çoğu insan, şeylerin güzel ve basit görüneceği paketin dışında çalışacaktır. Özetle main()
'un b.doWork()
numarasını main()
numaralı telefonu başka bir pakete koymasını engellemek istiyorsanız, özetle bakın.
package some.other.package
public final class Main {
...
}
2) tavsiye bu sonraki parçanın değeri kodunuzun genişletilmişse sadece gelecek sorunları çözmede çünkü mevcut kodla anlamak zor olacaktır.
public static void main(String[] args) {
A someALikeThingy = new B(); // <-- note use of type A
someALikeThingy.work(); //The name is silly but shows we've forgotten about B
//and know it isn't really just an A :)
}
: Ama gerçekten yakından ana gibi ise daha iyi olurdu demek istediği Kodunuzda b.doWork()
What does "program to interfaces, not implementations" mean?
gibi görerek şeylerden insanların korunması fikrine bağlıdır Niye ya? A
türü B
türüne göre ne işe yarar? İyi A
, arayüzü'a daha yakındır. Not, burada sadece interface
anahtar kelimesini kullandığınızda elde ettiğiniz şeyleri kastetmiyorum.Ben B
tür A
türünün somut bir uygulama olduğunu ve B
karşı kesinlikle kod yazmak zorunda kalmazsam gerçekten tercih ederim çünkü kim A
B
şeyler var garip bilir kim bilir. Burada anlamanız zor çünkü ana kod, kısa & tatlı. Ayrıca,ve B
arasındaki arabirimler herkesten farklı değildir. Her ikisi de sadece bir kamu yöntemi work()
var. main()
'un uzun ve kıvrımlı olduğunu düşünün, Imagine B
, her türlü A
yönteminin kapalı kalmasını sağladı. Şimdi başa çıkmak istediğiniz bir sınıf C
oluşturmanız gerektiğini hayal edin. Ana, B
no.lu ana hat beslendiğinde, B
'un sadece A
gibi basit bir şey olduğunu bildiğine inanmak rahatlatıcı olmaz mıydı? new
'dan sonraki bölüm haricinde, bu doğru olabilir ve main()
'a bir şey yapmanıza rağmen bu new
'u güncelleştirmenizden tasarruf etmenizi sağlar. Gerçekten de, bu, güçlü bir şekilde yazılan bir dilin kullanılmasının bazen güzel olabileceğidir değil mi?
<rant>
bile B()
ile new
sonra o bölümü güncellenmesi düşünüyorum Eğer yalnız değilsin çok fazla çalışmadır. Bu küçük bir saplantı, bize, herhangi bir kurucunun yapmanıza izin verebileceği basit bir enjeksiyondan çok, nesne yapısını otomatikleştiren bir dizi çerçeveyi yaratan dependency injection movement'u verdi.
</rant >
Güncelleme: Sana küçük dar paketleri oluşturmak için isteksiz yorumlarınızı görmek
. Bu durumda, bir kompozisyon tabanlı strateji modeli lehine bir kalıtım tabanlı şablon kalıbı terk düşünün. Hala polimorfizm oluyorsun. Sadece bedavaya olmaz. Biraz daha kod yazımı ve dolaylı. Fakat çalışma zamanında bile durumu değiştirirsiniz.
Bu, sezgisel karşıt görünebilir çünkü şimdi doWork()
herkese açık olmalıdır. Bu ne biçim bir koruma? Peki şimdi B
'u tamamen geride veya hatta AHandler
'un içinde saklayabilirsiniz. Bu, şablon kodunuzda kullanılanı tutan ancak sadece work()
'u görüntüleyen insan dostu bir cephe sınıfıdır. A
sadece interface
olabilir, AHandler
hala bir B
olduğunu bilmiyor. Bu yaklaşım bağımlılık enjeksiyon kalabalığı ile popülerdir, ancak kesinlikle evrensel çekiciliğe sahip değildir. Bazıları her seferinde körü körüne çeker, bu da birçok şeyi rahatsız eder. Burada bu konuda daha fazla bilgi edinebilirsiniz: Yapabileceğin Prefer composition over inheritance?
"kolayca yanlışlıkla b.doWork çağırmak yapabiliyor()". Gerçekten mi? Korunuyor, bu yüzden sadece A ve B örnekleri arayabilir. –
Ne yazık ki, korumalı olduğundan, paketteki tüm sınıflar bunu arayabilir. Paketleri bölmek bir yoldur, ancak 1 veya 2 sınıf paketlerden kaçınmayı tercih ederim. –
Hayır! Varsayılan erişim değiştiricisini tanımlıyorsunuz (yani, hiçbiri). Korumalı "sadece bana veya beni genişleten sınıflar bunu kullanabilir" anlamına gelir –