从Java中的基类访问子类字段

从Java中的基类访问子类字段,java,oop,class,inheritance,subclass,Java,Oop,Class,Inheritance,Subclass,我有一个名为Geometry的基类,其中存在一个子类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;

我有一个名为Geometry的基类,其中存在一个子类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;
  super.shape_name = sphere_name;
  super.material = material;
 }
}
我有一个包含所有几何体对象的ArrayList,我想对它进行迭代,以检查文本文件中的数据是否正确读取。以下是我目前使用的迭代器方法:

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);
   }
  }
 }
公共静态无效检查()
{
迭代器e=objects.Iterator();
while(e.hasNext())
{
几何g=(几何)e.下一步();
if(球体的g实例)
{
System.out.println(g.shape\u name);
系统输出打印LN(g材料);
}
}
}
如何访问和打印球体的半径和中心字段? 提前感谢:)

您必须(具体地说,):


使用instanceof并强制转换到所需的子类。您可能希望将这些字段公开,或者使用getter和setter实现私有字段的标准用法。

如果您希望访问子类的属性,则必须强制转换到子类

if (g instanceof Sphere)
{
    Sphere s = (Sphere) g;
    System.out.println(s.radius);
    ....
}
不过,这并不是最面向对象的方法:一旦你有了更多的几何体子类,你就需要开始对每一种类型进行强制转换,这很快就会变得一团糟。如果要打印对象的属性,应该在几何体对象上有一个名为print()的方法或沿着这些线的方法,该方法将打印对象中的每个属性。大概是这样的:


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();
   }
}

这样,您就不需要执行强制转换,只需在while循环中调用g.print()。

我同意rwhat,但与其实现自己的print()函数,不如重写toString()函数来避免向下转换(并且更加面向对象)

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());
     }
 }
注意,
check()
不关心g是球体还是立方体。这将有助于最小化对
instanceof
的调用。 在球体上

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();
  }
 }

任何新的形状(例如圆锥体)都可以使用toString()函数,但如果没有它,则只会打印出几何体的版本。

这与。这是否回答了您的问题?基类需要了解子类数据,这表明您的抽象可能不正确。您应该后退一步,问问自己检查在做什么,它是否需要位于对象模型外部的实用程序类的基、子类或可能的方法上。此外,您不需要在子类中到处都使用“super”,因为它们继承字段。
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());
     }
 }
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();
  }
 }