This topic is one of the most important we’ll cover in this course! Maybe we’ve said that before? But we really mean it this time. Interfaces are everywhere in computer science, and Kotlin provides a great way to start understanding what they are and how they work. So let’s do it!
abstract
abstract
But first, a short but important digression into one of the Kotlin keywords that we have not yet covered: abstract
.
(Break out your Kotlin keyword bingo cards!)
Like final
, abstract
can be applied to both classes and methods, with somewhat different results.
Let’s explore together:
We’ll return to abstract
in a minute.
But for now let’s move on!
This lesson focuses on interfaces. Like references, interfaces are ubiquitous in computer science. But let’s look at the Wikipedia definition together:
In computing, an interface is a shared boundary across which two or more separate components of a computer system exchange information. The exchange can be between software, computer hardware, peripheral devices, humans, and combinations of these. Some computer hardware devices, such as a touchscreen, can both send and receive data through the interface, while others such as a mouse or microphone may only provide an interface to send data to a given system.
Just to be clear—while interfaces have a specific meaning in Kotlin that we’re exploring, every Kotlin object has an interface. Let’s see how:
As we’ve pointed out in the past, Kotlin objects can only inherit from one class. This can lead to some problems as we design our classes.
Let’s consider a real example: natural ordering. Some classes has a natural ordering, meaning that there is a well-established order. For example:
String
s, lexicographic (or dictionary) order is a natural orderingHowever, not every class has such an ordering.
For example, it’s not clear that the Pet
classes we’ve been creating have a natural ordering.
So this is an example of a feature that not every Kotlin object has, meaning that we shouldn’t add it to Any
.
But whether or not an object can implement this feature doesn’t seem like it should constrain what it extends.
Where does that leave us?
interface
interface
Kotlin interface
s provide a way for classes to declare that they support certain functionality.
Unlike inheritance, a single class
can implement more than one interface
, while still extending another class.
Let’s see how this works!
interface
Referencesinterface
ReferencesReference variables work similarly with classes that implement interfaces as they do with polymorphism and inheritance. Let’s look at an example:
abstract
?abstract
?We can achieve something similar to interfaces using abstract
, but it’s not quite the same.
Let’s examine the differences:
Comparable
Comparable
As we begin with interfaces, we’ll focus on using them first, and then discuss more about how to provide existing interfaces.
Let’s look at one example of a useful built-in Kotlin interface: Comparable
.
OurComparable
OurComparable
Kotlin’s Comparable
interface is inherited from Java, as is what is called a parameterized interface.
We’ve discussed type parameters previously, but we don’t want to tangle with them on interfaces quite yet.
So, instead, when we work with Comparable
we’ll use our own version called OurComparable
:
This works identically to the official Comparable
interface except without the
type parameter.
compareTo
compareTo
Remember that when we implemented .equals
, Kotlin would call it when comparing
two objects for equality using the ==
operator:
Well, it turns out that if we implement compareTo
Kotlin will also call it
when comparing two objects for order using operators like <
!
We just have to do a bit more work to set up the method correctly.
Let’s see how!
OurComparable
ExampleOurComparable
ExampleNow, let’s write some code together that uses the OurComparable
interface to make an existing (simple) algorithm more generic.
Create a method named max
.
max
should accept an array of objects that implement OurComparable
and return the maximum.
Require that the array be non-empty.
As a reminder, compareTo
returns a negative integer, zero, or a positive integer as this object is less than,
equal to, or greater than the passed object.
Kotlin also allows you to use comparison operators directly with classes that implement compareTo
.
OurComparable
works exactly the same as the official Comparable
interface, except it is slightly simplified
and does not accept a type parameter.
Create a method named isSorted
.
isSorted
accepts a list of OurComparable
s and returns true
if the list is sorted in ascending order and
false
otherwise.
If the passed list is empty you should throw an IllegalArgumentException
.
As a reminder, compareTo
returns a negative integer, zero, or a positive integer as this object is less than,
equal to, or greater than the passed object.
OurComparable
works exactly the same as the official Comparable
interface, except it is slightly simplified
and does not accept a type parameter.
Need more practice? Head over to the practice page.