Доступ к полям подкласса из базового класса в Java - PullRequest
3 голосов
/ 22 декабря 2010

У меня есть базовый класс с именем Геометрия , из которого существует подкласс Сфера :

public class Geometry 
{
 String shape_name;
 String material;

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

и подкласс:

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, который содержит все Geometry объекты, и я хочу перебрать его, чтобы проверить, правильно ли считываются данные из текстового файла. Вот мой метод итератора:

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

Как получить доступ и распечатать поля Sphere радиуса и центра? Заранее спасибо:)

Ответы [ 4 ]

11 голосов
/ 22 декабря 2010

Если вы хотите получить доступ к свойствам подкласса, вам придется привести его к подклассу.

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

Однако это не самый оригинальный способ сделать что-то: разиметь больше подклассов геометрии, которые вам понадобятся, чтобы начать приведение к каждому из этих типов, что быстро превращается в большой беспорядок.Если вы хотите напечатать свойства объекта, у вас должен быть метод в вашем объекте Geometry, называемый 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();
   }
}

Таким образом, вам не нужно выполнять приведение, и вы можете просто вызвать g.print () внутри цикла while.

1 голос
/ 22 декабря 2010

Я согласен с тем, что, но вместо реализации вашей собственной функции 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 (), но ее отсутствие просто распечатает версию Geometry.

1 голос
/ 22 декабря 2010

Вы должны разыграть (в частности, понизить ):

((Sphere) g).radius
0 голосов
/ 22 декабря 2010

используйте instanceof и приведите к желаемому подклассу.Возможно, вы захотите сделать эти поля общедоступными или использовать стандартную идиому приватных полей с геттерами и сеттерами.

...