1

The Superclass reference variable can hold the subclass object, but using that variable you can access only the members of the superclass, so to access the members of both classes it is recommended to always create reference variable to the subclass.

class Animal {
   public void move() {
      System.out.println("Animals can move");
   }
}

class Dog extends Animal {
   public void move() {
      System.out.println("Dogs can walk and run");
   }
   public void bark() {
      System.out.println("Dogs can bark");
   }
}

public class TestDog {

   public static void main(String args[]) {
      Animal a = new Animal();   // Animal reference and object
      Animal b = new Dog();   // Animal reference but Dog object

      a.move();   // runs the method in Animal class
      b.move();   // runs the method in Dog class
      b.bark();
   }
}

output:

TestDog.java:26: error: cannot find symbol
  b.bark();
   ^
symbol:   method bark()
location: variable b of type Animal
1 error

What I do not understand here is why is the object 'b' able to access the Dog.move() and not Dog.bark() because the statement mentioned above says it can access only the members of the superclass and not the subclass.Following this logic the output of b.move() should be "Animals can move" and not "Dogs can walk and run".But that is not case.Can anyone help me with this?Thanks in advance!

injecteer
  • 20,038
  • 4
  • 45
  • 89
cooltogo
  • 67
  • 12

4 Answers4

1

Congratulations - you just discovered polymorphism.


In Java the classes are bound dynamically. That is if you are invoking a method the implementation of the object is invoked (in your case the Dog) and not the method of the reference type (in your case the Animal).

This allows overwriting methods and replace or fulfill their implementation.


On the other hand, you can only access methods that are available in the type you are referencing, not the implementing type (in your case the Animal). To invoke the methods of the instance, you would have to use it as the reference type (in your case the Dog).

Fabian Damken
  • 1,477
  • 1
  • 15
  • 24
1

This will not 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.

Jude Niroshan
  • 4,280
  • 8
  • 40
  • 62
Shekhar
  • 54
  • 5
1

In your question Animal is a parent class which doesn't have bark() method so that method isn't overridden. If you were able to access bark() from parent class without declaring either abstract method or defining it, then that would be violation of the Polymorphism principle.

If you really want to access it that way, then you can either define a abstract public void bark(); in your parent or access that method by typecasting like this

((Dog) b).bark();
Raman Sahasi
  • 30,180
  • 9
  • 58
  • 71
0

This code is wrong, as the line b.bark(); will give you a compiler error, because b is only defined as an Animal, which cannot bark().

If you change Animal b = new Dog(); to Dog d = new Dog(); it will work properly.

You've got inheritance mixed up. Dog can do what Animal can do, not vice versa.

class Animal {
    public void move() {
        System.out.println("Animals can move");
    }
}



class Dog extends Animal {
    @Override public void move() {
        System.out.println("Dogs can walk and run");
    }
    public void bark() {
        System.out.println("Dogs can bark");
    }
    public void moveSuper() {
        super.move();
    }
}



public class TestDog {

    public static void main(final String args[]) {
        final Animal a = new Animal(); // Animal reference and object
        a.move(); // runs the method in Animal class

        final Dog d = new Dog(); // Animal reference but Dog object
        d.move(); // runs the method in Dog class
        d.bark();
        d.moveSuper();
    }
}
JayC667
  • 2,418
  • 2
  • 17
  • 31