So now we are going to learn about the interfaces and abstract classes.
So starting with interfaces.
So interfaces just define a contract that certain classes have to sign.
And this just guarantees that those classes will have certain functionality.
Specifically they will implement some methods.
Interfaces themselves don't implement anything.
They just define the methods.
So let's start by defining an interface.
And as an example here we are going to work with payment processors.
And the goal is to have an interface that defines some of the behaviors.
And then the classes that might implement PayPal payment processor or stripe payment processor.
And by doing that we basically allow our app Up to easily swap between different payment processors
without making any changes to the code.
So the interface is defined by using the interface keyword.
It needs to be given a name so we can go with just payment.
Processor and interfaces define methods but never implement them.
So I'm going to go with public function.
Process payment.
Which needs to accept an amount and returns a boolean on success.
Notice how I'm using a semicolon here.
As as I've said, there is no implementation in the interface.
Let's also have another method here.
So this would be refund payment.
So signing a contract by a class means that a class implements such interface.
And thus PHP will make sure that the given class has this method with exactly this header, and also
that it has this second method.
Otherwise this would be a fatal error.
Okay.
Now let's proceed with the implementations.
Okay.
So I think we should see an example of a class that implements the interface.
So let's create a stripe processor.
So if you don't know stripe this is an online payment processor.
Essentially it lets you accept payments.
And to implement an interface you're going to use the implements keyword.
And just name the interface Dad's payment processor.
Now, with this code here, we expect to see a fatal error because as I've mentioned before, when a
class implements the interface, it actually needs to implement all the methods from the interface.
Let's run this.
And there's the fatal error saying something about abstract methods or implementing them vars.
Next up, let's jump to the concept of abstract classes and abstract methods.
So currently we have a choice.
We either implement all the methods from the interface in this stripe processor class, or we mark it
as abstract.
Now making a class abstract has some serious implications.
The main one is that you can't create an instance of such class.
So if I'd like to go and do new stripe processor, this will just throw a fatal error.
You can't create an abstract classes.
So every method in a class needs to be implemented.
So what's the point of the abstract classes.
So interfaces lets you make sure that some classes have the specific functionality that is required.
So by implementing that interface we just make sure that a class has those two possibilities that it
can process payments and that it can refund payments.
And how does it do that is not our concern.
Now when you have abstract classes, what it lets you do is you might want to implement some common
Nationality across all of your payment processors.
So if I have a stripe processor, but I might also have a PayPal processor.
This makes perfect sense.
And there might be some common functionality across those two classes.
Like they both take an API key to connect to those services.
Maybe they can have some common logic that is required by your app.
And then creating an abstract class which can implement this functionality is actually a great idea.
So let's create an abstract class that we're going to call online payment Processor that will implement
our interface.
That's payment.
Processor.
So now let's make those two classes.
Concrete classes.
A concrete class is a class that's not abstract.
It means that it implements all the interface methods.
And it also implements all the abstract methods.
So it won't directly implement the interface.
Instead this would extend the online payment processor.
And by extending the online payment processor it actually also implements that interface.
So this is all inherited.
Now this won't work yet because still this is an abstract class.
And the methods from the interface are not implemented anywhere.
But since we have this abstract class, let's add something that will justify its existence, which
is some common functionality that those two concrete classes should share.
So let's assume that both of those payment processors accept a kind of an API key that's just used to
connect to them.
So I'm going to create a constructor here that will essentially define a field.
Now I'm using the protected visibility keyword and this is API key.
Now we haven't used protected before.
So let me explain this.
So public means you can access methods and fields inside and outside the class.
This is the public interface to your class.
This is what others using this class can actually call.
And private.
As we might remember, are the fields and methods that are only accessible inside a specific class.
And the difference between private and protected is that protected fields and methods are not accessible
outside the class, but they are accessible in classes that extend them.
So this API key field can be accessed in those classes inside those classes that extend this base class.
And if you have private fields or private methods, those cannot be accessed outside the class, but
also can't be accessed in classes that extend the base class.
So that's the difference.
Okay.
So now both of those payment processors, they get access to the API key.
Now there might be some different requirements for the API key in both of those.
So we're going to go back to this later on.
For now I'd like this abstract class to implement the methods from the interface, because we'd actually
like to have the logic that is kind of the same.
And in both cases, we'd like to verify if the API key is correct.
So now I'm going to implement those methods from the interface.
The easiest way to start is just to copy those like that and just add the implementation.
Now by the way, even though those methods are empty, we can actually create those classes now because
the methods are now implemented.
So if I'm going to do processor and I'm going to pass some kind of a key, then when I run this code.
Everything is fine.
All right.
So at this point I'd like to take a break.
Let's summarize what we've learned so far.
So we can define an interface, which basically is like signing a contract by a class that it guarantees
to have this functionality.
It has to implement all the methods from the interface.
Then there are abstract classes, and the abstract class is a class that has at least one abstract method.
If you don't implement a method from an interface, it's automatically abstract.
You can also explicitly mark methods as abstract, but we're gonna see that in the next example.
So we've created this abstract class that is not concrete.
So it cannot be created and it implements the interface.
Now we want to have the common functionality of those two methods, but also with some specifics that
will be implemented in those two concrete classes.
So we're going to go back to it after a short break.