0

I've created an array with a grandparent type, passed objects that are grandchildren of that type, but I can't access the elements from the child class. These aren't the exact things I'm coding they are just examples.

Here is the Grandparent

public class Animal {

String name = "Animal";


}

Here is the child class

public class Bird extends Animal {

String name = "Bird";

}

Here is the Grandchild class

public class RedBird extends Bird {
String name = "Red Bird";



}

The problem I am encountering is this

public class Room {
public static void main(String args[]) {

Animal[] anim = {new RedBird};

System.out.println(Animal[0].name);

 }
}

The program will output the wrong thing

Animal

Does anybody know how I can fix this? Thanks!

Bread Bouquet
  • 23
  • 1
  • 1
  • 10
  • one way you can do is, you can create getName and override it in RedBird – The Scientific Method Sep 22 '22 at 23:16
  • elaborate. Just make a method with return name? – Bread Bouquet Sep 22 '22 at 23:21
  • yeah in both classes – The Scientific Method Sep 22 '22 at 23:22
  • The fact that you declare the type `Animal` makes Java pick up the `name` associated with that class, the one that says "Animal". That you declare the type `Animal[]` doesn't matter, it's still type `Animal`. I don't know if that helps you to understand but it's part of the the Java typing system. Using a method as TSM suggests helps because methods of the same name override, which gives different behavior and something more like what you probably want. – markspace Sep 22 '22 at 23:41
  • Does this answer your question? [Java inheritance fields](https://stackoverflow.com/questions/43579567/java-inheritance-fields) – markspace Sep 22 '22 at 23:43

2 Answers2

2

Another way to look at this is if you don't want this behavior, don't re-declare the field. In other words, adding String declares a new field, and you don't want to do that. You can use an initializer block or a constructor to assign a new name.

public class Animal {
  String name = "Animal";
}

public class Bird extends Animal {
  { name = "Bird"; }  // This is an initializer block
}

public class RedBird extends Bird {
  { name = "Red Bird"; }
}

This will print "Red Bird".

markspace
  • 10,621
  • 3
  • 25
  • 39
  • Which version of Java is this valid for? I've been out of the Java world for a long time and haven't seen this kind of reassignment of class fields before. – Code-Apprentice Sep 23 '22 at 13:48
  • 1
    Syntax snafu on my part. Fixed it with an initializer block. – markspace Sep 23 '22 at 16:07
  • This does not work for what I'm trying to do. – Bread Bouquet Sep 23 '22 at 17:20
  • You'll have to describe better what you are trying to do. Your problem is obvious, you are using the wrong `name` field, but if this doesn't fix it, what do you want instead? I think you want inheritance with method names, but that's obvious, so why are you not doing that? – markspace Sep 23 '22 at 18:53
2
class Animal {
    String name;
    public Animal() {
        name = "Animal";
    }
}

class Bird extends Animal {
    public Bird() {
        name = "Bird";
    }
}

class RedBird extends Bird {
    public RedBird() {
        name = "RedBird";
    }
}

class Main {
    public static void main(String[] args) {
        Animal a = new RedBird();
        System.out.println(a.name);
    }
}
Ozgun
  • 21
  • 1