不同类型的访问方法
Access methods on different types
我有这样的东西:
Figures fig = new Line();
在哪条线上延伸图。图是一个抽象 class,只有一个方法 getType()
通过返回 String
告诉我它是哪个图;
我有 3 种类型,Rectangle
、Circle
和 Figure
。他们都扩展了 Figures
.
现在是真正的问题。我将每一个都存储在 List<Figures>
中,我想访问每个对象的某些方法,例如 getStartX()
;和 getStartY()
;而且我不能,我也只能访问 Figures
上的方法。
您的摘要 class 应该定义 getStartX
和 getStartY
方法。如果您希望 Rectangle
、Circle
和 Figure
具有不同的行为并强制它们使用 Override
这些方法,则可以抽象。否则只需将方法放在 Figures
中即可使用(使用适当的关键字:public
/protected
,具体取决于您的需要)。
如果您想使用特定于 class 的方法,您需要检查它是哪个实例。像
for (Figures figure: myList) {
int x = figure.getStartX(); // Method common and declared in Figures
if (figure instanceof Circle) {
System.out.println("Oh no a Circle!");
int radius = ((Circle)figure).getRadius();
...
}
}
对于您的 Rectangle/Line,您可以使用 2 种方法定义接口:
public interface HasEndpoints {
int getEndX();
int getEndY();
}
public class Rectangle implements HasEndpoints {
...
public int getEndX() {return endx;}
...
}
for (Figures figure: myList) {
int x = figure.getStartX(); // Method common and declared in Figures
if (figure instanceof HasEndpoints) { // Rectangle and Line will go there
System.out.println("HasEndpoints implementor");
int endX = ((HasEndpoints)figure).getEndX();
...
}
}
您可以将 instanceof
与 if...else
一起使用并动态投射您的对象
Figure fig = new //Circle()/Triangle()/Rectangle();
if( fig instanceof Circle) {
((Circle) fig).getRadius(); //This method is only available in Circle class
}
getStartX()
和 getStartY()
应该在 Figure
class 中声明,或者您需要将对象转换为 Line
class:
Figure figure = figures.get(0);
if ("line".equals(figure.getType())) {
Line line = (Line)figure;
}
另一种选择是使用反射。但是您仍然需要确定,请求的方法可以被调用。
您总是可以将图形转换为线,但不是最佳选择。根据问题,您可以应用 Visitor Pattern 或将这些方法添加到 Figure,即使 Circle 没有起点和终点。
例如
public abstract class Figure{
public abstract void visit(FigureVisitor visitor);
}
public class Line extends Figure{
public void visit(FigureVisitor visitor){
visitor.visitLine(this);
}
}
public interface FigureVisitor{
public void visitLine(Line figure);
public void visitCircle(Circle figure);
}
public class StartingPointsVisitor implements FigureVisitor{
private Double startX;
private Double startY;
private Double endX;
private Double endY;
public void visitLine(Line figure){
this.startX = figure.getStartX(); //No cast needed
...
}
public void visitCircle(Circle figure){
//Stub-method
}
//Getters to read the results
}
是一个更复杂的解决方案,但正如我所说,这取决于问题,并且大部分复杂性仍然存在于 Visitor
我有这样的东西:
Figures fig = new Line();
在哪条线上延伸图。图是一个抽象 class,只有一个方法 getType()
通过返回 String
告诉我它是哪个图;
我有 3 种类型,Rectangle
、Circle
和 Figure
。他们都扩展了 Figures
.
现在是真正的问题。我将每一个都存储在 List<Figures>
中,我想访问每个对象的某些方法,例如 getStartX()
;和 getStartY()
;而且我不能,我也只能访问 Figures
上的方法。
您的摘要 class 应该定义 getStartX
和 getStartY
方法。如果您希望 Rectangle
、Circle
和 Figure
具有不同的行为并强制它们使用 Override
这些方法,则可以抽象。否则只需将方法放在 Figures
中即可使用(使用适当的关键字:public
/protected
,具体取决于您的需要)。
如果您想使用特定于 class 的方法,您需要检查它是哪个实例。像
for (Figures figure: myList) {
int x = figure.getStartX(); // Method common and declared in Figures
if (figure instanceof Circle) {
System.out.println("Oh no a Circle!");
int radius = ((Circle)figure).getRadius();
...
}
}
对于您的 Rectangle/Line,您可以使用 2 种方法定义接口:
public interface HasEndpoints {
int getEndX();
int getEndY();
}
public class Rectangle implements HasEndpoints {
...
public int getEndX() {return endx;}
...
}
for (Figures figure: myList) {
int x = figure.getStartX(); // Method common and declared in Figures
if (figure instanceof HasEndpoints) { // Rectangle and Line will go there
System.out.println("HasEndpoints implementor");
int endX = ((HasEndpoints)figure).getEndX();
...
}
}
您可以将 instanceof
与 if...else
一起使用并动态投射您的对象
Figure fig = new //Circle()/Triangle()/Rectangle();
if( fig instanceof Circle) {
((Circle) fig).getRadius(); //This method is only available in Circle class
}
getStartX()
和 getStartY()
应该在 Figure
class 中声明,或者您需要将对象转换为 Line
class:
Figure figure = figures.get(0);
if ("line".equals(figure.getType())) {
Line line = (Line)figure;
}
另一种选择是使用反射。但是您仍然需要确定,请求的方法可以被调用。
您总是可以将图形转换为线,但不是最佳选择。根据问题,您可以应用 Visitor Pattern 或将这些方法添加到 Figure,即使 Circle 没有起点和终点。
例如
public abstract class Figure{
public abstract void visit(FigureVisitor visitor);
}
public class Line extends Figure{
public void visit(FigureVisitor visitor){
visitor.visitLine(this);
}
}
public interface FigureVisitor{
public void visitLine(Line figure);
public void visitCircle(Circle figure);
}
public class StartingPointsVisitor implements FigureVisitor{
private Double startX;
private Double startY;
private Double endX;
private Double endY;
public void visitLine(Line figure){
this.startX = figure.getStartX(); //No cast needed
...
}
public void visitCircle(Circle figure){
//Stub-method
}
//Getters to read the results
}
是一个更复杂的解决方案,但正如我所说,这取决于问题,并且大部分复杂性仍然存在于 Visitor