In Kotlin we'll have possibility to create a "trait that may require a class being extended on the call side", like
class Bar {}
trait T1 : Bar {}
class Foo : Bar, T1, T2, T3 {}
class Wrong : T1, T2 //error: Wrong should extend Bar
I can't imagine any flow where I can apply this structure. Can anyone tell me why we need it?
I think the main reason for this is to allow the trait to make use of methods and properties defined in the concrete class. Imagine that Bar had some basic method that other convenience methods could be built on top of... by having the trait require that it be used on subclasses of Bar, you could define methods in the trait that call that method. You could then provide those methods to many subclasses by giving them the trait.
Related
What is the difference between sealed and internal in Kotlin? I have read Kotlin's documentation on sealed classes and visibility modifiers; however, it is still not clear to me when to use sealed vs. internal. Maybe someone could provide real-world code samples?
Sealed classes | Kotlin & Visibility modifiers | Kotlin resources.
sealed class will be visible in all modules, but extendable only in the same module. This means if you have this:
sealed class MyClass {} then you can do this in the same module:
class MyExtensionClass: MyClass() {}
But you can't do the same thing in another module. But you can still use both MyClass and MyExtensionClass in another module.
For example you can do this in another module:
val x: MyClass = MyExtensionClass()
You can't instantiate a sealed class directly neither in the same or another module. This means you can't do this nowhere:
val x = MyClass()
So sealed class is basically an abstract class which can only be implemented in the same module.
internal class can be used and extended in the same module just like a sealed class, but you can do neither in another module. So you can't even use or instantiate it in another module. Also you can directly instantiate an internal class as long as you are doing it in the same module.
So: Use sealed to better control extending something. For example you create a library and you want a class from this library to be used but not extended. Use internal if you wan't your class to be invisible to other modules (you create a library, but certain class in this library shouldn't even be directly compile time usable by libraries users)
A good use case for sealed class:
You build a library and have some abstract class or interface which has multiple different implementations, but you want to make sure the libraries user doesn't add its own implementations (you wan't to be in control of implementation details).
A good use case for internal class:
You have some interface and a factory that creates implementations, but you don't want the implementing class to be compile-time visible to libraries users. They just use the factory and don't need to worry about the implementation. They might build their own implementation though and therefor not use the factory you provided and this is OK.
These are not mutually exclusive. You can have an internal sealed class as well.
internal is about visibility, and sealed is about inheritance rules.
internal means the class type is only visible within the module. In other modules, you can't even mention the name of the type.
sealed means it is open (can be subclassed), but subclasses (or implementations if it's a sealed interface) can only be defined in the same module, and the compiler keeps track of an exhaustive list of all subclasses. Another rule is that you can't create anonymous subclasses of it (object: MySealedClass). The advantage of a sealed type is that the compiler knows when you've exhaustively checked a type in when statements, if/else chains, etc. It can also be used in a library to ensure that only known implementations of a class or interface are ever passed to it (prevent users from creating subclasses of something and passing them into the library).
Bonus:
Visibility modifier keywords: public, internal, private, protected
Inheritance modifier keywords: open, final, sealed
data and value also cause a class to be final implicitly as a side effect.
Is it possible to write default implementation of equals method in a Kotlin interface?
I have this code:
interface User {
val id: String
}
And I want all the classes implementing User to being compared using id property. Something like this:
interface User {
val id: String
fun equals(other: Any?) : Boolean {
//check type and stuff
return id == other.id
}
}
I know I can (and maybe should) use an abstract class, but I have to deal with this scenario now.
Thank you
No, I'm afraid that's not possible.
If you try your code, the compiler complains that:
'equals' hides member of supertype 'Any' and needs 'override' modifier
And if you add the override modifier:
An interface may not implement a method of 'Any'
The reasons are a bit obscure, and are inherited (!) from Java.
Originally, interfaces could only contain abstract methods (and constant fields). When the ability to specify method implementations in interfaces was added, it was done in a way so as not to break existing code, so they only apply where classes don't already have an implementation. (In Java they're called ‘default’ methods to reinforce that.) If a class has an implementation, either defined within the class or in a superclass, that gets used, and the default is ignored.
There are a few corner cases, though: the methods defined in Object (Java's equivalent of Kotlin's Any). Those are clone(), equals(), finalize(), getClass(), hashCode(), notify(), notifyAll(), toString(), and wait(). (Most of those are rarely used directly these days, but of course equals(), hashCode(), and toString() are very important.)
Because those methods are defined in Object, every class has a direct implementation of them (either from Object or some subclass). And so the interface's default implementation can never be used.
Exactly the same applies to Kotlin/JVM and the corresponding methods defined in Any — in fact, the compiler makes it explicit by giving an error if you try to provide a default implementation of any of those methods, as shown above.
This is a shame, because there are cases where a default implementation of equals(), hashCode(), and/or toString() would be extremely useful! But it would introduce complexity, fragility, and some surprising corner cases; see this answer for an authoritative explanation.
I have access to a library, but I don't want to fork the code and maintain the library, because I am too new to Kotlin.
The code looks like this:
data class Foo<out T: Baz>(val foos: ..., bars: ...)
I can call methods from the library to get back a Foo, but I need that Foo to implement Serializable from java.io. I asked someone how might I do this, and they suggested that I extend from the data class. Is this the right course of action, and if so, how might one go about it?
In Kotlin you can't make class implement interface which it doesn't implement (unlike Haskell and Go).
Sore your options are folowing:
Create your own class implementing Serializable which has all the same fields as basic. Then you can even create constructor in new class which accepts basic class as argument
Use another way of serialization, for example kotlinx.serialization
Let's say I have a Swing GUI that has to display a certain type of information in two different ways. From a design patterns perspective one would probably use the Strategy pattern here: create an interface that defines how the communication between the display component and the client works like this:
public interface Foo {
void showData(Data bar)
}
The real action is then done by different components that implement Foo and can be created and plugged in for doing the real work.
Now, what happens, if the real components are java.awt.Components? As I see it, it results in a mess of type casts because Component is a class. Let's assume an implementation like this one:
public class Baz extends Component implements Foo {
...
}
If I want to pass objects of class Baz around, the methods can either use "Component" as the parameter type or "Foo". The problem is that some methods need objects that are both Component and Foo (e.g. because they add the object to a JPanel and then supply the data calling the interface method showData()).
As I see it I have some choices to make this happen:
I can pass the reference as Component and cast to Foo. Before, I have to check that the reference is an instance of Foo and I have to handle situations where this requirement is not met. Another problem is that I have to communicate to clients of the method that the Component passed also has to implement Foo, which is awkward and error-prone.
I can do the same thing with Foo
I can add a method "Component getComponent()" to the Foo interface and the implementation would always return "this". This boilerplate method could be put into an abstract sub-class of Component. This solution means an interface method I don't want and an additional sub-class I don't need.
I can pass two references, one Component and one Foo reference to the same object. Internally, I'd have to make sure, though, that both references belong to the same object. And I have to deal with situations in which this requirement is not met.
I can use an abstract sub-class of Component and define the interface using abstract methods. This would allow me to pass references in a type-safe manner, but break with good OOP practices: keeping interfaces and implementations separate and also the interface segregation principle.
So, all of these solutions are merely workarounds. Is there any solution I'm missing? What should I do?
I would use the Strategy design pattern as you mentioned, but perhaps in a different context. The problem with trying to "shoe-horn" both Foo and Component into one class is that you could have combinations of implementations that would require duplicating code.
For example, imagine you have the following implementations of Component:
(Its been too long since Ive used Swing, these classes may not exist)
JPanel
JButton
JMenu
And you also had the following implementations of Foo
MyFoo
HisFoo
OurFoo
WhatTheFoo
And Imagine all the combinations of those: that's whats called a class explosion. This is the classic justification for the Strategy pattern.
I would create a sort of container class that uses a HAS-A relationship for each of the needed classes instead of using the IS-A relationship as follows:
(Im a c++ programmer, so you'll have to excuse the hybrid code :)
class ComponentFooHandler {
Component component_;
Foo fooImpl_;
inline Foo getFoo() {return fooImpl_;}
void setFoo(Foo f) {fooImpl_ = f;}
Component getComponent() {return component_;}
void setComponent(Component c) {component_ = c;}
void doAction() {
component_.someAction();
fooImpl_.anotherAction();
}
}
You would then have to create different implementations of Foo seperately. Then the Component and Foo implementations can be combined as needed with out having to duplicate Foo impl code. Notice also that you can call methods that like doAction() that can operate on both Foo and Component without knowing their details, similar to a Template Pattern.
To solve the issues with your original question:
When a Component is needed, call getComponent() on a handler instance
When a Foo is needed, call getFoo() on a handler instance
I would avoid creating methods that need both in one and split the method args into 2
Or just consider passing around a ComponentFooHandler
If I have a Trait that some classes use but not others, how can I test an object to see if it is an instance of a class that uses that Trait? What I want is something like isMemberOf: or isKindOf: but for Traits.
myInstance class traitCompositionIncludes: MyTraitClass