Access subclass fields from a base class in Java

If you want to access properties of a subclass, you're going to have to cast to the subclass.

if (g instanceof Sphere)
{
    Sphere s = (Sphere) g;
    System.out.println(s.radius);
    ....
}

This isn't the most OO way to do things, though: once you have more subclasses of Geometry you're going to need to start casting to each of those types, which quickly becomes a big mess. If you want to print the properties of an object, you should have a method on your Geometry object called print() or something along those lines, that will print each of the properties in the object. Something like this:


class Geometry {
   ...
   public void print() {
      System.out.println(shape_name);
      System.out.println(material);
   }
}

class Shape extends Geometry {
   ...
   public void print() {
      System.out.println(radius);
      System.out.println(center);
      super.print();
   }
}

This way, you don't need to do the casting and you can just call g.print() inside your while loop.


You have to cast (specifically, downcast):

((Sphere) g).radius

I agree with rwhat, but instead of implementing your own print() function, it might benefit you (and be more Object Oriented) to avoid the downcasts by overriding the toString() function.

public class Geometry 
{
 String shape_name;
 String material;

 public Geometry()
 {
     System.out.println("New geometric object created.");
 }

 public String toString() {
      StringBuilder result = new StringBuilder();
      result.append("Shape name: " + shape_name + "\t");
      result.append("Material: " + material + "\t");
      return result.toString();
 }
 public static void check (Geometry[] gList) {
     for (Geometry g: gList) {
         System.out.println(g.toString());
     }
 }

Note the check() doesn't care whether g is a Sphere or a Cube. This will help minimize the calls to instanceof. Over in Sphere...

public class Sphere extends Geometry
 {
  Vector3d center;
  double radius;

  public Sphere(Vector3d coords, double radius, String sphere_name, String material)
  {
   this.center = coords;
   this.radius = radius;
   shape_name = sphere_name;
   super.material = material;
  }
  public String toString() {
      StringBuilder result = new StringBuilder();
      result.append("Radius: " + radius + "\t");
      result.append("Center: " + center.toString() + "\t");
      result.append(super.toString());
      return result.toString();
  }
 }

Any new shape (e.g., Cone) would benefit by having the toString() function, but lacking it would just print out Geometry's version.