WEBVTT

00:00.620 --> 00:03.440
So let's review where we stand.

00:03.470 --> 00:08.630
We've got this interface which has two methods process and refund payment.

00:08.660 --> 00:16.220
We've got an abstract base class that will just handle some common functionality of our payment processors.

00:16.340 --> 00:21.950
It accepts an API key for example, and it implements currently empty.

00:21.980 --> 00:24.650
Those two interface methods.

00:24.650 --> 00:30.290
And then we've got those two concrete classes which extend the base class.

00:31.550 --> 00:35.810
So previously I've said that we might implement some common functionality.

00:35.810 --> 00:38.690
And this is what I'd like to do.

00:38.690 --> 00:46.550
But first let's introduce abstract methods that we just explicitly define.

00:46.820 --> 00:48.980
And this one would be protected.

00:48.980 --> 00:52.850
So accessible in this and the child classes.

00:53.990 --> 00:58.280
So this would be validate API key.

00:59.210 --> 01:00.830
This would be a boolean.

01:00.830 --> 01:03.190
So it's like in an interface.

01:03.190 --> 01:06.820
When a method is abstract, it's not implemented.

01:06.820 --> 01:11.800
It's supposed to be implemented by a class that extends this one.

01:12.430 --> 01:13.240
Aethes.

01:13.420 --> 01:18.640
Now I can actually use this method inside this class.

01:19.840 --> 01:28.510
So I can actually call this validate API key method even though it's declared abstract.

01:29.290 --> 01:31.420
Now how is that possible.

01:31.540 --> 01:34.600
So here first let's throw an exception.

01:34.600 --> 01:36.940
So we haven't talked about exceptions yet.

01:36.940 --> 01:40.240
This basically stops the program execution.

01:40.480 --> 01:43.030
So we're going to cover this a little bit later.

01:43.030 --> 01:47.680
And this is how you throw an exception using a throw keyword.

01:47.770 --> 01:54.160
So going back to this method I can call it even though it is marked as abstract.

01:54.190 --> 02:03.070
The reason is eventually for everything here to make sense, I need a concrete class and only then I

02:03.070 --> 02:08.770
can create such class and concrete class cannot have any abstract methods.

02:08.920 --> 02:15.580
This means that those classes that extend the base online payment processor.

02:15.850 --> 02:20.530
They need this method implemented Rlhs.

02:20.710 --> 02:29.290
So in this case here, when the validate API key is being called, this would actually run a concrete

02:29.290 --> 02:33.190
implementation of that method from a child class.

02:35.860 --> 02:41.560
Now the refund payment method can contain the same logic.

02:42.580 --> 02:46.570
So it validates the API key first.

02:49.600 --> 02:56.410
So now we can or we have to actually implement this abstract method in the child classes.

02:56.410 --> 02:59.320
So we've got these two child classes here.

02:59.320 --> 03:06.570
And if they are not to be abstract they need to implement this abstract method.

03:06.600 --> 03:09.120
So let's do it right now.

03:11.130 --> 03:19.260
Let me copy the header of this and provide the actual implementation here and here.

03:20.700 --> 03:24.900
And this is no longer an abstract method.

03:28.080 --> 03:31.920
So first let's validate the key for stripe.

03:31.920 --> 03:37.590
So this could be something simple like we're gonna use stripe pause.

03:39.630 --> 03:49.590
To make sure that inside the API key it starts with an src prefix.

03:51.270 --> 03:58.170
And we're just gonna check if the position of this string inside API key is zero, which basically means

03:58.320 --> 04:02.130
API key starts with src underscore.

04:04.380 --> 04:08.460
And PayPal can have different rules in here.

04:09.210 --> 04:20.310
So in this case we're going to check if the length of this API key equals exactly 32.

04:22.140 --> 04:26.160
Now at this point I think we should see this in action.

04:26.160 --> 04:32.220
But before we do those methods they require a return value which is a boolean.

04:32.340 --> 04:37.050
So for now let's just return true for both of them.

04:37.050 --> 04:43.410
And then we're gonna see how can we have some specific implementation of how those operations should

04:43.410 --> 04:44.490
be performed.

04:45.810 --> 04:49.530
So here we can see that we are creating a stripe processor.

04:50.910 --> 04:57.660
So this means we should be able to call process payment and see if it works.

04:57.900 --> 05:02.610
So let's process our payment of 500 and let's run it.

05:02.700 --> 05:04.830
So we see a fatal error.

05:04.830 --> 05:12.110
So as I said throwing an exception is a way to trigger fatal error manually, and it is our error message

05:12.110 --> 05:15.170
that it is an invalid API key.

05:15.710 --> 05:22.700
So as you see the method process payment, which is implemented in a base class in the parent class

05:23.180 --> 05:34.880
that's online payment processor has actually called an implementation of validate API key from the stripe

05:34.880 --> 05:35.840
processor.

05:35.840 --> 05:44.540
And I can confirm that because looking at the requirements here, it has to start with src underscore.

05:44.540 --> 05:47.000
And currently it is just key underscore.

05:47.000 --> 05:53.270
And if I change this to be what stripe requires now everything is fine.

05:55.280 --> 05:58.280
Now at this point let's ask a question.

05:58.460 --> 06:02.690
Why would we need an interfaces at all?

06:02.810 --> 06:12.100
If it seems that we can have the same functionality with an abstract class, and more Because the abstract

06:12.100 --> 06:15.190
class can actually implement something.

06:16.090 --> 06:17.470
So let's see an example.

06:17.470 --> 06:25.090
I can make an abstract class called payment processor.

06:25.180 --> 06:31.180
And just define those methods as being abstract.

06:32.590 --> 06:41.020
And now every class that extends this payment processor class would have to implement those methods.

06:42.070 --> 06:46.690
So here's the first limitation of using an abstract class.

06:46.690 --> 06:57.310
The way we just used interface classes can only extend one single class while they can implement multiple

06:57.310 --> 06:58.480
interfaces.

06:59.320 --> 07:09.250
So if we try to ignore this and just put everything inside the online payment processor, then we can

07:09.250 --> 07:17.530
quickly run into things that can't really be solved like with this online payment processor.

07:17.560 --> 07:27.370
We are accepting an API key, assuming that the payment processors are some kind of services with which

07:27.370 --> 07:29.440
we need to connect, and we need a key.

07:29.620 --> 07:40.240
Now, if we would like to use the same methods to process payment and refund a payment, but this time

07:40.240 --> 07:48.460
with cash, then the abstract class seems to not really fit what we require.

07:48.490 --> 07:54.160
Because with cash you don't really have any services nor API keys.

07:55.120 --> 08:00.100
So that's why interfaces really have their purpose.

08:01.450 --> 08:06.550
So let's see an example of such a cash payment processor.

08:08.140 --> 08:14.080
So I would define a cash payment processor.

08:14.160 --> 08:18.840
And this would directly implement the payment.

08:20.880 --> 08:22.020
Processor.

08:22.920 --> 08:24.630
So an interface.

08:24.630 --> 08:32.370
And from the interface we can just copy those methods and do whatever.

08:32.370 --> 08:41.280
We are not really worrying about the actual logic in this examples.

08:41.970 --> 08:42.180
Okay.

08:42.180 --> 08:46.170
So let's return true from those methods.

08:46.320 --> 08:53.400
And here maybe we can actually say that we process cash.

08:53.430 --> 08:59.460
That would be cash refund and cash payment.

08:59.820 --> 09:08.550
Now if we then go back to our abstract class, we can see that what happened here is by implementing

09:08.550 --> 09:15.810
the interface and initially implementing some common logic for process, payment and refund payment

09:15.830 --> 09:16.820
methods.

09:17.030 --> 09:26.960
We actually have no way of making sure that the stripe processor or PayPal processor contain any specific

09:26.960 --> 09:34.550
logic, so we can leverage the abstract methods to enforce that.

09:36.440 --> 09:46.400
So let me copy the header of process payment and just create an abstract protected function that can

09:46.400 --> 09:50.390
be called maybe execute payment.

09:50.510 --> 09:58.580
And it's going to have the same headers and another one that will be execute refund.

09:58.610 --> 10:07.400
Now we have two additional abstract methods that have to be implemented in every single child class

10:07.400 --> 10:10.730
of this online payment processor.

10:11.660 --> 10:20.780
Essentially, this means that these methods have to be implemented in stripe and PayPal payment processors.

10:21.170 --> 10:28.940
Now we are going to actually call those methods inside the online payment processor.

10:31.220 --> 10:41.690
So in the process payment we're going to return the result of this execute payment passing the amount.

10:44.630 --> 10:47.120
And with the refund payment.

10:50.240 --> 10:51.500
We're going to do the same.

10:51.500 --> 10:55.340
But just calling execute refund.

10:55.970 --> 11:06.170
So we just use specific designs in this example so that if anyone would like to or would need to create

11:06.200 --> 11:14.660
some other specific payment processor, they don't really have to worry about a lot of things because

11:14.660 --> 11:16.010
they have an interface.

11:16.010 --> 11:18.650
They need to adhere to a contract.

11:18.740 --> 11:28.450
And additionally there is an abstract class which has some predefined way of how things should be running.

11:28.450 --> 11:37.900
So with this payment processor interface and then with online payment processor abstract class, we

11:37.900 --> 11:47.140
actually show the way for ourselves, our team and all the future developers how things should be done

11:47.140 --> 11:49.060
in our program.

11:49.120 --> 11:58.660
So if you need a payment processor that needs to have some specific logic, is cash, or uses something

11:58.660 --> 12:03.130
that's just not online, you simply implement the interface.

12:03.130 --> 12:12.520
That's the most generic description of what features such payment processing system needs to provide.

12:13.180 --> 12:20.560
But then we have a little bit more specific requirements for an online payment processor.

12:20.560 --> 12:30.190
So it's still implements an interface, but then additionally requires all the child classes to implement

12:30.190 --> 12:41.800
some specific functionality, and also calls this functionality so that if you need another online payment

12:41.800 --> 12:50.500
processor, you just know you need to implement those three methods and then you don't worry about anything

12:50.500 --> 12:51.190
else.

12:52.510 --> 12:57.520
Okay, so I think this is quite some material to digest.

12:57.520 --> 13:01.210
That's why I think we should take another break.

13:01.210 --> 13:11.110
And in the final third episode about interfaces and abstract classes, we're gonna see how can we use

13:11.110 --> 13:13.120
all of those classes.

13:13.390 --> 13:23.740
And we're gonna summarize what benefits do interface and abstract classes give us in software engineering?
