Welcome back.
In this video we're going to look at promoting code reusability and flexibility.
What we're going to go over where why and how and also when to use interfaces to achieve that.
So let's start with where where would you use interfaces.
Well, when you need different classes to implement the same set of methods or properties, ensuring
consistency and allowing for flexible implementations?
Why would you do that?
Well, this promotes code reusability and flexibility.
Different classes can implement the same interface in various different ways, allowing for diverse
behavior while maintaining a common contract, then coming to when use interfaces when you have multiple
classes that should provide the same functionality, but it might implement it differently.
And then let's go into a real world example a payment processing system.
Imagine you're building an e-commerce platform that supports multiple payment methods such as credit
cards, PayPal, and bank transfer.
Each of those will have a different way as to how it manages the payment.
So let's now build this in a very simple way.
It's going to be a very, very simplified version.
So I'm going to create this interface.
And by the way it makes sense to have these interfaces in separate files.
I'm just putting them all into the same file for educational purposes, in the sense that it's easier
to see everything in one go without having to move between files all the time.
Okay, so we have this interface called I Payment Processor.
And what I want to have is I want to process the payment.
And what do I need?
I need the amount.
So I'm going to say decimal amount.
So this method now is not implemented as we can see.
But we're just saying okay if you want to process the payment, you need to give me the amount that
you want to process.
So the payment amount so to speak.
All right.
Now let's go ahead and create a credit card processor.
So public class credit card processor which is going to implement my payment processor.
And maybe I should call it processor I believe that's the correct English.
So I payment processor.
And then I need to implement its methods okay.
So this process payment.
So what I'm going to say is public void process payment which is the name of that method.
So I can also just copy paste.
Obviously I could have used the IDE to put it in there, but I'm going to do it manually.
And here I'm going to say decimal and it will be the amount okay.
Now let's go ahead and say what should happen in this case.
So I'm just going to say processing credit card payment of the amount, whatever amount is okay.
Whatever the decimal is that we're going to pass.
And then I need to implement the credit card payment logic okay.
We're not going to go into actually implementing the credit card payment logic.
It's really just about the idea of understanding what interfaces do and why code reusability is so useful
here.
Okay.
So then I will have another class.
This time it will be the PayPal processor.
Okay.
So I'm just going to copy this code and rename this PayPal processor which also implements the I payment
processor method.
It also uses the process payment method or implements it.
But now it's going to be the PayPal payment of amount and it implements the PayPal payment logic.
So that's pretty much what our two classes do.
So you see both of them are implementing this interface.
Now obviously our interface could have significantly more methods.
In our case it just has one method.
But it could be dozens of methods right.
So in our case it's simple.
It's really just this one method.
And now we can reuse it.
And there is always the same structure.
It always does return void.
So nothing.
And it always takes in one parameter which is a decimal amount.
So now let's use that interface.
Therefore I'm going to create a new class public class.
And I'm going to call this one payment service okay.
So this payment service and you will see that quite often that classes that implement interfaces are
services.
So this one will have a read only I payment.
Processor.
And you see, because it's private and read only it's an underscore processor.
Okay.
So it's going to process the I payment but only inside of this class.
It is not readable from outside and is also not settable after it's set once because it's a read only
method.
Then I have the constructor here and I'm passing the payment processor here.
So why do I do that?
Well, so that I can set my private read only payment processor here okay.
So at this point I can create a method which I'm going to call process order payment.
And this should be process order payment where I'm passing on a decimal amount.
And here I'm going to use the underscore payment processor.
And I'm going to process the payment with the amount.
All right.
So now let's go ahead and make this method public as well so that we can use it outside of this class
okay.
So everything up to here I think is still okay.
Now let's actually use it.
And that's where it becomes really really interesting.
And that's also where you will see why this code reusability is so cool here.
So therefore I'm going to create an AI payment processor credit card processor which will be a new credit
card processor.
And then I'm going to then I'm going to create a payment service where I'm going to pass the credit
card processor as the argument to the constructor.
And then I can use the payment service dot process order payment with whatever the amount is.
So let's say 100.
And this M is just making sure that it's a decimal okay.
This character M.
So you see we're processing an order payment with the credit card.
Now let's go ahead and do the same thing with PayPal.
So again it will be an AI payment processor.
But this time it's a PayPal processor with a new PayPal processor.
So you see that I'm using this AI payment processor interface to create an object of two different types
or two different classes.
So this is where this inheritance aspect comes in.
Right.
So here you see I called it or it was an AI payment processor.
And we said new PayPal processor.
So we didn't have to use AI payment processor here.
We actually could create a new object of that class PayPal processor which inherits AI payment processor,
which allows us to create objects of AI payment processor that at the same time are PayPal processors.
Because the PayPal processor is inheriting in this case, implementing an interface.
It's not really inheriting, but it's implementing the interface.
So it is similar to what we saw with inheritance earlier.
And this is one other part of polymorphism.
Okay.
So a lot is going on here.
As I said, although it's just a few lines of code, there is a lot going on here.
And then I'm going to use my payment service.
But this time I'm going to pass in the PayPal processor, and then I can use that payment service to
process the order payment with let's say, $200.
So you see that the code is the same.
The only thing that differs is the parameter that I'm passing as to the payment service constructor.
And that is really the power of the reusability.
Here we have this one class that is the service that accepts any type of payment processor, whether
it's PayPal, whether it's credit card, whether it's whatever other tools, paying cash or whatever,
even though that you wouldn't need a coding a code or probably you would, because somebody could come
in with cash and the register would still have to, like, enter it in somehow, and it would still
have to be processed code wise.
But you can see that this AI payment processor doesn't care what kind of class is going to be the processor,
as long as it implements its interface.
So we see that the PayPal processor implements the AI payment processor, and the credit card processor
also implements the AI payment processor, which is why we can now use them interchangeably, which
is why we can use either of those two as the arguments of the constructor of the payment service, which
just said, you know what?
During the creation of my service, so of my class, of my object, of my class, pass me.
I payment processor class or a class that implements the I payment processor.
That's maybe a better way of saying it.
And then you can do the default methods that I have to offer, which is for example, processing the
order payment.
So you see here also processing the order payment inside of our payment service.
We never specifically specified how that should happen because that is something that is defined inside
of the processor.
Who is the processor?
The processor is whoever we pass to the payment service object when we are creating it.
So if we are passing the PayPal processor, then this method will be called.
And if we're passing the credit card processor then this method will be called.
So you now see how we have very few lines of code so to speak, that do different things, but are pretty
much the same.
So you see both of those are processed processing credit card payment and processing PayPal payment.
So this was quite a bit to handle, right.
Because we had two concepts coming together.
Number one interfaces.
And the other one is polymorphism.
All right.
So what are the interfaces and what are what is the polymorphism.
That's something that we're going to look at in the next video.