2017-06-09 80 views
5

Mam metodę w Java tak:Czy odlewanie przez skrzyżowanie jest możliwe w Kotlin?

public <T extends A & B> methodName(T arg, ...) 

gdzie A jest klasa i B to interfejs.

W mojej klasie Kotlin, mam inny variable typu C, i życzę, aby osiągnąć następujące:

if (variable is A && variable is B) { 
    methodName(variable, ...) 
} else { 
    // do something else 
} 

Czy to możliwe, aby prawidłowo oddanych variable tak, że może on być stosowany jako argument bez błędów ?

Obecnie variable ma metody setter, taki mądry odlew nie jest dostępny. Jednakże przetestowałem go również z lokalnym numerem val, a wartość została określona jako typ Any, co nie pomaga.

+0

jaka jest twoja wersja kotlin? –

+2

Oto pokrewny problem: https://youtrack.jetbrains.com/issue/KT-7304 –

Odpowiedz

1

Kotlin nie obsługuje typów skrzyżowań. To powoduje, że variable jest inteligentnym rzutowaniem na Any, ponieważ jest to wspólny przodek A i B.

Jednak Kotlin obsługuje ogólne ograniczenia typów. Możesz użyć tego, aby ograniczyć parametr typu do jednego lub więcej typów. Można to wykorzystać zarówno w metodach, jak i klasach. To składnię funkcji (odpowiednik swoimi methodName w Kotlin):

fun <T> methodName(arg: T) 
    where T : A, 
      T : B { 
    .... 
} 

można użyć tego obejść problemu, tworząc klasę, która rozciąga się zarówno A i B, a następnie powierza realizację tych typy do twojego obiektu. Tak:

class AandB<T>(val t: T) : A by t, B by t 
    where T : A, 
      T : B 

Teraz można nazwać methodName zmieniając test IF-by sprawdzić, czy jest to AandB<*>:

if (variable is AandB<*>) { 
    methodName(variable, ...) 
} 

Trzeba owinąć variable w AandB gdzieś chociaż. Nie sądzę, że możesz to zrobić, jeśli nie masz informacji o typie dla variable dostępnej w dowolnym miejscu.

Uwaga: Klasa AandB nie implementuje hashCode, equals ani toString. Możesz zaimplementować je w celu delegowania do implementacji t.

Uwaga 2: Działa tylko wtedy, gdy A i B są interfejsami. Nie możesz delegować na zajęcia.

+0

Jak wspomniano i jak już testowałem, zarówno A, jak i B muszą być interfejsami. Jednak argument funkcji mojej jest typu T, gdzie T: [klasa], T: [interfejs]. Czy istnieje jakiś sposób? Twoja metoda jest jednak bardzo interesująca. –