0
class Bird{
    public Bird(){
    }

}

class Falcon extends Bird{
    public Falcon(){
    }

    public void fly(){
    System.out.println("Fly method in falcon");}
}

public class Test{
    public static void main (String args[]){
        Bird b=new Falcon();
        b.fly();    // error on this line
    }
}

The above code gives me a compile time error. Can anyone tell me why? I am using JDK 1.8

7
  • 6
    Bird Doesn't have a fly method specified in its' public interface. Commented Jun 6, 2016 at 3:34
  • "gives me a compile time error" is an incomplete description of your problem. What error? Commented Jun 6, 2016 at 3:35
  • 2
    To elaborate a bit on Elliott's comment: When the type has a static type of Bird, Java will only let you invoke methods on it that it knows all Birds have. You didn't declare a method fly() on Bird, so as far as Java knows, this Bird could be one that doesn't have that method -- and thus, it won't let you invoke it. Java doesn't know at compile time that b is specifically a Falcon, because you explicitly told it that it's just some kind of Bird. Commented Jun 6, 2016 at 3:37
  • I get error "The method fly() is undefined for the type Bird". Which part of this error message do you not understand? Commented Jun 6, 2016 at 3:38
  • 1
    @Andreas I don't think this is a concept that's always obvious to beginners. So it makes perfect sense to me that even with the error message, the reason could be confusing. Commented Jun 6, 2016 at 3:55

1 Answer 1

4

Basically, if you declare something as a Bird, the only things the compiler is "allowed" to know is that it has the methods defined for Bird. It's not allowed to know about any methods declared for any subclasses of Bird (unless you use a cast).

Suppose you were to say

Bird b = new Falcon();
someMethod(b);

and then, in someMethod:

public void someMethod(Bird b) {
    b.fly();
}

This is essentially the same thing you're doing. But the only thing someMethod knows about b is that it's some kind of Bird. It can't tell, at that point, whether it's a Falcon, or something like an Emu or Kiwi that doesn't have a flight method (since someMethod could be called from some other place in the program).

Sure, it might be possible for the program, when it sees b.fly(), to check at run time whether this kind of bird has a fly method, and throw an exception if it doesn't. Some languages do that. Java doesn't.

Also, if you're thinking that the compiler should know in this case:

Bird b = new Falcon();
b.fly();

that b is a Falcon, because it just created it as a Falcon: that doesn't work, because it would require overly complicated language rules to allow a compiler to see that b.fly() will always work in this case, but won't always work in other cases. Language rules need to be kept fairly simple and consistent, to ensure that programs will work on any compiler that meets the standard.

However, if you use a cast, you can get at methods of the subclasses:

Bird b = new Falcon();
((Falcon)b).fly();

This says to check (at run time) whether b is a Falcon. If it is, you can now use the methods defined for Falcon. If it isn't, you'll get an exception.

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

1 Comment

Great explanation! As additional commentary for "some languages do that. Java doesn't" -- this is, broadly speaking (and glossing over some subtleties), the difference between a "statically typed" language like Java, and a "dynamically typed" language (like Python, JavaScript and others).

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.