从Java中的基类访问子类字段
我有一个名为Geometry的基类,其中存在一个子类Sphere: 和一个子类:从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;
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();
}
}