0

I have a problem when I use inheritance and define an object of parent class then call the constructor from the child class which has its own properties. When i want to assign values to the child class using sets methods its gives me an error (cannot find symbol) this is my code

    public class Shape {
private final double PI =3.14;
public Shape() {
}
public double getPI() {
    return PI;
} 
}

public class Rectangle extends Shape {
private double length;
private double width;
public Rectangle() {
}  
public double getLength() {
    return length;
}
public void setLength(double length) {
    this.length = length;
}
public double getWidth() {
    return width;
}
public void setWidth(double width) {
    this.width = width;
} 
}
public class Circle extends Shape{
private double radius;
public Circle(double radius) {
    this.radius = radius;
} 
public double getRadius() {
    return radius;
}
public void setRadius(double radius) {
    this.radius = radius;
}  

}

public static void main(String[] args) {
    Scanner in=new Scanner(System.in);
    Shape s[] = new Shape[3];
    int type;
    for (int i = 0; i < s.length; i++) {
         System.out.println("Enter the Shape:\n 1.Rectangle \n 2.Circle");
         type = in.nextInt();
         if(type==1){
             s[i] = new Rectangle();
             s[i].setLength(5.5);
         }  
    }
}
2
  • 1
    you need to declare it as an instance of the child class, if you declare it as an instance of the parent class, you are limited to the members of said parent class Commented Nov 28, 2018 at 6:56
  • Since you declared Shape s[] an element s[i] has the type Shape. The class Shape does not declare the method setLength. Commented Nov 28, 2018 at 6:58

2 Answers 2

1

Your problem lies here:

s[i] = new Rectangle();
s[i].setLength(5.5);

Yes. You know that this form is an instance of Rectangle, all the JVM knows is that it's a Shape. If you want to use it as a Rectangle, you have to declare it as one:

Rectangle r = new Rectangle();
r.setLength(5.5);
s[i] = r;

EDIT: The reason for this is, when you declare an instance as a Shape (parent class), the JVM will consider it to be this, even if your code suggests (to a human reader) that a specific type will be used, the JVM will not make any assumptions on which sub class will be instantiated. You are limited to the possibilities of the class you declared it to be.

Since you now again save it as a Shape, in your array, if later on you'll want to get that value, you'll need to cast it.

Rectangle rNew = (Rectangle)s[index]; // of course after checking whether it is in fact a Rectangle
Sign up to request clarification or add additional context in comments.

4 Comments

and this is how you can check: if(s[index] instanceOf Rectangle)
*instanceof, not instanceOf. But, depending on whether or not Rectangle has subclasses as well, a s[index].getClass() == Rectangle.class would be better
Thank you for your help. but what if i want to declare 10 Shapes as array then the user decide for each element is it a Rectangle or Circle. then depends on user response he will input the value for that shape. if(type==1){ s[i] = new Rectangle(); s[i].setLength(5.5); } else if(type ==2){ s[i]= new Circle(); }
@JhonN just check my answer. the developer can still store both the Circles and the Rectangles in that array, since they are subclasses of Shape, but if you want to call the methods of the subclasses, you have to declare them as such.
0

you setLength() method is present in your sub class Rectangle while s[i] points to an instance of type Shape which is a super class. thus, it doesn't recognize the instance method due to implicit upcasting. you will have to explicitly downcast you object s[i] from shape to Rectangle. This is how you can do it:

Rectangle r = (Rectangle)s[i];
r.setLength(5.5);

NOTE: Ofcourse the above statements gos after s[i] = new Rectangle();

an ideal way though (as explained by @Stultuske):

Rectangle r = new Rectangle();
r.setLength(5.5);
s[i] = r;

10 Comments

which would throw a NPE, since s[i] would be null. There is no reason to downcast, since he just creates the Object there.
these statements are to go after s[i] = new Rectangle(); ofcourse
@Stultuske I am just trying to explain about why the method is not accessible !!
if it's right after that statement, the downcast would be overkill. Why creating it as an Shape if you know you need it as a Rectangle? Yes, I get that, but your solution shouldn't be this odd
cause Object-Oriented !!! you might wanna hold instances of Circle and Rectangle in the same list
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.