If i have such code which uses Composition using K...
# getting-started
v
If i have such code which uses Composition using Kotlin delegate
Copy code
interface Walk {
    fun walk()
}

class CatWalk : Walk {
    override fun walk(){
        println("Cat is walking")
    }
}

class Cat : Walk by CatWalk() {
    override fun walk(){
        println("Cat is running")
    }
}

fun main() {
    val cat = Cat()
    cat.walk()
}
This works fine as all functions are implemented by
CatWalk
but I want Walk interface to have some function lets say
eat()
which i dont want
CatWalk
class to implement but let the class
Cat
provide its implementation, how can i do so? I tried making
CatWalk
an abstract class and let
Cat
provide the implementation but it did not work that way Is there any way to achieve such behaviour?
c
Copy code
interface Walk {
    fun walk()
    fun eat()
}

interface CatWalk : Walk {
    override fun walk() {
        println("Cat is walking")
    }
}

class Cat : Walk, CatWalk
// ^ doesn't compile, 'eat' isn't implemented
If you're overriding (most) implementations provided by the delegate, you probably don't want to use delegates at all.
v
I have a use case like this
Copy code
interface Walk {
    fun walk()
    fun eat()
}

class CatWalk : Walk {
    override fun walk(){
        //how can i do this?
        showSnackBar("Cat is walking")
    }
    override fun eat() {
        showToast("Eat")
    }
}

class BaseCat {
    fun showSnackBar(message: String) {
       
    }
    
    fun showToast(message: String) {
        
    }
}

class Cat : BaseCat, Walk by CatWalk() {
}
How can i achieve this, I cannot pass the
Cat
instance in
CatWalk
constructor, it gives me error I cant have abstract fun in
CatWalk
Basically, all my screens extend a
BaseScreen
which has such utility methods, now i want to add features to Screens using Composition, but i want to call functions which are in the base class
BaseScreen
I hope you understand what i mean to say
Currently i have to rely on default functions of interfaces, but that stops me from implementing variables, for which i have to create another class
UseCase
in this case Example
Copy code
interface PostActionHandler : KoinComponent {

    val postActionUseCase: PostActionUseCase
    val component: BaseComponent
    val onNavEvent: (AppNavEvents) -> Unit
    val navigateForRemote: Boolean
        get() = false

    fun handlePostAction(action: PostAction) = with(action) {
        trackPostAction(this)
        when (this) {
            is PostAction.AuthorClick -> handlePostAuthorClick(post)
            is PostAction.Clicked -> handlePostClick(post)
            is PostAction.GroupClick -> handleGroupClick(group)
            is PostAction.LikeToggle -> handlePostLike(post)
            is PostAction.ImageClick -> handlePostImageClick(post, index)
c
Delegation isn't like inheritance. When using delegation, you are delegating to an existing object. You cannot override things from that object. The only thing you can do is 'shadow' them. I don't think you want to use delegation, here.
v
Then whats the best approach I can go for to achieve this, my approach of leveraging default functions of interface helps, but only for functions and not variables
c
If you need overrideable state, use an abstract class. But I don't really see why multiple screens would have the same state.
v
My main use case is to add interactions Like a feature of "Creating a Post", which if extended by any class, will have all code to do this, but as this is an interface i cannot keep any state or variable in it
I have to create another class and then add wrapper variables to achieve it Example:
Copy code
interface CreatePostFeature {

    val createPostUseCase: CreatePostUseCase
    val component: BaseComponent
    val refType: PostReferenceType
    val onNavEvent: (AppNavEvents) -> Unit
    val localPostsEventBus: LocalPostEventBus

    val imagesLeft
        get() = CreatePostUseCase.maxImageCount - images.size

    val imagePickerFeature: ImagePickerFeature?
        get() = null

    val scope
        get() = component.componentScope

    val text: TextFieldValue
        get() = createPostUseCase.text

    val images
        get() = createPostUseCase.images

    val link
        get() = createPostUseCase.link
c
How many different screens do you have that allow creating posts?
v
Around 4 screens implement this interface All they have to do is implement the variables which dont have a default getter But i dont want this extra
UseCase
class for variables and add wrapper variables to access those, Rather create the stateFlow, mutableState etc directly