0

(Question previously asked here. I did not quite get the desired answer.)

A quote from a book:

What if you want to call a method that’s defined by a subclass from an object that’s referenced by a variable of the superclass? Suppose that the SoftBall class has a method named riseBall that isn’t defined by the Ball class. How can you call it from a Ball variable? One way to do that is to create a variable of the sub- class and then use an assignment statement to cast the object:

Ball b = new SoftBall();
SoftBall s = (SoftBall)b;
// cast the Ball to a
// SoftBall
s.riseBall();

In the code snippet above, it shows a new Softball object being created and assigned as a reference to the variable b, which is completely legal since the class Softball is a subclass of the class Ball. Yet the quote states (indirectly) that you have to cast the variable to type Softball before you can use the variable to call methods from the Softball class. Why is that? Why can't I directly use the variable b of type Ball (which contains the reference to the Softball object) to call the desired method? The variable b already has the object.

(Note: I already read this post.)

  • To create a variable `b` of type `Ball` is to tell the compiler "the object in this variable can be anything of type `Ball`". If you want to the compilier to know that the object held by the variable is a `SoftBall`, use a variable of type `SoftBall`. That's what variable types are for. – khelwood May 10 '18 at 08:57
  • 2
    Quote from the answer you have referenced: `The declared type of the variable a is A. The compiler doesn't know (and shouldn't know) what its concrete type at runtime is B.`. – awesoon May 10 '18 at 08:57
  • Your expected scenario is possible only if Ball is abstract and has an abstract `riseBall()` method. – Ashwin K Kumar May 10 '18 at 09:02
  • think these concepts will help you to understand the answers - polymorphism and late binding in java – oreh May 10 '18 at 09:02

4 Answers4

4

Java is a statically typed language.

That means that the compiler checks if the type of the variable has the method you are trying to call.

The type of your variable b is Ball. Ball does not have a riseBall method.

That means your code would crash unless that b at runtime happens to contain a Softball (which the compiler cannot guarantee). You may know that it does, but you have to convince the compiler, too (i.e. give your variables the necessary types).

Thilo
  • 257,207
  • 101
  • 511
  • 656
1
Ball b = new SoftBall();

This just means that variable b is of type Ball, but if the methods present in class Ball if are overridden in extended class SoftBall, then using variable 'b', we shall be invoking the method definition of class 'SoftBall' rather than 'Ball'. Now, although variable b refers to the implementation of class 'SoftBall', it still is of type class 'Ball' and class Ball does not have any method 'riseBall'

Hope that makes sense.

Ankur
  • 892
  • 6
  • 11
0

Because the methods that are exposed depends on the declared type of the variable.

Ball b = new SoftBall();

b is actually a SoftBall but you are "hinding" it because you declared it as a Ball type. Since Ball type doesn't have a riseBall method you cannot access it by asking b.

Averroes
  • 4,168
  • 6
  • 50
  • 63
0

As we know java is a statically typed language.

This is a feature of statically-typed languages where variables are assigned a type ahead of time, and checked at compile-time to see that the types match.

If this code were performed on a dynamically-typed language, where the types are checked at `runtime, something like the following could be allowed:

Ball b = new SoftBall();
if (b instanceof SoftBall){
  b.riseBall();
}

b.riseBall() is guaranteed only to execute when the instance is a SoftBall, so the call to riseBall will always work.

However, Java is a statically-typed language, so this type of code is not allowed.

Pradeep
  • 12,309
  • 3
  • 20
  • 25