Narrator: So now that we know about the difference
between real objects and data containers,
let's dive into another important concept.
And that would be polymorphism.
Now we already had a first look at polymorphism
in the last course section,
where we built a factory function,
which created polymorphic objects
to hold different functions
for handling payments and refunds.
And I explained what polymorphism is back then.
It's simply an object or a method,
which always has the same structure and the same name,
but which then does different things
based on how it was created and how you use it therefore.
And that's a powerful concept,
because it can help us avoid code duplication.
We can also implement polymorphism,
or a use polymorphism when working with classes,
instead of creating objects or dictionaries
on the fly as I did it back in the last section.
So here is another clause, the delivery clause,
which has a private property purchase,
a constructor and then two methods,
deliver product and track product.
And in there you see something similar
as in the last course section,
we have different delivery types on this purchase,
which is part of the delivery,
and based on the different types,
we then dispatch different static methods
on some other object, some are class here.
And this is just some dummy code
both the purchase and the logistics object
doesn't really exist,
but I can still show you what polymorphism is
at this example and how you deal with it
when you using classes.
Because when using classes we can implement polymorphism
in a very, very elegant way.
The solution would be to not just use one class
but to have multiple specialized classes.
In this case, for the different kinds of delivery we have.
Express delivery, ensured delivery and standard delivery.
And we would just have a base delivery class
which holds all the shared logic and properties,
which all specialized classes need as well.
But then it would be the specialized classes
which have the specific deliver product
and track product implementations.
So if we would want to make this class
and these methods use polymorphism and be polymorphic
then we would in the end, create a couple of new classes.
For example, an express delivery class
but also ensured delivery class
and also standard delivery class.
We created these specialized versions
because these are in the end,
the three kinds of deliveries we have
if we have a look at these methods.
We see that the type of delivery seems
to play an important role.
So since this is the delivery class, which is responsible
for delivering a product or for tracking it,
we should have specialized wordings of these classes
for the different types of delivery.
So therefore here, we would have these three classes.
And for example, in the express delivery class here
we would then have a deliver product method.
So we can copy this, but it wouldn't have any if check.
It would just have the code which needs to be executed
to deliver a product with express delivery.
So in this case, I would reach out to logistics
and then call issue express delivery.
Now the purchase property is not accessible here
because at the moment, this is a standalone class
which doesn't have a purchase property.
The solution is to extend the base delivery class here
because when we extend that class
then we also have access to all the properties
this class has including its property.
Now, as a quick side note here,
of course here, I'm using inheritance
and I'm using a couple of concepts we know from classes
and the object oriented world.
Later I will also use an interface.
If this is all something you never heard about,
then you probably never worked with classes.
And then of course this specifically is a concept
you won't be able to utilize
and you won't need in general.
You still learned about polymorphism
in the last course, section though.
As I mentioned earlier, the idea of this course
and of this section is not to teach you classes
or object oriented programming
but to teach you a couple of concepts and ideas
and rules you should be aware
of when working with classes or objects.
And here we're working with classes
so therefore of course this general knowledge about classes
and that includes inheritance, is of course required.
You can of course skip this entire lecture for the moment
if that is something you don't have any experience with.
The only thing here is that this property
is private at the moment,
which means it can really only be used in here.
And if you are using a programming language
which knows the concept of private, public and so on,
then you know that you should change this
from private to protect it.
Which means it can still not be accessed from outside
of the class, but it can be accessed by child classes,
which is exactly what we need here.
And with that, we could then also copy over track product,
like this, and also get rid of the if statement here
and just call the code we need to track a product.
And now we repeat this procedure
for the other classes as well.
So we copy these methods also into ensured delivery,
get rid of all the if checks here
and just keep the code we wanna execute
if we do have an insured delivery.
And the same down here for tracking a product.
And then again, we copy it all into standard delivery
and remove all the if checks
and just keep the standard delivery code.
Of course, standard delivery and insured delivery
now also need to inherit from the base delivery class
which in the case of TypeScript is done like this.
So now we have these specialized classes.
In the base class, we can now remove the deliver product
and track product methods because
that is something our specialized classes will deal with.
Now, of course you might now ask,
that's all great, but where's the if statement?
I mean we need to decide somewhere
which specialized class should be used.
Well, that's something you need to do
in the place where you plan on using these classes.
So if you have some code in some other method or function
it doesn't matter where you wanna use such a delivery class.
You would in the past have created your delivery class
by instantiating a new delivery
and passing in some purchase object.
And then in the past,
before we created this specific versions
you could have called deliver product.
Now that's not possible anymore
because deliver product doesn't exist
on the base class anymore.
Instead you need a specific class now.
And that means that in the place
where this code would execute,
you need to decide which specific version you need.
But that's a decision you typically can make
in these places.
Now you just need to have your if check in that place here.
So here you would have your if check
with these different branches
and you could also use a switch case statement, of course
and then here you would have your delivery variable
which would be of type delivery.
And then here we would assign a value
of new express delivery and pass in our purchase.
Here, we would have a new insured delivery instance.
And down here we would have
a new standard delivery instance.
And then at the bottom we can call deliver product.
And of course, instead of this purchase delivery type,
you would have your purchase object
lying somewhere around here.
where you do execute this if statement.
Let's not worry about this condition at the moment though.
Let's assume we are in some place where we do have access
to this purchase.
Because this is sudo code anyways.
It won't execute anyways
because we don't have a real purchase here.
This is how you would solve these situations though.
How you would create the proper instance
of your delivery class based
on which specific type you need.
Now here actually, my IDE is complaining
that this is not a method of the delivery class.
And that would be correct,
it's the child classes which had it
but of course you can work
around something like this as well.
For example, by utilizing an interface or abstract classes.
So here we could have an interface called delivery
which dictates that we have a deliver product method
and that we have a track product method.
And then this here would be the delivery implementation,
for example,
and we would extend delivery implementation here
And our classes would implement
the delivery interface like this.
This is the TypeScript syntax for doing this,
for extending a class and for implementing an interface.
The exact implementation of course depends
on which programming language you are using.
This is just some way of doing it,
but now we can set the interface
as a type here and we therefore know,
whatever is stored in delivery will be an object
which implements this interface
and which therefore will have a deliver product method.
And therefore, now we can safely call deliver product here.
And it's this if check, which now ensures
that we're executing this method
on the correct type of object.
Now, of course you might have multiple places
in your code where you need such objects.
And therefore of course you could create
a factory function again
or a factory method in some utility class.
And for example, name this create delivery
where you get the purchase
for which it should be created.
And then you move that if code just
into your factory method, you pass the purchase
to these constructor functions
and then wherever you needed such
a specific type of delivery,
you would just call create delivery, pass your object to it
and you would then be good.
Of course, we need to return the created object
in the factory function.
And then this factory function could be used anywhere
in the code where you need this specific type of object.
And now in this factory function,
of course we can get rid of the this key word
and assume the purchase which we got here
has a delivery type.
Again, I just wanna make it really clear,
the object I do pass in doesn't have to this property,
but this again is just some sudo code.
Of course, instead of passing in an empty object down there
where you create your instance,
you would have a concrete purchase object,
which you would be getting from somewhere else
in your application.
It's just not the focus here.
The focus is that we do have such a factory function
which knows how to produce specific instances
of our classes here based on which kind of purchase we get.
And that's how you can use polymorphism
and create polymorphic objects when using classes.
It's basically the same idea as in the last course section
where I essentially created an object
or a dictionary on the fly with the factory function.
Now we're solving the same problem by using classes.