2

I have two classes Animal and Dog. As you can quess dog extends from animal. I can write these classes with no problem but I noticed that I can create a new dog object like this:

Dog firstDog = new Dog("rocky");

It's ok, but when I try to create new instance like this:

Animal secondDog = new Dog("alex");

There isn't any error but I can't reach any fields or methods that I wrote in Dog class even if they are public so if I want to hold an object in a variable whose type is same with its super class's type, I can reach field and methods that implemented only that super class (for this example name, color, setColor() and toString()) and there isn't any way to reach fields and methods which implemented in subclass. Did I understand correctly also when I try to call toString() function of secondDog it calls the method that I wrote in Dog class, I know I override this function in Dog class but I can't reach other methods that I implemented in Dog class. How java handle these?

Animal Class:

public class Animal {
    private String name;
    private String color;

    public Animal(String name){
        this.name=name;
    }

    public void setColor(String color){
        this.color=color;
    }

    public String toString(){
        return"Hi, my name is " + this.name + ". I'm " + this.color;
    }
}

Dog Class:

public class Dog extends Animal {
    private int age;
    public Dog(String name){
        super(name);
        setColor("gray");
        this.age = 7;
    }
    public String speakDog(){
        return"wof!";
    }
    public String toString(){
        return super.toString() + " and I " + speakDog();
    }
}
user3437460
  • 17,253
  • 15
  • 58
  • 106
azuosxela
  • 210
  • 1
  • 7
  • 15
  • Possible duplicate of [Can java call parent overridden method in other objects but not subtype?](http://stackoverflow.com/questions/1032847/can-java-call-parent-overridden-method-in-other-objects-but-not-subtype); http://stackoverflow.com/questions/10985223/java-polymorphism – Andrew Regan Mar 11 '16 at 23:21

3 Answers3

8

When you write this:

Animal secondDog = new Dog("alex");

You are telling Java secondDog is an Animal and that was it. The reason you are allowed to assign Dog into and Animal reference is because Dog is a subclass of Animal, hence it is allowed.

However, secondDog being explicitly an Animal will only be able to access properties and behaviours from Animal class.

To access properties and behaviours of Dog, you need to cast it:

((Dog)secondDog).speakDog();

Casting it to Dog is like telling Java: "Hey, trust me. This object is a Dog".

Only being more specific now, then you are allowed to access the properties of a Dog. (If not, it is still being treated as an Animal (higher class)).

However, if you cast it to a class which is not a subclass of Animal, you will get a ClassCastException.


In essence,

  • if secondDog remained as Animal (not being casted to Dog), it can only access all non private fields and methods from Animal.

  • if secondDog was casted as Dog, it can access all inherited fields and methods from Animal plus all non-private fields and methods from Dog.

user3437460
  • 17,253
  • 15
  • 58
  • 106
  • Yes, I understand. I can access only access all non private fields and methods from Animal when I didn't cast to Dog. But if I override one of these methods in Dog class I get the overrided one right in the main function? – azuosxela Mar 12 '16 at 11:28
  • @azuosxela You are right, it the method is overridden, you will invoke the overridden method in the subclass. For example, if you do System.out.println(secondDog); (even without casting it), it will invoke the `toString()` from the `Dog` class. – user3437460 Mar 12 '16 at 15:08
1

No, it is not possible to access the properties of the Dog through the Animal class. Consider the base object "Object" from which many sub-classes flow. You can say JFrame frame = new JFrame(""); or Object objFrame = new JFrame(""); frame.??? will give you access to all the JFrame's properties objFrame.??? will only give you access to the Object's properties.

I hesitate to ask why secondDog should be created as an Animal and not a Dog:)

Michael
  • 119
  • 6
0

Cast the Animal object to show it is a dog

Dog secondDog = (Dog) new Animal("alex);

Take a look at this:

Animal a = new Dog();
Dog d = (Dog) a; // no problem, the type animal can be casted to a dog, because its a dog
Cat c = (Dog) a; // raises class cast exception, you cant cast a dog to a cat

Only cast if it is a subclass.

Ruchir Baronia
  • 7,406
  • 5
  • 48
  • 83
  • 2
    With all due respect; this is utter nonsense. The point is that you tell the java compiler that the type of secondDog is Animal. And an Animal is an Animal; and not a dog. The additional cast doesn't change anything (in this context). Of course, when you know that your Animal is a Dog, then you can cast the Animal to Dog; and use dog methods. But that is not what your code is doing. – GhostCat Mar 11 '16 at 23:34