如何添加方法并截获来自不同类的私有字段



我正在尝试引入一个Shape类作为类CircleRectangle的父接口。我必须实现getName()方法,该方法将为Circle对象返回Circle,为Rectangle对象返回Rectangle。此外,我必须在CircleRectangle类中重写toString()方法。toString方法将调用getName()方法,并将生成一个表示对象的字符串,如下所示:

  • 半径为 2 的Circle表示为"Circle(2)"
  • 宽度为 2 且高度为 10 的Rectangle表示为"Rectangle(2, 10)"

另外,我无法修改类ShapeRectangleCircleMain,您可以在下面找到代码。我不确定如何做到这一点。有人可以帮我吗?

这是我到目前为止所做的:

形状.java

public interface Shape {
String getName();
double getPerimeter();
double getArea();
}

矩形.java

public class Rectangle {
private double width, height;
public Rectangle(double width, double height) {
this.width = width;
this.height = height;
}
public double getPerimeter() {
return 2 * (this.width + this.height);
}
public double getArea() {
return this.width * this.height;
}
}

圈子.java

public class Circle{
private double radius;
public Circle(double radius) {
this.radius = radius;
}
public double getPerimeter() {
return 2 * Math.PI * this.radius;
}
public double getArea() {
throw new RuntimeException("Oops, I don't know how to calculate this :(");
}
}

问题.aj

public aspect Question {
declare parents: Rectangle implements Shape;
declare parents: Circle implements Shape;

public String Rectangle.getName(){
return "Rectangle";
}

public String Circle.getName(){
return "Circle";
}

public String Rectangle.toString(){
return Rectangle.getName()+"(" + this.width +", " + this.height +")";
}

public String Circle.toString(){
return Circle.getName() + "(" + this.radius + ")";
}
}

主.java

public class Main {
public static void main(String[] args) {
try {
Shape s;
s = (Shape) new Rectangle(2, 10);
System.out.println("The area of " + s + " is " + s.getArea());
s = (Shape) new Rectangle(-2, 10);
System.out.println("The perimeter of " + s + " is " + s.getPerimeter());
s = (Shape) new Circle(-2);
System.out.println("The perimeter of " + s + " is " + s.getPerimeter());
s = (Shape) new Circle(2);
System.out.println("The area of " + s + " is " + s.getArea());
}
catch(Exception e) {
System.out.println("Error: " + e.getMessage());
}
}
}

我正在尝试引入一个 Shape 类作为 类 圆形和矩形

为此,您需要使用类型间声明AspectJ静态横切功能,该功能允许更改类的结构,即添加新方法,使类实现接口等。您正确完成的操作:

declare parents: Rectangle implements Shape;
declare parents: Circle implements Shape;

我必须实现 getName() 方法,该方法将返回 "圆" 圆形对象和矩形对象的"矩形"。

你也做对了:

public String Rectangle.getName(){
return "Rectangle";
}
public String Circle.getName(){
return "Circle";
}

另外,我必须在 Circle 和 Rectangle>类中重写 toString() 方法。

你也做对了:

public String Rectangle.toString(){ (...)}
public String Circle.toString(){ (...)}

toString 方法将调用 getName() 方法并将生成 表示对象的字符串,如下所示: 半径为 2 的圆 表示为"Circle(2)"矩形,宽度为 2,高度为 10 表示为"矩形(2, 10)"。

这一步你做错了:

public String Rectangle.toString(){
return Rectangle.getName()+"(" + this.width +", " + this.height +")";
}
public String Circle.toString(){
return Circle.getName() + "(" + this.radius + ")";
}

你有两个问题,

  1. 方法getName()不是静态的,因此更改两者Rectangle.getName()Circle.getName()this.getName();

  2. 字段widthheightradius私有的。因此,您不能简单地从这样的方面访问它们。从源头:

在方面编写的代码受与 引用类或方面的成员时的 Java 代码。所以,对于 例如,在某个方面编写的代码可能不引用具有 默认(受包保护)可见性,除非在 中定义了方面 相同的包。

虽然这些限制适用于许多方面,但可能存在 建议或类型间成员需要访问的某些方面 其他类型的私有或受保护资源。为了允许这一点,方面 可以宣布特权。特权方面的代码可以访问 所有成员,甚至是私人成员。

解决此问题,您(至少)有 3 个选项:

  1. 公开这些字段;
  2. 使方面Question特权;
  3. 为这些私人领域制作吸气剂。

OOP封装的角度来看,第三种选择是最好的。看起来像这样:

在类Rectangle添加widthheight字段的 getter:

public double getWidth() {return this.width;}
public double getHeight() {return this.height;}

并在类中添加Circleradius字段的 getter:

public double getRadius() {return this.radius;}

最后,相应地调整方面Question

public String Rectangle.toString(){
return this.getName()+"(" + this.getWidth() +", " + this.getHeight() +")";
}
public String Circle.toString(){
return this.getName() + "(" + this.getRadius()+ ")";
}

另外,我无法修改形状,矩形,圆形或主类, 您将在下面找到代码。

好吧,这不包括方法1)(无论如何都很糟糕)和3)(作为最好的IMO)。

因此,您可以使方面Question特权

privileged public aspect Question

我同意一些作者的相同观点:

  • J. D. Gradecki和N. Lesiecki.在《掌握AspectJ:Java中面向方面编程》一书中。
  • R. Laddad. 在《AspectJ in Action: Enterprise AOP with Spring Applications》一书中。

应尽可能避免特权方面,因为它们在方面和类之间增加了 an
固有依赖关系,并且它们规避了应用于该目标类的可见性规则。

最新更新