Refactoring Code with Inheritance

Optional Node
Collapse Content

If you examine the Circle, Triangle and Square Classes, you'll notice that there's a large amount of code overlap between them. This usually means that you should refactor your code to get rid of the duplication. In this case, you could use inheritance so that each shape can inherit from a superclass called Shape. To see if Inheritance is a good idea, you can use the IS-A test:

  • Square Is a Shape?
  • Circle Is a Shape?
  • Triangle Is a Shape?

Hopefully you answered yes to all of these questions. That means it would make sense to create a new superclass Shape and make Square, Circle, and Triangle inherit from it.

Refactoring Square

  1. Create a new Class called Shape.
  2. Look at the Square Class and see which instance variables it has in common with the other shapes and which is uniquely Square's.
  3. Look at the Square Class and examine what methods it has in common with other shapes and what is uniquely Square.
  4. Cut and paste all of the non-unique methods and instance variables from Square to the new Shape class.
  5. Make Square inherit from Shape by using the extends keyword.

Then you need to adjust the code to get the new, lean Square class to work:

  • variable access - The private variables in Shape will not be available to Shape's subclasses. Remove the private modifier from them.
  • constructor - Most of the constructor can be moved to Shape also. However, you will need to set size in Square. You can call super to explicitly set everything else.

abstract keyword and Polymorphism

abstract
What would an instance of the superclass Shape look like? It would be hard to draw a Shape without having a specific one in mind. This means that it would make sense to make the Shape class abstract. An abstract class is a class that cannot have instances of it created. It exists for its subclasses to inherit from and create their own instances. You can declare a class abstract by adding the keyword before class:

public abstract class Shape

abstract methods
Abstract Classes can create abstract methods, which are methods without any method body. They exist so the subclasses can implement them with their own specific code.

Like classes, abstract methods are created with the abstract keyword. Here are 2 examples:

abstract public void doSomething();

abstract public int doSomethingWithNum(int num);

They just consist of a method heading, and end with a semicolon instead of braces { }.

polymorphic methods
You can now create an abstract method draw in the Shape class. This will let you call the draw method from different shapes without worrying how each Shape implements its method. This means that code in the Shape class can now call draw and other code can call draw on collections of different Shapes.

Other Shapes

Other shapes
Once you've finished setting up Square so it inherits from Shape, you can test it out. Compile your code, create a new Square and try out its methods as before. If everything works correctly, you will get the same results.

You can then do the same process to make Circle and Triangle inherit from Shape. Add the extends keyword so they inherit from Shape, and delete their methods and instance variables that already exist in Shape. Then set up their constructors to set their unique variable (after calling the Shape constructor to set the rest).

Holding the Shapes Together
Since Circle Square and Triangle are now all subclasses of Shape, you can put them together in one "container". Just like you put the Circles into a Circle array, you can now put these Shapes into shapes, a Shape array. You can then add Triangle to the Shapes array, and update your methods like changeColor so that they can be performed on all of shapes.

Challenge

Which methods should stay in the Square Class? (2 possible answers.)

Please sign in or sign up to submit answers.

Alternatively, you can try out Learneroo before signing up.

Comments

  • I can't do this last task- I've tried to create an array Shape []shapes=new Shape[3];
    and then can't instantiate Shape() as it's abstract.
    I tried shapes[0]= Circle(); but this doesn't affect the whole Class.
    I'd really to understand this. A hint or a cheat would be appreciated.

  • @Shane, I can't see your code (since it's offline), but did you use the correct code when creating the Circle? shapes[0] = new Circle(); If all the shapes are correctly in one Shape array, you can create a method that will call changeColor of each Shape:

    cont...
  • Dear Admin,

    For the Refactoring Square exercise, moveVertical() method should be moved to the shape super class i believe based on the IS-A test.

    cont...
  • Meh -_-! Sorry Admin.... I had not read about the polymorphic methods... so use abstract for the draw method...

  • How do you do the refactoring task as when you move funcitons such as makeVisible it calls the draw function, which there isnt one in the Shapes class? If the draw function is put in the shapes class it will only draw that shape as draw is called within shapes not the shape (circle). Thanks

  • solved read the next part of the node

  • I did must change the status of draw() method in square from "private" to "public", because of compilation was not possible. Is this correct solution ?

  • draw can be private in Square on it's own. But it can't stay private when you refactor to inherit from Shape.

Contact Us
Sign in or email us at [email protected]