DeuS
DeuS

Reputation: 17

Kotlin Inheritance

I'm currently learning to split my messy code into DDD (note, learning) paradigm. The entities (IEntity, IUser) is domain layer is made up of interface, which then implemented at the Data layer (BaseEntity, User). Access to data is through the repository pattern. But as I defined for IUserRepository to return IUser, at the data layer I have to manually cast it User back to IUser to match the return signature.

How can I avoid the casting? Thank you.

Domain layer

interface IEntity
{
    var id: Long?
    var name: String?
}

interface IUser : IEntity
{
}

interface IBaseRepository<T: IUser>
{
    fun get(id: Long): Observable<T?>
}

interface IUserRepository : IBaseRepository<IUser>
{
}

Data layer

abstract class BaseEntity() : IEntity
{
    @SerializedName("id")
    override var id: Long? = null

    @SerializedName("full_name")
    override var name: String? = null
}

class User() : BaseEntity(), IUser
{
}

interface UserRetrofitApi
{
    @GET("user/{uuid}/")
    fun get(id: Long): Observable<User?>
}

class UserRepository(private val _api: UserRetrofitApi) : IUserRepository
{
    override fun get(id: Long): Observable<IUser?> {
        return _api.get(id) as Observable<IUser?> // How to avoid casting here without resorting to generic UserRepository<T: IUser>
    }
}

Upvotes: 1

Views: 393

Answers (2)

nhaarman
nhaarman

Reputation: 100388

Declare your get function in the base repository as follows:

fun get(id: Long): Observable<out T?>

and likewise change the get function in UserRepository to:

override fun get(id: Long): Observable<out IUser?> {
    return _api.get(id)
}

See the docs on variance for more information.

Upvotes: 1

kutsyk
kutsyk

Reputation: 295

If I understand you right you just need to change you return the result of UserRetroFitApi.get to Observable<IUser?>.

class UserRetrofitApi
{
    fun get(id: Long): Observable<IUser?> {
        val user = User()
        user.id = 1
        user.name = "User 1"
        return Observable.just(user)
    }
}

Upvotes: 0

Related Questions