Is it possible to call subclasses' methods on

2019-01-03 06:36发布

Animal is a superclass of Dog and Dog has a method called bark

public void bark()
{
    System.out.println("woof");
}

Consider the following:

Animal a = new Dog();
if (a instanceof Dog){
    a.bark();
}

What will happen?

  1. the assignment isn't allowed
  2. the call to bark is allowed and "woof" is printed at run time
  3. the call to bark is allowed but nothing is printed
  4. the call to bark causes a compile time error
  5. the call to bark results in a run time error

I said 2 as we are checking if the object is a dog; as dog is the class with the bark method in it, if it is then we call it which will print out :s

Is my understanding correct here?

9条回答
欢心
2楼-- · 2019-01-03 07:10

This won't compile since Animal does not have a method called bark. Think of it this way, all dogs are animals, but not all animals are dogs. All dogs bark, but not all animals bark.

查看更多
乱世女痞
3楼-- · 2019-01-03 07:11

If the idea is to print the subclass method from superclass object, this will work:

Instead of Animal a = new Dog(); if (a instanceof Dog){ a.bark(); } change to

Animal a = new Dog();

if (a instanceof Dog){ 
    Dog d = (Dog) a; 
    d.bark();
}  

This casts the superclass back to subclass and prints it. although its bad design, its one way to know which child class object its pointing to dynamically.

查看更多
我命由我不由天
4楼-- · 2019-01-03 07:19

In java(only language i know) you can create an empty method and call it in super class. Then you can override it in subclass to do whatever you want. This way the super class calls its subclass' method.

public class Test {
    public static void main(String[] args){
        Snake S = new Snake();
        Dog d = new Dog();
    }
}


class Animal{ //Super Class
    public Animal(){
        bark(); //calls bark when a new animal is created
    }
    public void bark(){
        System.out.println("this animal can't bark");
    }
}



class Dog extends Animal{ //Subclass 1
    @Override
    public void bark(){
        System.out.println("Woof");
    }
}



class Snake extends Animal{//Subclass 2
    public void tss(){
    }
}

This code calls an object of Snake then calls an object of Dog. It writes this to console:

this animal can't bark
Woof

Snake doesn't have any bark method so super class' method is called. It writes the first line to the console. Dog has a bark method so super class calls it instead. It writes the second line to the console.

查看更多
仙女界的扛把子
5楼-- · 2019-01-03 07:20

In Head First Java they use the very good analogy of a TV remote control for a reference and your TV as the object that the reference points to. If your remote only has buttons (methods) for on, off, channel up and down, and volume up and down, it doesn't matter what cool features your TV has. You can still only do those few basic things from your remote. You can't mute your TV, for example, if your remote has no mute button.

The Animal reference only knows about Animal methods. It doesn't matter what other methods the underlying object has, you can't access them from an Animal reference.

查看更多
别忘想泡老子
6楼-- · 2019-01-03 07:25

no - the answer is;

4) the call to bark causes a compile time error

the bark method isnt defined as a method on the assigned type Animal, which will therefore result in compile time issue; this could be solved by casting;

((Dog)a).bark();
查看更多
乱世女痞
7楼-- · 2019-01-03 07:26

FYI, this is not a good design.

Just about any time you have code of this form:

if (x instanceof SomeClass)
{
   x.SomeMethod();
}

you are abusing the type system. This is not the way to use classes, it's not the way to write maintainable object oriented code. It's brittle. It's convoluted. It's bad.

You can create template methods in a base class, but they have to call methods that exist in the base class and are overridden in sub-classes.

查看更多
登录 后发表回答