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
Related
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 = ......
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()
}
I know I can do something like this:
interface ISpecialEnum{/*interace stuff*/}
fun <T> consumeSpecialEnum(enum: T)
where T:Enum<T>, T:ISpecialEnum{
//code
}
to force a function to accept only enums with a specific interface.
Is there anything in kotlin to check if a generic extends a data class? Like:
interface ISpecialDataClass{/*interface stuff*/}
fun <T> consumeSpecialDataClass(dataClass: T)
where T:DataClass<T>, T:ISpecialDataClass{
//code
}
You can check if your type T is a data class (and that it implements your interface) like so:
fun <T> func(param : T) where T : ISpecialInterface {
if (param::class.isData) {
// do stuff
}
}
If you only want to check if it's a data class, you should remove the 'where' clause, however, to ensure that the type T cannot be null, you need to replace fun <T> with fun <T : Any>, as just <T> defaults to <T : Any?>.
In contrast with enums, there is no common supertype for all data classes (excluding Any, which is a common supertype for absolutely all kotlin classes).
So, generally, this check can't be done in compile time (but it is possible in runtime via reflection API).
I have a simple Kotlin interface:
#FunctionalInterface
interface ServiceMethod<T> {
fun doService(): T
}
This, in spite of the name, is essentially identical to Java's Supplier functional interface. The only difference is that I can implement the Supplier, and I can't implement my own.
val supplier = Supplier<String> {
"Hello"
}
val serviceMethod = ServiceMethod<String> {
"Hello"
}
The ServiceMethod implementation gives me a compiler error saying "Interface ServiceMethod does not have constructors." Huh? Of course it doesn't! It's a functional interface.
I know that I can write it as an anonymous inner class:
val serviceMethod = object : ServiceMethod<String> {
override fun doService(): String {
return "Hello"
}
}
But this is much more verbose. In this case I could just use the Supplier interface, but that won't work for other interfaces. I shouldn't have to write an interface in Java, just to be able to a lambda in Kotlin. I'd rather use a lambda for all my Kotlin interfaces, especially since I'll be writing a lot of these. Am I missing something obvious?
Use the fun interface modifier since Kotlin 1.4
In Kotlin 1.3 and earlier, SAM (single abstract method) conversions, where you can instantiate an interface like Supplier using a lambda function, were only supported for Java interfaces.
The language designers originally thought SAM conversions wouldn't be useful for Kotlin interfaces, because a Kotlin function already has a type. For example, the type of your doService function can be written as () -> T. Instead of creating an object that implements an interface, you could simply write:
val serviceMethod: () -> String = { "Hello" }
Kotlin 1.4 adds SAM conversions for Kotlin interfaces, but it doesn't work out of the box for every interface. Instead, you have to apply the special fun modifier to a Kotlin interface to make it eligible for SAM conversion.
In your example, it would simply look like this:
fun interface ServiceMethod<T> {
fun doService(): T
}
With the modifier added, you can create an instance using a lambda exactly as you were hoping in your question.
val serviceMethod = ServiceMethod<String> { "Hello" }
You can learn more in the Kotlin documentation for functional interfaces.
As the title states, I am looking for a way to implement a final (method that cannot be overridden) in a kotlin interface.
So here is my code:
interface NewsItemState {
final fun delete(newsItem: NewsItem) {
validateCanDelete(newsItem)
deleteNewsItem(newsItem)
}
fun validateCanDelete(newsItem: NewsItem)
fun deleteNewsItem(newsItem: NewsItem)
}
And here is my use case:
I want the delete function to be final so that it cannot be
overridden in the implementations of the interface.
I want the
validateCanDelete and deleteNewsItem methods to be overridden in
the implementations of the interface.
Now, I know that this is not possible at the moment and that adding final to a method is not allowed in the interface. I also know that I can achieve this by replacing the interface with an abstract class.
However, I was wondering if there is a way of implementing the same functionality in an interface because my final method is not going to have any "state managing" logic.
While it's not possible to have final methods in interfaces, it's absolute OK to define extension methods for interface types.
interface NewsItemState {
fun validateCanDelete(newsItem: NewsItem)
fun deleteNewsItem(newsItem: NewsItem)
}
fun NewsItemState.delete(newsItem: NewsItem) {
validateCanDelete(newsItem)
deleteNewsItem(newsItem)
}