Is it possible in Kotlin to define a value with a combination of interfaces as type? - kotlin

Say I have two Kotlin interfaces, like
interface MyInterfaceA {
fun myFunA()
}
interface MyInterfaceB {
fun myFunB()
}
Can I declare a value with type constrained to both interfaces at the same time? I.e., I am looking for something like this (pseudocode)
val myVal : {MyInterfaceA, MyInterfaceB} = ...
So that whatever I initialize myVal with must implement both interfaces?

Something you could do,is to create another class or interface that implements both interfaces
class CombineAB: MyInterfaceA, MyInterfaceB {
}
val myVal: CombineAB = ......

Related

Kotlinx serialisation, common interface or type class

I am working on a plugin type system where 3rd parties will register classes that will expose data. I don't know exactly what the data will look like but I will enumerate these plugin instances collect the data and I would like to serialise it. A simplified version.
interface DataProvider {
fun getDataThatIsSerializable() : ???
}
What can i set the return type to so that I know that I will be able to serialise it with kotlinx serialisation. I cannot see any common interface that is injected into the class and given thet kotlin doesn't support type classes its not clear how to achieve what I am trying to do?
I considered something like this:
interface DataProvider {
fun getDataThatIsSerializable() : Pair<Any,KSerializer<*>>
}
but i could not pass this into the Json.encodeAsString functions, the types do not match
Are there any other options I can consider?
kotlinx.serialization doesn't like serializing things unless you can tell it exactly what you're working with.
Would it make sense for the DataProvider to be responsible for serializing its own data? Something like:
interface DataProvider {
fun getDataThatIsSerializable() : Any
fun encodeAsJsonString(data: Any) : String
}
#Serializable
data class Foo(val value: Int)
class FooDataProvider : DataProvider {
override fun getDataThatIsSerializable() : Any {
return Foo(7)
}
override fun encodeAsJsonString(data: Any): String {
return Json.encodeToString(Foo.serializer(), data as Foo)
}
}

Short Interface implementation in kotlin

Now
in kotlin we have a possibility to implement the interface like this:
interface AnimalStrategy {
fun eat(): Outcome
}
Want to have
Question: Is it possible to declare the interface in kotlin in shorter syntax?
interface AnimalStrategy = fun eat(): Outcome

Can I resolve a generic type from another generic declaration in an interface?

Expect you have an interface like this:
interface MyInterface<T : BaseClass<I>, I> {
fun someMethod(param: I) : T
}
As you can see I use I as a parameter in someMethod. But actually I don't want to declare I when I implement this interface like this:
class BaseClassImpl : BaseClass<OtherClass>
class Impl : MyInterface<BaseClassImpl, OtherClass> {
override fun someMethod(param: OtherClass) {
TODO("Not yet implemented")
}
}
Theoretically it should be possible that the I generic can be resolved by the compiler without the additional declaration because it's provided by BaseClassImpl. So MyInterface<BaseClassImpl> should already provide enough information to resolve the necessary generic for someMethod().
Is there any way to achieve that in Kotlin?
It's impossile in Kotlin.
Language specification states:
There are two kinds of type inference supported by Kotlin.
Local type inference, for inferring types of expressions locally, in statement/expression scope;
Function signature type inference, for inferring types of function return values and/or parameters.
It can't infer type of one generic parameter based on the type of another (especially for supertype declaration, because it is a very base for building type constrains system).
You may declare typealiases (for each T) to avoid repating I each time you implement this interface:
typealias MyInterfaceForBaseClassImpl = MyInterface<BaseClassImpl, OtherClass>
class Impl : MyInterfaceForBaseClassImpl {
override fun someMethod(param: OtherClass) : BaseClassImpl {
//...
}
}
It is not about compiler resolving, but about enforcing, when you declare interface MyInterface<T : BaseClass<I>, I : OtherClass> , declaration expects two parameters, May be you can create OtherInterface with OtherClass embedded and use it while implementing instead of MyInterface
interface BaseClass<I: OtherClass>
interface OtherClass
interface MyInterface<I : OtherClass, T: BaseClass<I>> {
fun someMethod(param: I)
}
class BaseClassImpl: BaseClass<OtherClass>
interface OtherInterface<T: BaseClass<OtherClass>> : MyInterface<OtherClass, T>
class Impl : OtherInterface<BaseClassImpl> {
override fun someMethod(param: OtherClass) {
}
}

Make a function execute only in Kotlin interfaces?

If I have an interface, is there any easy way I can declare a function to make it a public member, but non-overridable? Meaning, it would be exclusively callable and could not be set or overridden by its descendants
interface IFoo {
fun ExecuteOnly(){
// Do Something
}
}
I read a book recently by CommonsWare where this situation was described.
and I quote it from there:
"... As a result, anything in an interface hierarchy is permanently open , until you start
implementing the interfaces in classes. If that is a problem — if you have some
function that you really want to mark as final — use abstract classes, not interfaces..."
You can define an extension function on the interface.
fun IFoo.executeOnly() {
}
It will still be possible for someone to define a member function with that name in a class implementing IFoo but the intention is quite clear. And anyway when using an object via a IFoo reference the IFoo extension will be chosen.
No, you cannot. That's not how Kotlin's interface is implemented.
You can use an abstract class instead
abstract class Foo {
fun executeOnly(){
// Do Something
}
}
Ofcourse You Can... Actually there is not much difference bw kotlin interfaces and abstract classes... simply add a body and a private modifier..
interface MyInterface {
fun triggerTakeMe(){
takeMe()
}
private fun takeMe(){
println("Taken")
}
}
class MyClass : MyInterface
fun main() {
val obj = MyClass()
obj.triggerTakeMe()
}

What does 'by' keyword do in Kotlin?

While developing for android I sometimes come across something that looks like this:
var someModel: someViewModel by notNullAndObservable { vm ->
...
}
I don't understand what the significance of the by keyword is.
In simple words, you can understand by keyword as provided by.
From the perspective of property consumer, val is something that has getter (get) and var is something that has getter and setter (get, set). For each var property there is a default provider of get and set methods that we don't need to specify explicitly.
But, when using by keyword, you are stating that this getter/getter&setter is provided elsewhere (i.e. it's been delegated). It's provided by the function that comes after by.
So, instead of using this built-in get and set methods, you are delegating that job to some explicit function.
One very common example is the by lazy for lazy loading properties.
Also, if you are using dependency injection library like Koin, you'll see many properties defined like this:
var myRepository: MyRepository by inject() //inject is a function from Koin
In the class definition, it follows the same principle, it defines where some function is provided, but it can refer to any set of methods/properties, not just get and set.
class MyClass: SomeInterface by SomeImplementation, SomeOtherInterface
This code is saying:
'I am class MyClass and I offer functions of interface SomeInterface which are provided by SomeImplementation.
I'll implement SomeOtherInterface by myself (that's implicit, so no by there).'
In the Kotlin reference you will find two uses for by, the first being Delegated Properties which is the use you have above:
There are certain common kinds of properties, that, though we can implement them manually every time we need them, would be very nice to implement once and for all, and put into a library. Examples include lazy properties: the value gets computed only upon first access,
observable properties: listeners get notified about changes to this property,
storing properties in a map, not in separate field each.
Here you delegate the getter/setter to another class that does the work and can contain common code. As another example, some of the dependency injectors for Kotlin support this model by delegating the getter to receiving a value from a registry of instances managed by the dependency injection engine.
And Interface/Class delegation is the other use:
The Delegation pattern has proven to be a good alternative to implementation inheritance, and Kotlin supports it natively requiring zero boilerplate code. A class Derived can inherit from an interface Base and delegate all of its public methods to a specified object
Here you can delegate an interface to another implementation so the implementing class only needs to override what it wants to change, while the rest of the methods delegate back to a fuller implementation.
A live example would be the Klutter Readonly/Immutable collections where they really just delegate the specific collection interface to another class and then override anything that needs to be different in the readonly implementation. Saving a lot of work not having to manually delegate all of the other methods.
Both of these are covered by the Kotlin language reference, start there for base topics of the language.
The syntax is:
val/var <property name>: <Type> by <expression>.
The expression after by is the delegate
if we try to access the value of property p, in other words, if we call get() method of property p, the getValue() method of Delegate instance is invoked.
If we try to set the value of property p, in other words, if we call set() method of property p, the setValue() method of Delegate instance is invoked.
Delegation for property:
import kotlin.reflect.KProperty
class Delegate {
// for get() method, ref - a reference to the object from
// which property is read. prop - property
operator fun getValue(ref: Any?, prop: KProperty<*>) = "textA"
// for set() method, 'v' stores the assigned value
operator fun setValue(ref: Any?, prop: KProperty<*>, v: String) {
println("value = $v")
}
}
object SampleBy {
var s: String by Delegate() // delegation for property
#JvmStatic fun main(args: Array<String>) {
println(s)
s = "textB"
}
}
Result:
textA
value = textB
Delegation for class:
interface BaseInterface {
val value: String
fun f()
}
class ClassA: BaseInterface {
override val value = "property from ClassA"
override fun f() { println("fun from ClassA") }
}
// The ClassB can implement the BaseInterface by delegating all public
// members from the ClassA.
class ClassB(classA: BaseInterface): BaseInterface by classA {}
object SampleBy {
#JvmStatic fun main(args: Array<String>) {
val classB = ClassB(ClassA())
println(classB.value)
classB.f()
}
}
Result:
property from ClassA
fun from ClassA
Delegation for parameters:
// for val properties Map is used; for var MutableMap is used
class User(mapA: Map<String, Any?>, mapB: MutableMap<String, Any?>) {
val name: String by mapA
val age: Int by mapA
var address: String by mapB
var id: Long by mapB
}
object SampleBy {
#JvmStatic fun main(args: Array<String>) {
val user = User(mapOf("name" to "John", "age" to 30),
mutableMapOf("address" to "city, street", "id" to 5000L))
println("name: ${user.name}; age: ${user.age}; " +
"address: ${user.address}; id: ${user.id}")
}
}
Result:
name: John; age: 30; address: city, street; id: 5000