【问题标题】:Subclass error: CloneNotSupportedException never being thrown in the try body子类错误:永远不会在尝试正文中抛出 CloneNotSupportedException
【发布时间】:2018-10-22 19:04:39
【问题描述】:

我现在正在做一个关于继承和深度克隆的交接。

这个练习是关于使用继承和深度克隆的思想重写给我们的代码,使用一个将形状绘制到画布上的程序。

现在我已经为超类point 和我的子类group 实现了clone() 方法,但是当它编译时我总是在我的子类中得到一个CloneNotSupportedExceptionclone()真的不明白为什么。

这是我的超类的代码:

public abstract class Point implements Cloneable
{
public Point clone() 
    {
        try {
             Point copy = (Point)super.clone();
             copy.imgGroup = (ArrayList<Point>)imgGroup.clone();
             return copy;
        }
        catch (CloneNotSupportedException e) {
            throw new InternalError();
        }
     }
}

这是我的子类的代码:

public class Group extends Point implements Cloneable
{
public Group clone() 
    {
        try {
            Group copy = (Group)super.clone();
            copy.group = (ArrayList<Point>)group.clone();
            for (int i = 0; i < group.size(); i++) {
                copy.group.set(i,group.get(i).clone());
            }
            return copy;
        }
        catch (CloneNotSupportedException e) {
            throw new InternalError();
        }
    }
}

任务:

构造类Group。可以将某个Figure 对象添加到几个不同的组中。您必须确定同一个Figure 对象是否可以同时属于多个组。在本练习中,这不应该发生。所有Group 对象必须独占拥有它们的项目对象。不能在多个组之间共享对象。

因此,我们从添加方法开始:

public Figure class clone ();
// (define it in the same style as on page 4 in the document below)
// this was what point clone() was in the class Point.

在此之后有一些方法的实现说明和一个Group 克隆。

所以在这个任务中,我应该用各种方法实现Group 以及一个新的clone(),这就是我现在遇到的问题。

我希望你能帮助我指出正确的方向,只是想知道为什么会发生这种情况。谢谢!

【问题讨论】:

  • 可以分享一下作业要求吗?
  • 它是瑞典语,所以我会尝试翻译:
  • 如果Point真的应该是抽象的,那么就不要在Point中实现clone,而是让子类实现clone()。使用抽象类,您可以将继承的接口方法的实现推迟到具体的子类。
  • 这可能是题外话,但是否可以覆盖在Point 中声明的clone() Group

标签: java inheritance exception deep-copy


【解决方案1】:

我总是在我的子类中使用 clone() 得到一个 CloneNotSupportedException

我想你得到的是; Unreachable catch block for CloneNotSupportedException.

那是因为你在你的超类签名中省略了throws CloneNotSupportedException。但是,在子类中,您希望 super.clone() 抛出选中的 CloneNotSupportedException。将您的超类实现更改为;

public abstract class Point implements Cloneable {
    public Point clone() throws CloneNotSupportedException { 
        Point copy = (Point) super.clone(); 
        return copy;
    }
}

这样在超类签名中抛出的异常对子类可见。

更新

请关注下面的this comment 以获得更好的清晰度。

更新 2

添加更多详细信息,因为用户删除了另一个答案(我上面的评论所指的地方)。

您不能实例化抽象类 - 但您仍然可以在其中包含 clone() 方法。但是抽象类应该在其克隆方法中返回的具体克隆实例是什么?当您在抽象类中说thissuper.clone() 时,它们都在运行时引用同一个子类实例。这意味着浅拷贝 (Point copy = (Point) super.clone();) 在您的情况下是 Group 的一个实例。您可以在抽象超类的clone 方法中添加System.out.println(super.clone().getClass()) 来见证这一点。

因此,您可以在超抽象类中深度克隆可继承属性 - 并且 - 在子类的 clone() 方法中仅深度克隆子类的属性。这样,如果您定义了多个子类,就可以避免在所有子类中深度克隆超类属性。

【讨论】:

    猜你喜欢
    • 2021-08-10
    • 1970-01-01
    • 2020-06-06
    • 1970-01-01
    • 2021-11-11
    • 2015-03-28
    • 1970-01-01
    • 2017-07-01
    • 1970-01-01
    相关资源
    最近更新 更多