Do abstract classes fall under implementation inheritance or interface inheritance? - oop

I'll start off with describing my understanding of Implementation Inheritance and Interface Inheritance.
Implementation Inheritance can be described as defining a base class with a set of default behavior. We further define more functionality by extending from that base class and adding/overriding functions as needed. Here is an example of such a scenario:
class Entity
func attack():
# attacks
func heal():
# heals
func block():
# block
class Warrior extends Entity
func attack():
# warrior attack
func block():
# warrior block
We can continue to define other classes that override any combination of functions from the base Entity class. One of the drawbacks is that we can have classes that inherit functionality that it may not necessarily need. One way to avoid this is through Interface Inheritance.
With Interface Inheritance, we are inheriting the what instead of the how from a base class.
interface AttackBehavior
func attack()
interface BlockBehavior
func block()
interface HealBehavior
func heal()
class Warrior
var attack_behavior: AttackBehavior
var block_behavior: BlockBehavior
func attack():
attack_behavior.attack()
func block():
block_behavior.block()
class BattleMage
var attack_behavior: AttackBehavior
var heal_behavior: HealBehavior
func attack():
attack_behavior.attack()
func heal():
heal_behavior.heal()
We can see that defining the behaviors as components an object has while also defining unique behaviors through interfaces allows for some flexibility in our implementations.
So my question is as follows, if we have an abstract class such that it only defines state and abstract functions, does that inheriting from this fall under implementation inheritance or interface inheritance? I suppose it could even fall under a completely separate category.
For example lets look at the interface inheritance example and modify it a bit
interface AttackBehavior
func attack()
interface BlockBehavior
func block()
abstract class Warrior
var attack_behavior: AttackBehavior
var block_behavior: BlockBehavior
func attack()
func block()
class Berserker extends Warrior
constructor():
attack_behavior = ChaoticAttackBehavior()
block_behavior = WeakBlockBehavior()
func attack():
attack_behavior.attack()
func block():
block_behavior.block()
In this example, we define a Berserker class that has chaotic attack patterns but weak block behavior. In the constructor, we define the attack_behavior and block_behavior while maintaining the contract of the Warrior class by implementing attack and block.
Does this violate the principles of interface implementation in any way? In the above example, we are still inheriting what a Warrior does instead of how it does it. I worry that I am just splitting hairs at this point but I would appreciate a different perspective on this idea.
For example lets look at the interface inheritance example and modify it a bit
interface AttackBehavior
func attack()
interface BlockBehavior
func block()
abstract class Warrior
var attack_behavior: AttackBehavior
var block_behavior: BlockBehavior
func attack()
func block()
class Berserker extends Warrior
constructor():
attack_behavior = ChaoticAttackBehavior()
block_behavior = WeakBlockBehavior()
func attack():
attack_behavior.attack()
func block():
block_behavior.block()
In this example, we define a Berserker class that has chaotic attack patterns but weak block behavior. In the constructor, we define the attack_behavior and block_behavior while maintaining the contract of the Warrior class by implementing attack and block.
Does this violate the principles of interface implementation in any way? In the above example, we are still inheriting what a Warrior does instead of how it does it. I worry that I am just splitting hairs at this point but I would appreciate a different perspective on this idea.

Related

Breaking down a GOD class to single responsible classes

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(){}
}

Why only interfaces can be delegated to in kotlin?

I have seen few similar questions, but none had explained why delegation is limited to interfaces?
Most of the time in practice we have something that has actually no interface at all, it is a class that implements nothing but provides some functionality or implements an abstract class.
Is there any fundamental limitation that forces this to be limited to interfaces or can we expect kotlin to have unrestricted delegation in the future?
This is especially useful if we want to extend functionality of a class using composition not inheritance.
class A {}
class B(val a: A) : A by a {}
When you delegate an interface, the class does still implement the interface. So for consistency, if you can delegate a class, it should work the same way. I.e.
class A(x: Int) {
fun foo() = x
}
class B(val a: A) : A by a {}
needs to compile to
class B(val a: A) : A {
override fun foo() = a.foo()
}
except this doesn't work:
foo isn't open and can't be overridden.
you need to call a constructor of A. class B(val a: A) : A(a.x) won't help either: x is not a member of A.
What about equals and hashCode: are they delegated? Either decision would lead to weird consequences.

Kotlin: why use Abstract classes (vs. interfaces)?

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.

Class delegation in Kotlin

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.

Interface and Abstract method differences

If interface has 2 method A() And B() and abstract class has also same A() and B() then what
is the different between them?
An interface just provides a skeleton of a class which implements this interface.
A abstract class (which can implement an interface, too) can add some default functionality which (of course) can be overridden in derivated classes.
Take a look at: Interface vs Abstract Class (general OO)
The difference is that classes that implement the interface will be forced to provide their own implementation of these methods, while classes that extend the abstract class will be provided with an implementation of these methods.
Differences:
Assuming A() and B() don't have implementation in abstract class, i.e. only signatures.
In case of the interface A() and B() will only be signatures, i.e. without any implementation and class implementing this interface will have to provide the implementation like this (without keyword override):
returnType AbstractClass.A()
{
// Code here
}
A class implementing Abstract class will have to override the abstract methods like this:
override accessSpecifier returnType A()
{
// Code here
}
override accessSpecifier returnType B()
{
// Code here
}