2016-05-03 67 views
6

varsayalım ben bir arayüz olarak tanımlanan çok karmaşık şartname vardır:Kotlin heyeti

interface Spec { 
    fun sayHello() 
} 

Ve standart bir uygulamayla:

Şimdi
class Impl(private val msg: String) : Spec { 
    override fun sayHello() { 
     println(msg) 
    } 
} 

Ben oluşturmak istediğinizi varsayalım Bu belirtimi ve delegeleri bir uygulamaya uygulayan sınıf, ancak tam temsilci nesnesi nesnenin kullanım ömrü boyunca değişebilir.

class Derived(var target: Spec) : Spec by target 

Yukarıdaki örnekte sorun yapıcı çağrıldığında yapıcı argüman target temsilci nesnesi olarak olmasıdır: Burada bir örnek verilmiştir. Delegeye daha sonra bir özellik erişimi yerine doğrudan sınıf tarafından erişilir. (Bu, Kotlin tarafından üretilen bytecode yoluyla onaylanmıştır.)

Yani, sınıf oluşturulduktan sonra target özelliği değiştirilse bile, temsilci değişmez.

Herkes, her bir yöntemi yazmak zorunda kalmadan, bu yetkilendirmeyi Kotlin'de yapmak için bir yöntem sağlayabilir mi?

İdeal bir çözüm, nesnenin ömrü boyunca delege gerektiğinde delege olarak değerlendirilecek ve kullanılacak lambda veya başka bir ifade olarak genel olarak bir delegasyona izin verebilir.

cevap

6

Şu an bunu yapmanın bir yolu yok. Kullanılacak

class Holder(var impl: Spec) : Spec { 
    override fun sayHello() = impl.sayHello()  
} 

class Derived(target: Spec, 
       private val holder: Holder = Holder(target)) : Spec by holder { 

    fun changeTarget(newTarget: Spec) { 
     holder.impl = newTarget 
    } 
} 

Maalesef holder sırayla bir yapıcı parametre olmalıdır: Bkz Kotlin issue KT-5870

Currenlty Kotlin Sen dolaylama düzeyi ekleyebilir

0

sınıf in başlatıcısı yetki verilen kişi için ifadeyi değerlendirir delegasyon yapısı ile (Kotlin v1.0'da olduğu gibi), bu nedenle birincil kurucuyu karmaşıklaştırır.

+1

Bu durumda, yazarın kaçınmaya çalıştığı tüm yöntemleri manuel olarak devretmeniz gerekir. – Michael

+0

@Michael evet bu doğru, ancak sadece manuel bir temsilci sadece bir kez 'Tutucu' için yapmak zorundayım, bundan sonra hiçbir ek tablo – voddan

+0

ile kullanabilirsiniz Bunun için herhangi bir ek sınıfa ihtiyacınız yok. Sadece 'Derived' den her şeyi delege edin. – Michael