2012-10-04 12 views
7

Uzatılmış bir sınıfın süper yapıcısına iletilmesi gereken bir kurucuda oluşturulmuş bir nesneye yapılan bir başvuruyu sürdürmenin iyi bir yolu var mı (süper tarafından erişilebilir hale getirilmesinin dışında) sınıf veya yapıcıya parametre olarak geçirme)?Süper yapıcıya aktarılan yeni nesneyi atıfta bulunun

Bir örnekle açıklamama izin verin. aşağıdaki gibi bu sınıf ben istiyorum, Şimdi

class TestA { 
    TestA(Object foo) {} 
} 

uzanır: Bu sınıf (ı değiştiremez ve hangi bana foo erişimi vermez olan) al

class TestB extends TestA { 
    Object myCopyOfFoo; 

    TestB() { 
     super(new Object()); 
    } 
} 

mi var myCopyOfFoo'da oluşturulan new Object()'u depolamanın iyi bir yolu var mı? Bu üç fikir

Hiçbiri çalışır:

TestB() { 
    myCopyOfFoo = new Object(); 
    super(myCopyOfFoo); 
} 

(Hata: Yapıcı çağrısı bir yapıcı ilk deyimi olmalıdır)

TestB() { 
    super(myCopyOfFoo = new Object()); 
} 

(Hata: Bir örnek alan myCopyOfFoo atıfta olamaz açıkça bir kurucu) başlatırken

TestB() { 
    super(makeFoo()); 
} 

Object makeFoo() { 
    myCopyOfFoo = new Object(); 
    return myCopyOfFoo; 
} 

(Hata: i atıfta olamaz nstance yöntemi açıkça ben aşağıdakileri yapabileceğini tahmin bir kurucu)

çağırarak, ancak ne iş parçacığı güvenli ne de zarif ise:

static Object tempFoo; 

TestB() { 
    super(tempFoo = new Object()); 
    myCopyOfFoo = tempFoo; 
} 

kimse benim için daha iyi bir fikir var mı? Ve neden dünyadaki ilk iki düşüncem yasal değil?

cevap

15

ne dersiniz:

ikinci yapıcı özel olduğundan, sadece aynı sınıftan (ya kapatıcı bir sınıfın) içinde çağrılabilir yüzden sadece şey çağırarak ikinci yapıcı olduğundan emin olmak gerekir yapabilirsiniz
class TestB extends TestA { 
    Object myCopyOfFoo; 

    // I assume you actually wanted this to take a parameter called foo? 
    // I've left it as per the question... 
    TestB() { 
     this(new Object()); 
    } 

    private TestB(Object copy) { 
     super(copy); 
     myCopyOfFoo = copy; 
    } 
} 

İlk kurucu yaptığı gibi uygun bir kopyasını yaptı.

DÜZENLEME: En gerçek durum varolan parametrenin bir kopyasını alıyorsun ki, o zaman bu Rağmen oldukça çirkin :(

+0

Bu zaten her durumda birçok durumda ikinci özel yapıcısı kullanıyorum çünkü aslında güzel kodumu uyan iyi bir çözüm gibi görünüyor. Bu cevabı kontrol etmeyi denemeye başladım, ama yine de çok fazla kod gibi görünüyor.Bundan şüphe duyuyorum, ama daha kısa öneriler olup olmadığını görelim. Ama şimdiden teşekkürler! –

+0

@Markus: * Gerçek * durumunuzun gerçekten bir parametre alması ve bir kopya oluşturması durumunda potansiyel bir öneri sahibiyim. Verdiğiniz kod gerçekten temsilcisiyse (yani hiçbir şeyden yeni bir nesne oluşturuyorsa), diğer önerim yardımcı olmaz. Ama ben onu düzenleyeceğim. –

0

...

class ClassB extends ClassA { 
    private final Foo copyOfInput; 

    ClassB(Foo input) { 
     super(input = input.clone()); 
     copyOfInput = input; 
    } 
} 

çalışacak neler aşağıdaki hakkında:

class TestB extends TestA { 
    Object myCopyOfFoo = new Object(); 

    TestB() { 
     super(myCopyOfFoo); 
    } 
} 

özünde bu yo yapacak, böylece yeni bir nesne TestB oluştururken nesnesi, yalnızca başlatılacaktır istiyorsun?

+1

Nope, "supertype yapıcısı çağrılmadan önce myCopyOfFoo öğesine başvuruda bulunamıyor" hatası al –

+1

Diğer bir problem de derleyicinin myCopyOfFoo öğesinin TestB() yapıcısına başlatılmasını satır içi olarak yapmasıdır. Yani, bir hata atmasa bile, yeni Nesne'den ziyade null ile super() öğesini çağırır. –

1

Başka bir seçenek:

public class TestB extends TestA { 

    Object myCopyOfFoo; 

    private TestB(Object foo) { 
     super(foo); 
     myCopyOfFoo = foo; 
    } 

    public static TestB createInstance() { 
     Object foo = new Object(); 
     return new TestB(foo); 
    } 

} 
İlgili konular