Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

kotlin abstract static fun in companion objects

Tags:

I learn the use of ViewHolder from an offical sample named UserViewHolder.

public class UserViewHolder extends RecyclerView.ViewHolder {

static UserViewHolder create(LayoutInflater inflater, ViewGroup parent) {
    UserItemBinding binding = UserItemBinding
        .inflate(inflater, parent, false);
    return new UserViewHolder(binding);
  } 

  private UserItemBinding mBinding;

  private UserViewHolder(UserItemBinding binding) {
    super(binding.getRoot());
    mBinding = binding;
  }

  public void bindTo(User user) {
    mBinding.setUser(user);
    mBinding.executePendingBindings();
  }

}

I'm going to write many ViewHolder classes, so I hope I can write an abstract class. In Java, it looks like:

public abstract  static class BaseViewHolder {

abstract static BaseViewHolder create()

abstract void bindTo()

}

I try to write it using Kotlin , but finally I find that it's not as simple as it in Java.

abstract class BaseViewHolder(itemView: View):RecyclerView.ViewHolder(itemView) {

abstract fun bindTo(viewModel: BaseViewModel)

}

In Kotlin, if I want a static function, I need to write the function in "companion objects". But it can't be a "abstract".

In Java, a abstract class with abstract classes is common.

But how can I write it in Kotlin?

update:

I have wrote my own SleepViewHolder. I'm going to write lots of ViewHolder, such as AppleViewHolder, BananaViewHolder and so on. So I want to build a BaseViewHolder as a pattern. My question is that, in that case, what's the best way to write the pattern BaseViewHolder? Should I change the constrcuter of it, or make the create function public?

open class SleepViewHolder private constructor(private val binding: ItemSleepBinding)
: RecyclerView.ViewHolder(binding.root) {

companion object {
    @JvmStatic
    fun create(inflater: LayoutInflater, parent: ViewGroup): SleepViewHolder {

        val binding: ItemSleepBinding
                = DataBindingUtil.inflate(inflater, R.layout.fragment_base, parent, false)

        return SleepViewHolder(binding)
    }
}

open fun bindTo(viewmodel: SleepViewModel) {
    binding.vm = viewmodel
    binding.executePendingBindings()
}

}

like image 280
jatwing Avatar asked Jan 11 '18 05:01

jatwing


People also ask

Is companion object static Kotlin?

Unlike Java or C#, Kotlin doesn't have static members or member functions. Kotlin recommends to simply use package-level functions instead.

Can abstract and static used together?

Declaring abstract method static If you declare a method in a class abstract to use it, you must override this method in the subclass. But, overriding is not possible with static methods. Therefore, an abstract method cannot be static.

How does Kotlin define static fun?

In order to implement a static method in Kotlin, we will take the help of "companion objects". Companion objects are the singleton objects whose properties and functions are tied to a class but not to the instance of that class. Hence, we can access them just like a static method of the class.

Why did Kotlin get rid of static?

Kotlin is known primarily as a drop-in replacement for Java, but it gets rid of a well-known Java construct: the static keyword. Instead, that class-level functionality is offered mainly by companion objects.


1 Answers

In Kotlin, unlike Java or C#, classes do not have static methods. In most cases, it's recommended to simply use package-level functions instead.

If you need to write a function that can be called without having a class instance but needs access to the internals of a class (for example, a factory method), you can write it as a member of an object declaration inside that class.

Even more specifically, if you declare a companion object inside your class, you'll be able to call its members with the same syntax as calling static methods in Java/C#, using only the class name as a qualifier.

This is how you can write a companion class

class MyClass {
   companion object { } // will be called "Companion"
}
fun MyClass.Companion.foo() { // ...
}

this is how you call foo() function...

MyClass.foo()
like image 118
Suryakant Sharma Avatar answered Sep 22 '22 13:09

Suryakant Sharma