Java neden bazı sınıflarla kapsülleme kullanmıyor?


25

Sorum şu System.inve System.outsınıflarla ilgili (Standart kütüphanedeki gibi başkaları da olabilir). Neden? OOP'de bu kötü bir uygulama değil mi? Şunun gibi kullanılmamalı mı : System.getIn()ve System.getOut()? Her zaman bu soruyu yaşadım ve umarım burada iyi bir cevap bulabilirim.

Yanıtlar:


36

Sınıf içindeki inve outalanlarının tanımı System:

public final static PrintStream out;
public final static InputStream in;

Bunlar sabittir. Onlar da nesneler oluyor, ama bunlar sabittir. Math sınıfı ile aynı.

public static final double E = 2.7182818284590452354;
public static final double PI = 3.14159265358979323846;

Veya Boolean sınıfında:

public static final Boolean TRUE = new Boolean(true);
public static final Boolean FALSE = new Boolean(false);

Veya Color sınıfında:

public final static Color white     = new Color(255, 255, 255);
public final static Color black     = new Color(0, 0, 0);
public final static Color red       = new Color(255, 0, 0);

Değişmeyen bir kamu sabitine erişirken, onu kapsüllemek için önemli bir avantaj yoktur - kavramsal olarak veya performansa dayalı. Orada. Değişmeyecek.

Color.whiteVe arasında gerçek bir fark yoktur System.out.


Öyle görmedim, onlar sürekli nesneler. Bu oldukça iyi bir açıklama.
Clawdidr

1
Bugünün Java'sında @Clawdidr, biri olabilir kullanmayı düşünün enumgerçi ... onları tutmak için enumJava 1.5 (1.0 gün içinde bu seçenek yoktur) ile yeniydi.

Sadece meraktan (kendim Java geliştiricisi değil): final staticve arasında bir fark var static finalmı? Eğer öyleyse ne?
Marjan Venema,

1
@MarjanVenema fark yok, sadece değiştiricilerin tercih edilen sırası. kontrol biçemi değiştiricisi kontrolü tercih edilen sırayı gösterir. Görünüşe göre, jdk versiyonunda bu iki kaynak dosyayı kim yazdıysa, sipariş üzerinde anlaşamadım. Sadece kongre.

:) ve yanıt verdiğiniz ve bağlantı için zaman ayırdığınız için Michael'a teşekkür ederiz.
Marjan Venema,

5

Asıl sebep, bunun eski bir konudur. System.in,out,errSabitleri Java 1.0 parçası ... ve muhtemelen çok daha geriye idi. O zaman, tasarımın sorun yaşadığı açıktı, düzeltmek için çok geçti. Yapabilecekleri en iyi şey, System.setIn,setOut,setErrJava 1.1'deki yöntemleri eklemek ve ardından dil belirtimi sorunları 1 ile ilgilenmekti .

Bu, neden System.arraycopyadının Java adlandırma kurallarını ihlal ettiği statik bir yöntemin olduğu sorununa benzer .


Bunun "kötü tasarım" olup olmadığına gelince, sanırım öyle. Mevcut OO dışı işlemenin ciddi bir sorun olduğu durumlar vardır. (Bir Java programını çalıştıracak nasıl ... düşün içine onların "standart IO" dere gereksinimleri çatışma. Düşün zaman başka ... birim gerektirir bir akışlarını değiştirerek bu kodu test.)

Bununla birlikte, birçok şeyi yapmanın mevcut yolunun daha uygun olduğu argümanı ile de ilişki kurabilirim .


1 - Bu dikkat etmek ilginç System.in,out,err Değişkenlerin JLS'de "özel anlambilim" olarak özel olarak belirtildiğini . JLS, eğer bir finalalanın değerini değiştirirseniz, bu alanların haricinde davranışın tanımsız olduğunu söyler .


2

Dıştaki nesnenin değişmez olduğuna inanıyorum, bu da kamuya açık bir statik alanda tutulması için bir şekilde güvenli (bu tartışmalı).

JDK'daki sınıfların çoğu, en iyi nesne yönelimli tasarım ilkelerine saygı göstermiyor. Bunun bir nedeni, Nesne Oryantasyonunun sadece bir ana paradigma olarak ortaya çıktığı ve pek çok programcının şu an olduğu gibi onlara aşina olmadığı neredeyse 20 yıl önce yazılmış olmalarıdır. Kötü bir API tasarımına çok iyi bir örnek, 19 yılını değiştiren Tarih ve Saat API'sidir ...


3
İfadeyi daha da güçlendirirdim, ortak bir son değişken (statik ya da değil) bir alıcı olarak tam olarak "Güvenli" olur ve bir belirleyici / alıcı çifti üzerindeki hareketsizliği algılardım. Belirleyiciler hemen hemen her zaman kötü bir fikirdir (Değiştirilemez iyidir - ve değiştirilemez ise, "Belirleyen" yöntem de muhtemelen küçük bir işletme mantığını hak eder) final, ama ikisini de yapmamak tercih edilir - bir sınıfa verileri için sorma, bir sınıfa verisine bir şeyler yapma.
Bill K,

@BillK: Evet, aynı zamanda Demeter Yasası olarak da bilinir (bir yasa değil, bir kılavuz olsa da).
sleske

2

Bu cevap harika ve doğru.

Bazı durumlarda kullanılabilirlik adına tavizler verildiğini eklemek istedim .

String türünün nesneleri, String ilkel olmadığında yeni, olay olmadan başlatılabilir:

String s = "Hello";

İlkel olmayan bir dize olması, şöyle başlatılmalıdır:

String s = new String("Hello");          // this also works 

Ancak derleyici daha kısa, daha az OO seçeneğine izin verir, çünkü String API'de en yaygın kullanılan sınıftır.

Ayrıca, diziler OO olmayan bir şekilde başlatılabilir:

int i[] = {1,2,3};

Yeterince garip, bir nesne bir sınıfın örneği veya bir dizidir. . Anlam dizileri tamamen ayrı bir sınıf türüdür.

Diziler, lengthsabit olmayan bir ortak alana sahiptir. Ayrıca sınıf dizileri ile ilgili hiçbir dokümantasyon örneği yoktur. (Arrays sınıfı veya java.reflect.Array ile karıştırılmamalıdır).

int a = myArray.length;    // not length()

6
Sana farklı şeyler - new String("Hello")her zaman yeni bir String nesnesi yaratacak. String s = "Hello";İnterned nesnesini kullanacak iken . Karşılaştırma: "Hello" == "Hello"doğru olabilir new String("Hello") == new String("Hello"), her zaman yanlıştır. İlkinde mümkün olmayan derleme zamanı optimizasyonu büyüsü var new String("Hello"). Bkz en.wikipedia.org/wiki/String_interning

@MichaelT Dizilere tamamlayıcılık aşkına fazladan gariplik ekledim.
Tulains Córdova,

2
@Tarik "Dize ilkel olmayan olmak, bunun gibi bir şekilde anlatılmalıdır: String s = new String("Hello");" a itiraz ediyordum . Daha kısa olan seçenek ( String s = "Hello";) string interning nedeniyle daha doğrudur.

2
İle String, "daha doğru" bir seçenek yoktur. İkisi de doğru. Gerçi, MichaelT'ın dediği gibi, kısa olanı String interning nedeniyle tercih edilir.
Andres F.

1
@AndresF. "Daha az OO" için "daha az doğru" değiştirdim.
Tulains Córdova
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.