Share
Explore

Kotlin Interfaces: Lecture and Lab Guide

Interfaces are directives that you MUST do something.
But how you do it is up to you as the programming.
They enable design driven programming.
Team A, Team B: Team B can write classes which will work with Team A’s classes (even if Team A has not written those classes yet: ) BECAUSE the Information Architecture running the project published a Library of Interfaces which various catagories of Classes must IMPLEMENT:

// Define a base class for Feline open class Feline { open fun roam() { println("The Feline is roaming in its natural habitat.") }

open fun sleep() { println("The Feline is sleeping.") } }
// Define a subclass of Feline for Lions class Lion: Feline() { override fun roam() { super.roam() println("The Lion is roaming in the savannah.") }
override fun sleep() { super.sleep() println("The Lion sleeps under the shade of a tree.") }
fun roar() { println("The Lion roars loudly, asserting its dominance.") } }
// Define a subclass of Feline for Tigers class Tiger: Feline() { override fun roam() { super.roam() println("The Tiger stealthily moves through the dense jungle.") }
override fun sleep() { super.sleep() println("The Tiger sleeps in a quiet, secluded spot.") }
fun hunt() { println("The Tiger hunts its prey, showcasing its prowess.") } }
// Main function to demonstrate the behavior of Lions and Tigers fun main() { val lion = Lion() lion.roam() lion.sleep() lion.roar()
val tiger = Tiger() tiger.roam() tiger.sleep() tiger.hunt() }
Introduction to Kotlin Interfaces
- Kotlin interfaces are used to define a contract for classes.
They can contain abstract methods - meaning method signature is provided but NOT the implementation. The programmer writing the class which implements the Interface must provide the implementation : how they do that is up to them, according to the runtime needs of how that object will work}
as well as implementations for some methods, but they cannot store state
Defining Interfaces
- To define an interface in Kotlin, use the `interface` keyword - **Example**: ```kotlin interface MyInterface { fun bar() fun foo() { // optional body } } ```
Implementing Interfaces
Applying multiple interfaces to a class is the Java/Kotlin way to achieve multiple inheritance.
- A class or object can implement one or more interfaces by providing concrete implementations for all of its abstract methods.
- **Example**: ```kotlin class Child : MyInterface { override fun bar() { /* body */ } } ```
### Properties in Interfaces
- Interfaces can declare properties that must either be abstract or provide implementations for their accessors. These properties cannot have backing fields.
- **Example**: ```kotlin interface MyInterface { val prop: Int // abstract val propertyWithImplementation: String get() = "foo" } ```
Interface Inheritance
- One interface can derive from another, adding new properties or methods.
Classes implementing such an interface must define all the missing implementations.
- **Example**: ```kotlin interface Named { val name: String } interface Person : Named { override val name: String get() = "John Doe" } ```
Resolving Overriding Conflicts
- When a class implements multiple interfaces that define the same method, Kotlin requires that the class provides an explicit implementation for the method.
- **Example**: ```kotlin class C : A, B { override fun callMe() { super<A>.callMe() super<B>.callMe() } } ```
Lab: Implementing and Extending Kotlin Interfaces
### Objective
Through this lab session, you will gain hands-on experience with Kotlin interfaces, learning how to define, implement, and extend them.
### Setup
Ensure you have Kotlin set up on your machine. You may use IntelliJ IDEA or any other Integrated Development Environment (IDE) that supports Kotlin.
### Exercises
1. **Define and Implement an Interface** Create an interface named `Vehicle` with two methods: `start()` and `stop()`. Then, implement this interface in a class named `Car`, providing concrete implementations for the methods.
2. **Adding Properties to Interfaces**
Extend the `Vehicle` interface by adding a read-only property `name` of type `String`. Implement this property in the `Car` class.
3. **Interface Inheritance**
Define a new interface `ElectricVehicle` that inherits from `Vehicle`. Add a method `chargeBattery()` to `ElectricVehicle`. Implement this interface in a class named `ElectricCar`.
4. **Resolving Conflicts**
Create two interfaces, `A` and `B`, each with a method `greet()`. Then, create a class `Greeting` that implements both interfaces and resolves the conflict by printing a custom message.
### Completion Criteria
- Successfully define and implement all specified interfaces. - Demonstrate the ability to add and implement properties in interfaces. - Show understanding of interface inheritance and successfully implement an inherited interface. - Correctly resolve conflicts arising from multiple interface implementation.

Remember, the goal of this lab is to familiarize yourself with Kotlin interfaces, their implementation, and practical uses in real-world scenarios.

Hhow Interfaces deliver multiple inheritance in KOTLIN


In Kotlin, while a class cannot inherit from multiple classes (as Kotlin does not support multiple inheritance of classes), it can implement multiple interfaces.
This capability allows Kotlin to achieve a form of multiple inheritance through interfaces. Here's how interfaces can be used to provide multiple inheritance-like functionality:

Example 1: Implementing Multiple Interfaces in a Single Class


// Define two interfaces with different functionalities
interface Walker {
fun walk()
}

interface Swimmer {
fun swim()
}

// Implement both interfaces in a single class
class Duck : Walker, Swimmer {
override fun walk() {
println("Duck is walking")
}

override fun swim() {
println("Duck is swimming")
}
}

fun main() {
val duck = Duck()
duck.walk() // Outputs: Duck is walking
duck.swim() // Outputs: Duck is swimming
}

In this example, the Duck class implements two interfaces: Walker and Swimmer. Each interface has its own method, and Duck provides the implementation for both. This allows Duck to inherit behavior from multiple sources.

Example 2: Using Interfaces for Polymorphism

kotlinCopy code
interface Flyer {
fun fly()
}

interface Diver {
fun dive()
}

class Seagull : Flyer, Diver {
override fun fly() {
println("Seagull is flying")
}

override fun dive() {
println("Seagull is diving")
}
}

fun testAbilities(bird: Any) {
when (bird) {
is Flyer -> bird.fly()
is Diver -> bird.dive()
}
}

fun main() {
val seagull = Seagull()
testAbilities(seagull) // Outputs: Seagull is flying and then Seagull is diving
}

Here, Seagull implements two interfaces, Flyer and Diver. This example also demonstrates polymorphism, where the function testAbilities can accept any object and perform actions based on the implemented interfaces.

Example 3: Complex Interface Implementation

kotlinCopy code
interface Vegetarian {
fun eatPlants()
}

interface Carnivore {
fun eatMeat()
}

class Bear : Vegetarian, Carnivore {
override fun eatPlants() {
println("Bear eats plants")
}

override fun eatMeat() {
println("Bear eats meat")
}
}

fun main() {
val bear = Bear()
bear.eatPlants() // Outputs: Bear eats plants
bear.eatMeat() // Outputs: Bear eats meat
}

In this example, the Bear class implements both Vegetarian and Carnivore interfaces, thus simulating a scenario where a single class can inherit features from multiple sources, analogous to multiple inheritance.
Through these examples, you can see how Kotlin uses interfaces to enable a class to inherit multiple sets of behaviors from different interfaces, overcoming the limitation of single inheritance of classes.
ChatGPT can make mistakes. Consi

Exercise: Write a program show casing Abstract Classes, Interfaces, Inheritance and Composition in KOTLIN.

Use the program code to tell the story of the Animals in the Jungle.

One day, the LION King wanted to take a 1 year sabbatical to go and study Zen Meditation and Martial Arts in the Shinto Monastery in Japan. He held a meeting with representatives of the other families in the Jungle to decide how the affairs of the jungle should be administered in his Absence. What happened next will surprise you...
image.png
In this Kotlin program, we'll use abstract classes, interfaces, inheritance, and composition to tell the story of the animals in the jungle when the Lion King decides to take a sabbatical.

The program will showcase various OOP principles in a fun and illustrative manner.

// Define an abstract class 'Animal' to represent common properties and functions of
// animals
abstract class Animal(val name: String) {
abstract fun speak(): String
}

// Define an interface 'Leader' to represent leadership behavior
interface Leader {
fun makeDecision(): String
}

// Lion class inherits from Animal and implements Leader
class Lion(name: String) : Animal(name), Leader {
override fun speak() = "Roar! I am $name, the Lion King."

override fun makeDecision() = "I delegate my duties to the Council of Animals."
}

// Elephant class inherits from Animal and can potentially be a leader
class Elephant(name: String) : Animal(name), Leader {
override fun speak() = "Trumpet! I am $name, the wise Elephant."

override fun makeDecision() = "I will ensure peace in the jungle."
}

// Monkey class just inherits from Animal
class Monkey(name: String) : Animal(name) {
override fun speak() = "Chatter! I am $name, the playful Monkey."
}

// CouncilOfAnimals class demonstrates composition
class CouncilOfAnimals(private val members: List<Animal>) {
fun holdMeeting() {
println("Jungle Meeting is in session!")
members.forEach { println(it.speak()) }
}

fun makeGroupDecision() {
val leader = members.filterIsInstance<Leader>().random()
println("Decision by ${leader.name}: ${leader.makeDecision()}")
}
}

fun main() {
val lionKing = Lion("Leo")
val wiseElephant = Elephant("Ella")
val playfulMonkey = Monkey("Momo")

println(lionKing.speak())
println("Lion King's decision: ${lionKing.makeDecision()}")

// Create a council of animals with different representatives
val animalCouncil = CouncilOfAnimals(listOf(wiseElephant, playfulMonkey))

// Lion King takes a sabbatical
animalCouncil.holdMeeting()
animalCouncil.makeGroupDecision()
}

In this story:
The Animal abstract class represents the common characteristics of animals. Each animal must define its own way of speaking (speak method).
The Leader interface represents the ability to make decisions, which is a trait not all animals have.
The Lion class extends Animal and implements Leader, showcasing both inheritance and interface implementation. When Lion King, Leo, decides to take a sabbatical, he delegates his duties to a council.
The Elephant and Monkey classes extend Animal. Elephant (Ella) also implements Leader, potentially taking on leadership roles.
The CouncilOfAnimals class demonstrates composition. It is composed of a list of Animal objects and can hold meetings and make decisions. It selects a random leader from its members to make a decision.
Through this program, we demonstrate the concepts of abstract classes, interfaces, inheritance, and composition in Kotlin in an engaging and narrative-driven manner.

Describe how this line "val leader = members.filterIsInstance<Leader>().random()" interacts with the rest of the program


The line val leader = members.filterIsInstance<Leader>().random() from the CouncilOfAnimals class plays a crucial role in demonstrating polymorphism and the use of interfaces in Kotlin. Let's break down how this line interacts with the rest of the program:
Context: This line of code is part of the makeGroupDecision function within the CouncilOfAnimals class, which is designed to make a decision on behalf of the jungle's animal community in the absence of the Lion King.
Functionality:
members: This refers to the list of Animal objects that are part of the CouncilOfAnimals. The members list is diverse and can contain any animal that extends the Animal class.
filterIsInstance<Leader>(): This is a Kotlin standard library function that filters the members list to include only those elements that implement the Leader interface. In this story, both Lion and Elephant implement the Leader interface, so they would be included in the filtered list if they are part of members.
random(): This function randomly selects an element from the filtered list. The randomness introduces an element of unpredictability as to who will make the decision in the Lion King's absence.
Interaction with Other Components:
The selected leader (either an instance of Lion or Elephant in this scenario) is then used to call the makeDecision method, as both these classes implement the Leader interface and provide their own implementation of this method.
This demonstrates polymorphism where the exact type of leader (Lion or Elephant) is not known at compile time. The decision-making process is dynamically determined at runtime based on which Leader instance is randomly chosen.
This approach aligns with the story's plot, where the Lion King, who usually makes decisions for the jungle, delegates his authority to the Council of Animals during his sabbatical. The council, in turn, randomly selects a leader from its members to make a decision.
In summary, this line effectively demonstrates key object-oriented programming principles in Kotlin, such as polymorphism and interface usage, by dynamically selecting a leader from the council members who can make decisions, thus continuing the governance of the jungle in the Lion King's absence.


Describe what is going on in this line: class CouncilOfAnimals(private val members: List<Animal>)


The line class CouncilOfAnimals(private val members: List<Animal>) in Kotlin is the declaration of a class named CouncilOfAnimals. Let's dissect this line to understand each part:
Class Declaration: class CouncilOfAnimals declares a new class named CouncilOfAnimals. This is the standard syntax for defining a class in Kotlin.
Primary Constructor: The part within the parentheses (private val members: List<Animal>) is the primary constructor of the CouncilOfAnimals class. In Kotlin, the primary constructor is part of the class header.
Constructor Parameter:
private val members: This defines a parameter for the constructor. The use of private val signifies that members is a read-only (immutable) property of the class and is private to the class.
List<Animal>: This indicates that the members parameter is a list of Animal objects. List<Animal> is a generic collection in Kotlin, where Animal is the type of objects that the list will hold. In this context, it means that the members list can contain any objects that are instances of the Animal class or any of its subclasses.
Encapsulation: The private keyword in private val members ensures encapsulation. It restricts the visibility of the members property to within the CouncilOfAnimals class only. This means that the list of members cannot be accessed directly from outside the CouncilOfAnimals class, adhering to the principles of encapsulation in object-oriented programming.
Purpose in the Program: In the context of the provided program story, the CouncilOfAnimals class represents a council formed by the animals in the jungle. The members list holds the representatives of different animals who are part of this council. The class likely contains methods (like holdMeeting and makeGroupDecision) that utilize this list to perform operations relevant to the council, such as holding meetings or making decisions on behalf of the animal kingdom.
This line defines the CouncilOfAnimals class with a primary constructor that takes a private, immutable list of Animal objects as its members. This design allows for encapsulation and flexibility in representing a council composed of various animals in the jungle.


To illustrate the execution of the provided Kotlin program from start to end, let’s list the method call interactions and associated data field passing:

Want to print your doc?
This is not the way.
Try clicking the ⋯ next to your doc name or using a keyboard shortcut (
CtrlP
) instead.