0

I know that,No matter what the actual object is,that the reference variable refers to,The methods i can call on a reference is dependent on the declared type of the variable (in line 15 of code).I want to know why so.Why can't the class user use the reference variable s of type Shape to call its subclass method drawCircle()?

    public class Shape{
            public void displayShape(){
               System.out.println("shape displayed");
                      }
    public class Circle extends Shape{
            public void drawCircle(){
                System.out.println("circle drawn");
                      }
    public class Test{
            p.s.v.main(String[] a){
            Circle c=new Circle();
            Shape s=new Shape();
            display(c);
            display(s);
            public void display(Shape myShape){
               myShape.displayShape();//possible for ref variable c and s
               myShape.drawCircle();//not possible for reference var s
               }
             }
         }

Can u provide me an explanation of what happens at the object level?I am new to java.

1
  • correct your code and write full codes don`t use shortcuts like you have used here "p.s.v" instead write public static void main(String args[]). Plus there are many more mistakes, so kindly refactor your code once.Nested functions are not allowed in java if you want to achieve such functionality use lambda expressions of java 8. Commented Jul 15, 2017 at 8:24

4 Answers 4

0

The compiler just knows that myShape is a reference variable of type Shape, which contains only one method displayShape() , so according to the compiler, it is not possible to call a method drawCircle() which the Shape class does not contain.

The compiler is not concerned with what object this variable will hold at runtime. You may extend another class from the Shape class at some later point of time, and use the myShape reference to hold that subclass object. The compiler is just concerned with what type myShape is at compile-time.

If your Circle class happened to override the displayShape() method, like below :

public class Circle extends Shape {
    public void displayShape() {
        System.out.println("I am a Circle!");
    }

    public void drawCircle() {
    // Implementation here
    }
}

the only decision happening at runtime would be which displayShape() method to call.

Sign up to request clarification or add additional context in comments.

Comments

0

First, you forgot to make Circle subclass of Shape.

Then you said :

The methods i can call on a reference is dependent on the declared type of the variable

But the Shape myShape parameter is also a variable :

 public void display(Shape myShape){
    ...
    myShape.drawCircle();
 }

So also here, as for a local variable or a field variable, the compiler relies only the declared type to bound the invoked method.
And as the Shape class is used as the type of the declared variable, only methods of this class may be invoked on.

2 Comments

It's not even possible to call display method, its declared in main method body somehow, that seems to be his issue.
@user3734782 It is right. I don't think that it is its problem even it may be misleading. I think that it is just a very approximative and pseudo code. You have also p.s.v.main(String[] a){ and display should be static method. But well...
0

If you are sure that myShape is a Circle you can explicitly cast it to one ((Circle)myShape).drawCircle(); or Circle myCircle = (Circle)myShape; myCircle.drawCircle(); but if you do that and it isn't actually a Circle then you will get a ClassCastException.

Generally, you want to try and avoid this sort of casting though as its something of a code smell which suggests your design is a bit off. (Sometimes you do need to do it, but its not taking advantage of polymorphism).

To take advantage of polymorphism you would instead have Shape define displayShape() as an abstract method and then instead of drawCircle(), drawSquare() etc... each subclass of Shape will have its own version of the displayShape() method, while in Shape itself you would have: public abstract displayShape(); which is a way of telling the compiler "all my subclasses will have this displayShape() method so when someone calls displayShape() on one of me, use the one defined in that subclass".

So for example:

Shape myCircle = new Circle();
Shape mySquare = new Square();
myCircle.displayShape(); //draws a circle
mySquare.displayShape(); //draws a square

//And if you can't choose which one you want...
Shape surpriseMe = new Random().nextBoolean() ? myCircle : mySquare;
surpriseMe.displayShape(); //draws either a circle or a square!

Comments

0

How about reading about polymorphism.

public abstract class Shape {
   public abstract void draw();
}

public class Circle extends Shape {
    @Override
    public void draw() {
       System.out.println("Circle drawed");
    }
}

public class Triangle extends Shape {
    @Override
    public void draw() {
       System.out.println("Triangle drawed");
    }
}

public class Test() {
   public static void display(Shape shape) {
      shape.draw();
   }

   public static void main(String[] args) {
      //how can you define "shape" in real world? its triangle or... -> abstraction
      Circle c = new Circle();
      Triangle t = new Triangle();

      display(c);
      display(t);
   } 
}

Comments

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.