Interfaces and Polymorphism
We've had four weeks of CS15 and by now, the buzz words of Object-Oriented Programming (OOP) should be familiar to you. OOP is an extremely powerful and quickly growing modeling paradigm making programming large scale applications much easier than before. For the remainder of the course, a good understating of OOP concepts will be integral to designing and implementing the assignments. This lab is about how to make your life as a programmer much easier by teaching you how to write flexible and reusable code through interfaces and making polymorphism your best friend.
Goal: Learn how to implement polymorphism using interfaces.
Life before polymorphism, sigh...
Let's say you are running a little low on funds, and decided to earn some money, and exercise your creative muscles at the same time, by opening a car painting business! Since you are a very savvy programmer, you're going to write a program that will do the painting for you.
You'll begin by finding cars that need to be painted.
Because of the support code for this lab, it is very important to follow the directions in the stencil and in the CheckPoints! Name methods in the exact way asked for and instantiate in the order we state.
Check Point 1
cs015_install labInterPolyto get the stencil for this lab. (You should have the following files in your directory: App.java, PaintShop.java, Car.java, Fish.java, and Incredibles.java).
We'll concentrate on the Car.java file for now. The Car has the following components:
- Add a
paint(...)method to the
Carclass that takes a
java.awt.Coloras a parameter. Inside this method you will want to set the color of the
Car's components listed above. Each component has a
setColor(...)method that takes a
java.awt.Coloras a parameter. Click "Save" to save the code you added to the
- Compile your code to make sure there are no errors!
Now that we have a car, let's figure out how to paint it!
Check Point 2
- Add an instance variable to the
PaintShop.javato store the current color.
- Create an accessor method and mutator method for the current color instance variable. This should be a piece of cake after LiteBrite.
- Add a
paintCar(...)method to the
- It should take in a
Caras a parameter.
- It should not return anything.
- It should paint the
Carbased on the "current color".
- HINT: use the
(Remember to save!)
- HINT: use the
- Test what you've done by instantiating a
Carobject in the constructor of App.java. An instance of
PaintShopshould already be created. In order for the
PaintShopto "know about" the car (i.e. to set up an association with the car), use the
add(...)method and pass it the car you've just created. (Question: where is this
add(...)method defined?) Save!
- Compile and run the application. (run with:
java labInterPoly.App) You can paint the
Cardifferent colors by selecting a color from the Color Chooser and then clicking on the car.
Your painting business became very successful and you want to expand your business to paint other things like: walls, roads, tables, chairs, beds, ceilings, squares, circles, and everything else in the world that can be painted. Yes, it seems ambitious, but with Java at your side anything is possible!
Your new customers request that you paint some superheroes.
Check Point 3
HINT: This is very, very similar to what you did above.
- Write a
paint(...)method in your
Incredibles.java) to color in its components. Save!
- Write a
paintIncredibles(...)method in the
- Instantiate an instance of
Incrediblesin the constructor for
Appand add it to the
PaintShop(just like you did with the
- Compile and run the application. You can control which item you are painting using the radio buttons at the top.
There are a lot of very similar methods that you have to write for all the things that can be painted. The design so far has a serious problem. Your
PaintShop class is very spiffy, and you want everyone to benefit from your hard work. The only problem is, every time someone wants to paint something new, you are going to have to add a new
paintThing(...) method in the
PaintShop class to paint the new item. If someone wanted to paint a door, you would need to add a
paintDoor(...) method, if someone wanted to paint a house, you would need to add a
paintHouse(...) method...and you get the idea.
Wouldn't it be nice to just have one method that can paint anything that can be painted? It seems like a fairly simple concept, but the trick is that the PaintShop's
paintThing(...) method takes in a parameter: the object it is supposed to paint. For
paintCar(...) it took in a car, for
paintIncredibles(...), it took in an instance of the
Incredibles. What type should it be for the generic version? Tricky, tricky, tricky...
One way to do it would be to have some superclass that can be painted and create subclasses that inherit from this superclass for all the objects that you want to paint. This is called inheritance. However, there are a few problems with that design. Firstly, since each class can only inherit from one class at a time, if a class is the subclass of a
Paint class, then it cannot be the subclass of anything else. This is the exact situation we are in. The
Incredibles classes already extend from another class (see
extends in the class definition!), so they can't be the subclass of anything else. Secondly, the relationship between the different subclasses is a weak one; the only thing they have in common is that they can be painted. Using inheritance here would be limiting and unnecessary.