Java Language Polymorphism

Java Language Polymorphism


Hello, World! Steve Perry here. Polymorphism can be a complicated topic. So I’ve put together this video to accompany
the Java Polymorphism developerWorks recipe,
along with an application called the polymorpher that demonstrates Poymorphism using the Java
language. Here’s what we’ll cover: * A working definition of Polymorphism
* The class hierarchy of the polymorpher application, and
* The polymorpher application itself So what is Polymorphism? There are lots of ways to define it, but the
type of polymorphism I’ll talk about in this video
is what is called Ad-hoc polymorphism. According to British computer scientist Chris
Strechey (STRAY-CHEE) Ad-hoc polymorphism can be defined as: (https://en.wikipedia.org/wiki/Polymorphism_(computer_science)) “…functions that can be applied to arguments
of different types, but that behave differently depending
on the type of the argument to which they are applied.” In this video I’ll demonstrate three approaches
to polymorphism using the Java language: * Interfaces
* Abstract methods, and * Method overriding And each one of these approaches is demonstrated
in the polymorpher application. ********************************** And speaking of the polymorpher application,
let’s familiarize ourselves with it now by looking at a UML diagram of its class hierarchy. (FADE OUT) (SHOW CLASS DIAGRAM) At the top of the class hierarchy is the NamedEntity
class. It has a single method – name() – that
returns the name of the NamedEntity. Next are two subclasses of NamedEntity: Person,
and Dog. The Employee class is a subclass of Person. There are two interfaces in the application. The Greeter interface, which has a single
method – greet() – used to return a
greeting appropriate to the class that implements it. And the Complainer interface, which has a
single method – complain() – used to return some
kind of appropriate complaint. The Person class and the Dog class both implement
the Greeter interface. The Person class implements the Complainer
interface. Employee implements both of these interfaces
through Java inheritance. ********************************* (FADE IN) Okay, so enough jibber jabber. Let’s look at some code! (FADE OUT) First, I’ll clone the Github repo, which can
be accessed at: https://github.com/makotogo/polymorpher I’ll drop out to a Terminal window, navigate
to the location on my computer where I want the code
to reside, and issue the git clone command: git clone https://github.com/makotogo/polymorpher Once the repo has been cloned, I’ll open Eclipse,
and import the code. Choose File>Import>Maven>Existing Maven
Projects Select the directory where the Maven POM resides,
and click Finish. (FADE IN) In this project I’ve written unit tests that
capture the requirements. This is part of an approach to writing great
software called Test-Driven Development And I’m a big fan. (FADE OUT) At this point, there is only skeleton code
to implement the application. (SHOW ONE OF THE SKELETON CLASSES) But by studying the unit tests, you can deduce
how to write the implementation. (SHOW THE CORRESPONDING UNIT TEST CLASS) (FADE IN) Because by definition, the unit tests were
written based on the requirements. So, here’s the plan: (FADE OUT) Run the unit test class AllTests, which runs,
well, all of the unit tests. (RUN AllTests) All of the unit tests will fail, of course,
because there is only skeleton implementation code. (FADE IN) Next, write code until all of the unit tests
pass. That’s Test-Driven Development. Did I mention
I’m a big fan? I don’t have enough time in this video to
write all of the code, so we’ll look at one of the
classes, and I’ll let you finish the rest on your own. (FADE OUT) Let’s look at DogTest.java. It’s worth pointing out that I’m using JUnit
5 for this project, and I won’t walk through all
of the JUnit 5 features like @RunWith(JunitPlatform.class)
and so forth. But I wanted you to be aware of it. In the init() method, the classUnderTest variable
is set to a new instance of the Dog class. In the testName() method I can deduce from
the assertion that calling the name() method on
Dog should return the string “WOOF!” This is also the case for testGreet(). Now I’m going to write the implementation
in Dog.java. (OPEN Dog.java) I’ll set the return value of the
greet() method to the String literal “WOOF!” And delegate the name() method to the greet()
method since the unit test dictates they return the same
value. Let me run just the DogTest unit test. And now the unit test passes. So I’m done with the
Dog class. (FADE IN) I want to point out, if you get stuck, check
out the solution package, where you’ll find completed
classes that you can refer to. Once I have written all of the implementation
code all of the unit tests should pass. (SHOW ALL UNIT TESTS PASSING) And now I’m done. (FADE IN) Now, I want to point out the three approaches
to Polymorphism that we discussed by opening up the App.java
and AppTest.java source code. (FADE OUT) First, let’s see how polymorphism is achieved
through the use of interfaces. Let’s look at the nested unit tests for the
Dog implementation. In the testProcessGreeting() method
the compiler binds the call to processGreeting() in the App class to the overload that takes
a Greeter parameter. (SHOW THIS IN ECLIPSE) Once control at runtime is passed to here,
the runtime has to check the underlying type – a
Dog in this case – before it knows which Greeter.greet()
to call. (FADE IN) That’s polymorphism. But why? (FADE OUT) Because when the processGreeting(Greeter)
method is called from the DogImplementationTest.testProcessGreeting()
method, the result is “WOOF!” but when that same method
is called from PersonImplementationTest.testProcessGreeting() (SHOW THIS METHOD) The result is “Hello”. (FADE IN) And that’s how polymorphism is done through
interfaces. Now, let’s look at how polymorphism is achieved
through abstract methods. (FADE OUT) Look at the difference between the testProcessNamedEntity()
methods in the DogImplementationTest and PersonImplementationTest classes. Notice how they produce different results,
even though they are calling the same method on App. (FADE IN) Person.name() gives the person’s name. Dog.name() says “WOOF!” And finally, let’s look and see how polymorphism
is achieved through the use of method overriding. (FADE OUT) Recall how Person implements the Complainer
interface, and by inheritance, Employee inherits Person’s
implementation of the complain() method. But but the polymorpher application, I have
chosen to implement complain() differently for Employee, in order to demonstrate polymorphism. Person.complain() returns “My feet hurt” but
Employee.complain() returns “I deserve a raise”. And that too is polymorphism. (FADE IN) I’m afraid we’ll have to leave it there for
now. But go ahead and play around with the code,
modify the methods, and get a feeling for how this works. Thanks for watching!

Leave a Reply

Your email address will not be published. Required fields are marked *