2017-05-29 6 views
3

Kann die AsyncResult-Klasse verwendet werden, um zu verhindern, dass InFlight, Error und InFlight in UserDataAppResult und CreateUserResult neu definiert werden?Wie versiegelten Klassen Generika in Kotlin machen?

//TODO: use this to make the below classes generic? 
sealed class AsyncResult{ 
    object InFlight : AsyncResult() 
    data class Error(val errorMessage: String) : AsyncResult() 
    data class Loaded<out T>(val users: T) : AsyncResult() 
} 

sealed class UserDataAppResult : AppResult() { 
    object InFlight : UserDataAppResult() 
    data class Error(val errorMessage: String) : UserDataAppResult() 
    data class Loaded(val users: List<User>) : UserDataAppResult() 
} 

sealed class CreateUserResult : AppResult() { 
    object InFlight : CreateUserResult() 
    data class Error(val errorMessage: String) : CreateUserResult() 
    data class Loaded(val users: User) : CreateUserResult() 
} 

Ist es möglich, dass der obige Code so aussieht?

sealed class AsyncResult{ 
    class InFlight : AsyncResult() 
    data class Error(val errorMessage: String) : AsyncResult() 
    data class Loaded<out T>(val users: T) : AsyncResult() 
} 

sealed class UserDataAppResult : AsyncResult() 
sealed class CreateUserResult : AppResult() 

val activeUsers: Flowable<UserDataAppResult> = appDatabase.userDao().getActiveUsers(appSettings.currentLanguage.ordinal) 
    .map<UserDataAppResult> { UserDataAppResult.Loaded(it) } 
    .onErrorReturn { UserDataAppResult.Error(it.localizedMessage) } 
    .startWith(UserDataAppResult.InFlight) 
    .observeOn(AndroidSchedulers.mainThread()) 
    .share() 

fun createUser(): Flowable<CreateUserResult> { 

    val userId = UUID.randomUUID().toString() 
    val user = User() 
    user.id = userId 
    return appDatabase.userDao().insertAll(user) 
     .map <CreateUserResult> { CreateUserResult.Loaded(user) } 
     .onErrorReturn { CreateUserResult.Error(it.localizedMessage) } 
     .startWith(CreateUserResult.InFlight) 
} 

Derzeit wird UserDataAppResult.Error nicht gefunden, was sinnvoll ist. Aber ist es möglich, die versiegelte AppResult-Klassenhierarchie wiederzuverwenden und neue Typen einzuführen?

Antwort

1

In Kotlin ist das nicht möglich. Jeder Typ, den Sie verwenden, muss irgendwo eine explizit deklarierte Klasse haben. Klassen werden nicht implizit vom Compiler erstellt, selbst wenn verschachtelte Klassen in der Oberklasse deklariert sind.

Für Ihr Problem, empfehle ich Ihnen, den Code aus der Kombination von zwei Vererbung-basierten Hierarchien zu einem der beiden kombinieren Vererbung und Zusammensetzung, oder einfach nur umstrukturieren die Hierarchie in irgendeiner Weise, zum Beispiel (ich nehme an, die genaue Instanz eines Ergebnis wäre Ihnen für den Fall irrelevant sein, wenn es nicht Loaded):

sealed class AsyncResult { 
    object InFlight : AsyncResult() 
    data class Error(val errorMessage: String) : AsyncResult() 
    sealed class Loaded<out T>(val result: T) : AsyncResult() { 
     sealed class UserDataAppResult(users: List<User>) : Loaded<List<User>>(users) 
     sealed class CreateUserResult(user: User) : Loaded<User>(user) 
    } 
} 
+0

Danke, ich werde dein Ansatz versuchen und sehen, wie ich weitermachen. –