Access subclass fields from a base class in Java

10,108

Solution 1

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.

Solution 2

You have to cast (specifically, downcast):

((Sphere) g).radius

Solution 3

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.

Share:
10,108
user283188
Author by

user283188

Updated on June 04, 2022

Comments

  • user283188
    user283188 almost 2 years

    I have a base class called Geometry from which there exists a subclass Sphere:

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

    and a subclass:

    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;
      super.shape_name = sphere_name;
      super.material = material;
     }
    }
    

    I have an ArrayList that contains all Geometry objects and I want to iterate over it to check whether the data from a text file is read in correctly. Here is my iterator method so far:

    public static void check()
     {
      Iterator<Geometry> e = objects.iterator();
      while (e.hasNext())
      {
       Geometry g = (Geometry) e.next();
       if (g instanceof Sphere)
       {
        System.out.println(g.shape_name);
        System.out.println(g.material);
       }
      }
     }
    

    How do I access and print out the Sphere's radius and center fields? Thanks in advance :)