Problem:
I have a GOD class in my project which consists of more than 40 to 50 functions that belong to different services.
What I want to achieve:
I want to move unique functions to dedicated subclasses and common functions to a parent class. So that all the functions that belong to a particular feature belongs to a dedicated class. Now the GOD class is injected in many classes.
Can someone suggest me a design pattern where I don’t have to individually inject all these SubClass but a factory which will give the instances of these SubClasses and also provide access to the common functions which are in the parent class. Is it possible?
class GodClass {
fun common(){}
fun a(){}
fun b(){}
fun c(){}
fun d(){}
}
abstract class ParentClass {
fun common(){}
}
class SubClass1: ParentClass {
fun a(){}
fun d(){}
}
class SubClass2: ParentClass {
fun b(){}
fun c(){}
}
Related
abstract class ServerMock(param: String) {
protected var someVar = params + "123"
fun justMyVar() = someVar
}
Usage example:
class BaseServer(param: String) : ServerMock(param) {
val y = someVar
}
Can this class be marked as open and not abstract?
What is the difference between open and abstract class?
abstract class cannot be instantiated and must be inherited, abstract classes are open for extending by default. open modifier on the class allows inheriting it. If the class has not open modifier it is considered final and cannot be inherited.
You can not instantiate an abstract class. You either need to subclass or create an anonymous class using object. In abstract classes you can just declare function without implementing them (forcing the subclass to imlement them) or provide a default implementation.
abstract class BaseClass {
fun foo() // subclasses must implement foo
fun bar(): String = "bar" // default implementation, subclasses can, but does not have to override bar
}
// error: can not create an instance of an abstract class
val baseClass = BaseClass()
class SubClass : BaseClass {
// must implement foo
override fun foo() {
// ...
}
// can, but does not need to override bar
}
// declaring an anonymous class (having no name) using object keyword
val baseClass: BaseClass = object : BaseClass {
// must implement foo
override fun foo() {
// ...
}
// it is optional implementing bar
override fun bar(): String {
return "somethingElse"
}
}
A class that is neither abstract nor open is considered to be final and can not be extended.
If you want to allow subclassing you should mark it open.
class AClass
// error: This type is final, so it can not be inherrited from.
class BClass : AClass
open class CClass
class DClass : CClass
So if you want to allow BaseServer to be subclassed you should mark it open. If you also want to declare functions, but force subclasses to implement them you can replace open with abstract.
Documentation
Kotlin Abstract Classes
Kotlin Inheritance (incl. open)
Imagine you have 2 classes
Class Person [parent class]
Class Coder [sub/child class]
When you want to inherit Coder from Person you have to make Person open, so it is available to inherit from.
Meanwhile you can make objects from Person itself.
When you don't need to make objects from parent class(in our case it's Person) or you don't see any meaning creating objects from it you can use abstract instead of open.
It works the same way as open does. But the main difference is that you cannot make objects from Person(parent class) anymore.
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()
}
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)
}
I'm aware of two differences between Abstract classes and Interfaces in Kotlin:
An abstract class can have state (e.g. var...)
A class can implement multiple interfaces, but not multiple abstract classes.
Since Kotlin is a rather fresh language, I wonder why Abstract Classes were not abandoned? Interfaces seem superior tool, with a very little need for Abstract Classes.
To elaborate: Kotlin does support concrete function implementation in interfaces, e.g.:
interface Shiny {
fun shine(amount : Int) // abstract function
fun reflect(s : String) { print ("**$s**") } // concrete function
}
Can someone provide a strong practical example of the need for Abstract Classes?
The practical side of abstract classes is that you can encapsulate a part of implementation that works with the state, so that it cannot be overridden in the derived classes.
In an interface, you can only define a property without a backing field, and an implementation class must override that property (with either a backing field or custom accessors).
Given that, you cannot define logic that stores some state in an interface in a reliable way: an implementation class might override the properties in an unexpected way.
Example:
interface MyContainer {
var size: Int
fun add(item: MyItem) {
// ...
size = size + 1
}
}
Here, we provide a default implementation for add that increments size. But it might break if an implementing class is defined like this:
class MyContainerImpl : MyContainer {
override val size: Int
get() = 0
set(value) { println("Just ignoring the $value") }
}
On contrary, abstract classes support this use case and thus allow you to provide some guarantees and contract for all their implementations: they can define some state and its transitions that will stay the same in a derived class.
Apart from that, abstract classes can have non-public API (internal, protected) and final members, whereas interfaces cannot (they can only have private members, which can be used in the default implementations), and all their default implementations can be overridden in the classes.
Abstract classes exist essentially for a hierarchy of classes. For example, if the abstract parent class had a concrete function that was also defined in the child class which extends the parent class, then in certain cases it would be necessary to call the parent's function. When you use an interface it is impossible to do so due to the entirely abstract nature of the class.
Trait delegation is described in docs, and there are no questions. But what about class delegation?
class FrameWorkClass // Third party class we cannot modify
class MyDerivedFrameWorkClass(c:FrameWorkClass) : FrameWorkClass by c
What is the best way to achieve this without modifying FrameWorkClass? Obviously we are unable to make it implement our interface.
You can only delegate an interface to a variable that implements that interface. You cannot delegate directly to another class. As #Damian was pointing out; basically is simplified as:
interface Framework {}
class FrameWorkImpl: Framework {}
class MyDerivedFrameWorkClass(val fw: FrameWorkImpl) : Framework by fw {}
Or you can generically say:
class MyDerivedFrameWorkClass(val fw: Framework) : Framework by fw {}
to accept any implementation of the Framework interface and delegate to it, so FrameworkImpl and FrameworkHappyDays both work if they implement the Framework interface.
This is updated to current Kotlin, where trait has been renamed to interface
At the moment only traits can be delegated like this. If you have a class that you would like to delegate, I would simply take that class and extract a trait(interface) including all the methods you are interested in. Here is an example based on your code.
Imagine you have these classes:
class FrameWorkClass {
fun foo() {}
fun boo() {}
}
class MyDerivedFrameWorkClass(c:FrameWorkClass) : FrameWorkClass by c
It does not compile right? Let's say you are interested in foo()
trait FrameWorkTrait {
fun foo() {}
}
class FrameWorkClassImpl: FrameWorkTrait {
override fun foo() {}
fun boo() {}
}
class MyDerivedFrameWorkClass(c:FrameWorkTrait) : FrameWorkTrait by c
At least this is how I would do it.