继承时克隆方法,复制构造函数和getter方法之间的混淆

时间:2012-02-29 19:51:02

标签: java

我创建了一个类似于此的位置:

package TruckingCompany;

public class Location 
{
    private double x;
    private double y;
    private static final double xMax=1000.0;
    private static final double xMin=-1000.0;
    private static final double yMax=1000.0;
    private static final double yMin=-1000.0;
    public Location()
    {
        setX(0.0);
        setY(0.0);
    }
    public Location(double x,double y)
    {
        setX(x);
        setY(y);
    }
    public Location(Location location)
    {
        setX(location.getX());
        setY(location.getY());
    }
    public void setX(double x)
    {
        if(x>=xMin && x<=xMax)
        this.x=x;
    }
    public void setY(double y)
    {
        if(y>=yMin && y<=yMax)
        this.y=y;
    }
    public void set(double x,double y)
    {
        setX(x);
        setY(y);
    }
    public double getX()
    {
        return x;
    }
    public double getY()
    {
        return y;
    }
    public double getDistanceFrom(Location from)
    {
        double dx,dy;
        dx=getX()-from.getX();
        dy=getY()-from.getY();
        return Math.sqrt(Math.pow(dx, 2.0)+Math.pow(dy, 2.0));
    }
    @Override
    public String toString()
    {
        return "(" + x + " , " + y + ")";
    }
}

所以基于这个类,我想制作一个继承自Location的类车。 但它也必须实现一个接口(我称之为Movable),因为从Vehicle我想要制作其他类,然后公司(我的项目模拟货运公司)可以使用VehicleList of Vehicles。我需要使用标记<T implements Movable>调用方法,这就是我创建界面的原因。

所以这是类车辆:

package TruckingCompany;

public class Vehicle extends Location,implements Movable
{
public void setLocation(Location location)
{
    set(location.getX(),location.getY());
}
public Location getLocation()
{
    return new Location(getX(),getY());
}
}

这是Movable接口:

package TruckingCompany;

import java.sql.Time;

public interface Movable 
{
public void setLocation(Location location);
public Location getLocation();
public void move(Time howLong);
public void setDirection(double degrees);
public Time getReachingTime(Location to);
}

将getLocation作为getter方法是正确的吗?它不应该是一个克隆? 我也可以实现Cloneable,并使其成为克隆方法。 另一种选择可能是使其成为复制构造函数而不是getter方法。 务实地说,哪些选项是正确的?

3 个答案:

答案 0 :(得分:1)

从其他人的观察开始,不要扩展位置。

除了Vehicle之外,您还要制作Movable以外的任何其他内容吗?如果没有,你只是想制作几个具体的Vehicle子类,那么我只需将Movable重命名为Vehicle。如果您想使抽象类AbstractVehicle具有基本Vehicle实现,您可以这样做。然后,只需将所有车辆类型设为Vehicle(或扩展AbstractVehicle)的具体实现。

另外,根据您在C ++中的问题标题和经验,您可能会考虑使用不像Java中常见的C ++习语。复制构造函数 - 尽管可能并且有时用Java创建 - 在Java中不是普通的习惯用法。特别是,我觉得很奇怪你会为Location创建一个。您实际上想要通过创建现有位置的精确副本来解决问题的频率是多少?也许你有一个用例,但它并没有突然出现,因为很明显为什么这会有用或有必要。位置应该是不可变的,并且当位置发生变化时,车辆应该获得新的位置。

答案 1 :(得分:0)

如果您需要安全发布,请制作Location immutable

另外,通过Vehicle 扩展 Location,您说车辆位置,听起来不对。相反,车辆位置,因此我建议您让车辆拥有私人Location字段,延伸Location

答案 2 :(得分:0)

虽然您可以在Movable类中使用set和get方法,但这两个函数否定了在Vehicle类中扩展Location的优势。我的建议是不要扩展位置,而是将其保留为变量。

public class Vehicle implements Movable {
    ...
    private Location myLocation;
    ...
}

这应提供与以前相同的功能,但强制执行车辆具有位置但不是位置的想法,并且可以随意修改位置而无需修改车辆本身。