-3

I'm trying to understand the rationale for the last statement of my code being illegal in Java. See comment below.

public class Rectangle {

private int height;
private int width;

public Rectangle(int height, int width) {
    this.height = height;
    this.width = width;
  }

}

class ColoredRectangle extends Rectangle {
private String color;

public ColoredRectangle(int height, int width, String color) {
    super(height, width);
    this.color = color;
}

public String getColor() {
    return color;
}

public static void main(String[] args) {
    ColoredRectangle blueRectangle = new ColoredRectangle(2, 4, "blue");
    Rectangle sameObjectDifferentType = blueRectangle;
    ((ColoredRectangle) sameObjectDifferentType).getColor(); //Will compile
    sameObjectDifferentType.getColor();  //Won't compile 
  }
}

I know that I shouldn't use this design, and instead use different constructors. I know that getColor() is "not defined in Rectangle." Still, the way I think about this code is: sameObjectDifferentType is a reference to an object that is both a Rectangle and a ColoredRectangle, and therefore I should be able to access all of its members regardless if I declare the reference as Rectangle or ColoredRectangle. So... why is Java designed like this?

yinder
  • 17
  • 1
  • 7
  • `color = this.color` should be `this.color = color`. – MC Emperor Jan 12 '19 at 16:40
  • *I know that getColor() is "not defined in Rectangle."* That is precisely correct. `getColor()` is not defined in `Rectangle`. You thought about it correctly the first time. – Elliott Frisch Jan 12 '19 at 16:41
  • What happens if you have an other class that is an `Rectangle` and has a `getColor()` method? Now we can't even type check this expression. – Johannes Kuhn Jan 12 '19 at 16:46
  • How else would Java be designed? That's how OOP works - not all `Rectangle`s are also `ColoredRectangle`s. – jonrsharpe Jan 12 '19 at 16:51
  • The constructor for ```Rectangle``` is backwards, by the way: it updates its arguments from the member variables! –  Jan 12 '19 at 19:49

2 Answers2

0
Rectangle sameObjectDifferentType = blueRectangle;

When you make a declaration like this, you are explicitly telling the compiler that it should be treated as a Rectangle. While it may be a ColoredRectangle in this case, it would not take much for that guarantee to disappear.

Joe C
  • 15,324
  • 8
  • 38
  • 50
0

In this line, you are declaring that sameObjectDifferentType is of a type Rectangle

Rectangle sameObjectDifferentType = blueRectangle;

In more real world examples, this would allow you to have several different types, that you would want to treat in the same way. The classic example is CurrentAccount, CheckingAccount, SavingsAccount which all inherit from Account.

Suppose your banking application had code to lookup an account and find out the account holder. That code would just deal with the abstract Account types. It means that in the future when you introduce a StudentAccount, providing it inherits from Account you can use a StudentAccount in all the places you currently deal with Accounts without changing code.

Suppose you had a FilledRectangle and WireFrameRegtangle in your example. You could have a calculateArea(Rectangle rect) method that would apply to all Rectangles.

However, one trade off you make for this power and flexibility is that you lose the ability to directly deal with properties of the subclass when you declare an object to be of a super class type, so

sameObjectDifferentType.getColor();  //Won't compile 

However, Java does give you a way to get back to the subclass as you have noted by casting:

((ColoredRectangle) sameObjectDifferentType).getColor(); //Will compile

You as a developer know that sameObjectDifferentType is really a ColoredRectangle under the hood so you are safe to make this cast.However if you did

((FilledRectangle) sameObjectDifferentType).getFillPattern(); 

You would end up with a run time ClassCastException

Hope this helps.

Spangen
  • 4,420
  • 5
  • 37
  • 42
  • Thanks @yinder, If you're happy, please can you mark my answer as the accepted one by clicking on the tick next to it? – Spangen Jan 13 '19 at 18:47