管理异构 Java 数组中的不同对象
Managing different objects in an heterogeneous Java array
我必须在 Java 中解决这个 "container problem"。我有一个由不同数字组成的数组,我希望下面的代码能够工作:
package container;
class Figure{
public void draw() {}
public String getColor() { return null; }
}
class Square extends Figure{
@Override
public void draw(){
System.out.println("Square");
}
}
class Circle extends Figure{
@Override
public void draw(){
System.out.println("Circle");
}
public float getRadius(){
return 8;
}
}
public class Container {
public static void main(String[] args) {
Figure[] figures = new Figure[3];
figures[0]= new Circle();
figures[1]= new Circle();
figures[2]= new Square();
for(Figure figure:figures){
figure.getColor();
figure.draw();
((Circle) figure).getRadius();
}
}
}
您可以看到有问题,因为 Square
没有 getRadius()
方法。我有以下限制:
- 不能使用泛型
- 无法使用
instanceof
这应该是一个不错的面向对象设计解决方案。
如果您不能使用 instanceof
,您可以在 Figure
class 中声明抽象方法,并为不需要它的图形添加虚拟实现。以下没有 instanceof
和 java 泛型的代码有效:
package container;
abstract class Figure {
public void draw(){};
public String getColor(){return null;};
protected abstract float getRadius();
}
class Square extends Figure{
@Override
public void draw(){
System.out.println("Square");
}
// zero radius for non-circle figures, for instance
// or you can throw UnsupportedOperationException here.
public float getRadius() { return 0;}
}
class Circle extends Figure{
@Override
public void draw(){
System.out.println("Circle");
}
public float getRadius(){
return 8;
}
}
public class Container {
public static void main(String[] args) {
Figure[] figures = new Figure[3];
figures[0]= new Circle();
figures[1]= new Circle();
figures[2]= new Square();
for(Figure figure:figures){
figure.getColor();
figure.draw();
figure.getRadius();
}
}
}
您可以尝试使用 try/catch:
来防止 ClassCastException
try {
((Circle) figure).getRadius();
} catch(ClassCastException e) {
//does nothing
}
在Figure中添加getRadius
,然后在square的实现中抛出一个UnsupportedOperationException
怎么样?
您想编写适用于所有类型 Figures
的代码,并且如果 Figure
是 Circle
或 Square
,您想要不同的行为。这就是他们发明多态性的原因。您的代码如下所示:
Figure f;
if (f is Circle) {
doFoo();
} else {
doBar();
}
相反,更好的方法如下:
interface Figure {
public void do();
}
class Circle implements Figure {
public void do() {
doFoo();
}
}
class Square implements Figure {
public void do() {
doBar();
}
}
那么你的代码就变成了:
Figure f;
f.do();
你为什么不在你的基础 class 中添加一个 enum FigureType
来标识 child class?
public static enum FigureType {
Square,
Circle
}
public static class Figure {
private FigureType type;
public Figure(FigureType type) {
this.type = type;
}
public FigureType getType() {
return type;
}
public void draw() {
}
public String getColor() {
return null;
}
}
您必须向每个 child class 添加一个默认构造函数,它使用 FigureType
.[=16 调用 parent class 构造函数=]
public static class Square extends Figure {
public Square() {
super(FigureType.Square);
}
@Override
public void draw() {
System.out.println("Square");
}
}
public static class Circle extends Figure {
public Circle() {
super(FigureType.Circle);
}
@Override
public void draw() {
System.out.println("Circle");
}
public float getRadius() {
return 8;
}
}
用法:
public static void main(String[] args) {
Figure[] figures = new Figure[3];
figures[0] = new Circle();
figures[1] = new Circle();
figures[2] = new Square();
for (Figure figure : figures) {
figure.getColor();
figure.draw();
if (figure.getType() == FigureType.Circle) {
((Circle) figure).getRadius();
}
}
}
结果:
Circle
Circle
Square
无一例外
我必须在 Java 中解决这个 "container problem"。我有一个由不同数字组成的数组,我希望下面的代码能够工作:
package container;
class Figure{
public void draw() {}
public String getColor() { return null; }
}
class Square extends Figure{
@Override
public void draw(){
System.out.println("Square");
}
}
class Circle extends Figure{
@Override
public void draw(){
System.out.println("Circle");
}
public float getRadius(){
return 8;
}
}
public class Container {
public static void main(String[] args) {
Figure[] figures = new Figure[3];
figures[0]= new Circle();
figures[1]= new Circle();
figures[2]= new Square();
for(Figure figure:figures){
figure.getColor();
figure.draw();
((Circle) figure).getRadius();
}
}
}
您可以看到有问题,因为 Square
没有 getRadius()
方法。我有以下限制:
- 不能使用泛型
- 无法使用
instanceof
这应该是一个不错的面向对象设计解决方案。
如果您不能使用 instanceof
,您可以在 Figure
class 中声明抽象方法,并为不需要它的图形添加虚拟实现。以下没有 instanceof
和 java 泛型的代码有效:
package container;
abstract class Figure {
public void draw(){};
public String getColor(){return null;};
protected abstract float getRadius();
}
class Square extends Figure{
@Override
public void draw(){
System.out.println("Square");
}
// zero radius for non-circle figures, for instance
// or you can throw UnsupportedOperationException here.
public float getRadius() { return 0;}
}
class Circle extends Figure{
@Override
public void draw(){
System.out.println("Circle");
}
public float getRadius(){
return 8;
}
}
public class Container {
public static void main(String[] args) {
Figure[] figures = new Figure[3];
figures[0]= new Circle();
figures[1]= new Circle();
figures[2]= new Square();
for(Figure figure:figures){
figure.getColor();
figure.draw();
figure.getRadius();
}
}
}
您可以尝试使用 try/catch:
来防止 ClassCastExceptiontry {
((Circle) figure).getRadius();
} catch(ClassCastException e) {
//does nothing
}
在Figure中添加getRadius
,然后在square的实现中抛出一个UnsupportedOperationException
怎么样?
您想编写适用于所有类型 Figures
的代码,并且如果 Figure
是 Circle
或 Square
,您想要不同的行为。这就是他们发明多态性的原因。您的代码如下所示:
Figure f;
if (f is Circle) {
doFoo();
} else {
doBar();
}
相反,更好的方法如下:
interface Figure {
public void do();
}
class Circle implements Figure {
public void do() {
doFoo();
}
}
class Square implements Figure {
public void do() {
doBar();
}
}
那么你的代码就变成了:
Figure f;
f.do();
你为什么不在你的基础 class 中添加一个 enum FigureType
来标识 child class?
public static enum FigureType {
Square,
Circle
}
public static class Figure {
private FigureType type;
public Figure(FigureType type) {
this.type = type;
}
public FigureType getType() {
return type;
}
public void draw() {
}
public String getColor() {
return null;
}
}
您必须向每个 child class 添加一个默认构造函数,它使用 FigureType
.[=16 调用 parent class 构造函数=]
public static class Square extends Figure {
public Square() {
super(FigureType.Square);
}
@Override
public void draw() {
System.out.println("Square");
}
}
public static class Circle extends Figure {
public Circle() {
super(FigureType.Circle);
}
@Override
public void draw() {
System.out.println("Circle");
}
public float getRadius() {
return 8;
}
}
用法:
public static void main(String[] args) {
Figure[] figures = new Figure[3];
figures[0] = new Circle();
figures[1] = new Circle();
figures[2] = new Square();
for (Figure figure : figures) {
figure.getColor();
figure.draw();
if (figure.getType() == FigureType.Circle) {
((Circle) figure).getRadius();
}
}
}
结果:
Circle
Circle
Square
无一例外