Welcome back.
And this video we are going to look into interfaces and interfaces are a feature which allow us to extend
the functionality of classes.
So, for example, our car class could extend the functionality of an interface that has certain features,
and let's go ahead and just create such an interface.
So if this interface prepared here, which is called drivable, it has one value, which is a double
value called max speed.
Then it has a function called drive of type string, so it's going to return a string.
But there is no implementation of the function, so it just doesn't have a function.
Body only has to head of the function.
And then we have a brake function, which actually has a function body as well.
So an interface may provide a default implementation of some or all of its properties and functions,
but it doesn't have to.
And if a property or function has a default implementation, the class that uses this interface may
choose to override it.
What does that mean?
Well, let's say we have this interface drivable right in there.
We have these functions and this property.
Now, if our class car decides to extend the functionality of the drivable interface.
Then it needs to implement the property that is created in the interface, but is not implemented.
So here we need to go ahead and say, wow, max speeds of type double should be in there.
And because of your overriding something, so we are overriding the next speed from here.
We need you at the keyword override that by itself doesn't make our class happy yet, as you can see,
it's still not happy, it's still complaining something is still missing.
And that is because we haven't implemented a member called Drive.
So here's this drive function, and because it doesn't have a function body, we need to create one
in the class that extends the interface.
So we need to go ahead and create a drive function.
So you can see we are already creating a drive function.
Why is it still complaining?
While this drive function doesn't follow the same structure.
So you can see the head of the function doesn't return a string.
So let's go ahead and actually do that.
So override fun drive.
And once again, fun drive.
And you can see it gives me some help here, the idea.
But it requires me to implement something.
So I need to add a return statement here so I can, of course, go ahead and return.
Driving the interface drive.
OK, so that's just going to be the text that I return.
Alternatively, what you could have done is you could have done it in a shorter way, for example,
just saying.
That it's going to return whatever the string is.
OK.
So both of them are fine.
I can see this version is also fine.
It's just a shorter version of this here.
All right, so now we have multiple drive functions, and that is already starting to become confusing,
maybe.
But no worries.
The one drive that we have here is actually the drive that comes from our interface that we are extending,
OK?
So.
You can see here this drive.
We implemented it and suddenly our car is not complaining anymore, then going back to our other drive
that we have created, it's an open function drive, which is, so to speak, new.
So this is the lowest level in which it's defined and that is in our class car.
So this is another drive which we, of course, can override from other classes that inherit our car.
Now, if electric car wants to inherit from car, it also has to follow the structure of our.
Interface here.
So let's also add.
A Max Meteor.
And let's use it here as well.
Now, of course, our function drive that we had in our electric car that we created doesn't work anymore
because now this drive.
Is trying to override, so it thinks that we are trying to override the drive function.
Which comes from here.
This one.
OK, so we also need to follow the structure of drive.
Now, let's add the over right keyword, but then we also need to return the string type.
And of course, here return.
And we can use the same structure that we had before, or at least the same string that we are returning
here.
So what is an interface?
Well, an interface is essentially a contract that a class may choose to sign.
If it does, the class is obliged to provide implementations of the properties and functions of the
interface.
OK, so we see that here because our class car is extending the interface drivable.
It's now obliged to implement its.
Variables and functions or its properties and functions.
The properties we did that by using it in the primary constructor and to function well, we implemented
it directly here.
You can also see, because our break had already an implementation, we never had to use it, but we
can of course use it.
We can even use it and a subclass here.
So in the subclass of our car, in the electric car, we can still go ahead and implement brake so it
can see override brake.
And you can see this super keyword and that is to call the brake function of the superclass.
And because our superclass, which is our car, didn't implement the functionality for brake, it will
use the one from the interface.
So it will just use this brake here.
So now, if I go ahead and call break, and by the way, now of course, we are missing things when
creating those Audi A3 and so forth.
And I think it was speed, right?
So 200 kilometers, I'd say, is the top speed here and 240 is going to be the top speed of the electric
car and the errors disappear.
But now which driver would be called when we called this drive?
Well, if we look at it, one requires a distance, the other one doesn't.
So it's going to call this drive.
And then this year is, of course, going to require the distance, so it's going to call.
This drive here.
All right, now, let's say we want to call the brake function here.
All right, let's just test it.
Let's go ahead and use Tesla as the brake.
And let's use already a three break.
And here, of course, it's a break.
So I'm going to get rid of the other calls here just to keep it simple.
And let's actually run it here.
And we will see that it says that drivable is breaking in both cases, so the case for Tesla and Order
three, even though while we're already a three judges of type car never actually implement that the
brake function?
OK, so has it because it automatically inherited from brake.
Now.
What if we implement something here, let's say print line break inside of.
The electric.
Let's test it again.
So you can see the drivable is breaking, and that is our test that.
And then it says break inside of electric car is also our Tesla, and then we have this drivable is
breaking, that's our audio that breaks.
So what is happening?
Well, when using override fun brake.
So Super Brake, what happens is that the super function brake, so whatever was implemented for brake
in the interface or in the superclass will be used or will be executed.
And then on top of that, our own code that we add afterwards will also be executed.
OK, so that is what this super dart method name does.
But away subclasses of a class that implement an interface in this case are electric car are also considered
to be implementing the interface.
OK, I said it in a certain way, but I've never said it specifically like that.
OK, so just so you know, our electric car is also implementing the interface called.
Drivable.
Another site notes an interface can inherit from another interface.
So, yeah, in case you want to create your own interfaces that inherit from other interfaces, you
can do so.
So why would you even use interfaces?
Well, interfaces are super useful when you have certain functions in mind that you definitely want
to be implemented later on and also already know the properties of of a class that you want to then
have implemented, but you don't want to implement them directly.
You just want to prepare everything and you don't want to, for example, create a specific body already
for a function.
All right.
So this is the introduction to interfaces, and in the next video, we're going to look at abstract
classes, which are similar in a certain way to interfaces.
But they have some differences in the nuances as well.
So let's have a look at those.