Java:两个相似的类,一个不可变的,它们之间共享代码
假设我有两门课。两者都有相同的成员字段(包括相同的名称),但一个类的成员字段声明为final(不可变),而另一个不是final。大多数成员方法都适用于这两个类 我如何与另一个类共享不可变类的成员方法(好像通过继承或其他方式),而不必将整个方法复制到另一个类中。我想没有这样的办法,但我想我应该先问一下。否则,我将在不同的名称空间中声明它们,并给它们相同的类名。应该注意的是,并非所有的不可变类方法都适用于可变类Java:两个相似的类,一个不可变的,它们之间共享代码,java,class,immutability,sharing,Java,Class,Immutability,Sharing,假设我有两门课。两者都有相同的成员字段(包括相同的名称),但一个类的成员字段声明为final(不可变),而另一个不是final。大多数成员方法都适用于这两个类 我如何与另一个类共享不可变类的成员方法(好像通过继承或其他方式),而不必将整个方法复制到另一个类中。我想没有这样的办法,但我想我应该先问一下。否则,我将在不同的名称空间中声明它们,并给它们相同的类名。应该注意的是,并非所有的不可变类方法都适用于可变类 public class ImmutableDoubleLine { publi
public class ImmutableDoubleLine {
public final DoublePoint origin;
public final DoublePoint endPoint;
// ...
public double getLength() {
return origin.calcDistance(endPoint);
}
}
public class MutableDoubleLine {
public DoublePoint origin;
public DoublePoint endPoint;
// ...
// same code as immutable class
public double getLength() {
return origin.calcDistance(endPoint);
}
}
为什么要将字段声明为公共字段 只需将它们设置为私有,并仅在派生类中添加setter。不可变类没有setter,字段必须在构造函数中设置
通过这种方式,您不需要将DoublePoint设置为final,但要小心,如果您返回的是DoublePoint而不是final,则必须返回它们的防御性副本。为什么要将字段声明为public 只需将它们设置为私有,并仅在派生类中添加setter。不可变类没有setter,字段必须在构造函数中设置
通过这种方式,您不需要将DoublePoint设置为最终版本,但要注意,如果您返回的是最终版本而不是最终版本,则必须首先返回它们的防御性副本。这一点非常重要 除非类
DoublePoint
是内部不可变的,并且它的所有实例变量都是内部不可变的,使用最终DoublePoint origin
语句所做的只是将引用设置为origin
和端点
,如果它们不能更改为指向不同的实例,则不设置为不可变doubleline
不可变
我之所以提到这一点,是因为您没有显示DoublePoint
的代码
第二,针对您的实际问题,使用接口
,并让两个类都实现它:
public interface DoubleLine
{
public double getLength();
}
我会尽可能地使所有内容都不可变,这使调试更容易,并发性也更容易。首先,这一点非常重要 除非类
DoublePoint
是内部不可变的,并且它的所有实例变量都是内部不可变的,使用最终DoublePoint origin
语句所做的只是将引用设置为origin
和端点
,如果它们不能更改为指向不同的实例,则不设置为不可变doubleline
不可变
我之所以提到这一点,是因为您没有显示DoublePoint
的代码
第二,针对您的实际问题,使用接口
,并让两个类都实现它:
public interface DoubleLine
{
public double getLength();
}
我会尽可能使所有内容都不可变,这会使调试更容易,并发性也更容易。使用组合。让其中一个类保存另一个类的实例,并将成员方法传递给内部实例。这是一种门面类。使用合成。让其中一个类保存另一个类的实例,并将成员方法传递给内部实例。这是一种facade类。使它们都继承自抽象类
AbstractDoubleLine
,向该类添加两个抽象方法getOrigin()
和getEndPoint()
,并使用这些getter实现所有常用方法
不可变类的getter当然应该通过使DoublePoint实例不可变或通过防御复制来保证其不可变。使它们都从抽象类继承
AbstractDoubleLine
,向该类添加两个抽象方法getOrigin()
和getEndPoint()
,并使用这些getter实现所有常用方法
不可变类的getter当然应该保证DoublePoint实例的不可变性,或者通过使它们不可变,或者通过防御性复制。在不可变类中,使它们更容易公开。在可变类中,它们可能是私有的。不过,这个概念仍然是一样的。我仍然希望在它们之间共享代码,但只共享其中的一些方法。而且,在需要时不要忘记防御性复制。您需要做更多的工作来创建可变类中的getter(如果需要)和setter,但除此之外,所有代码都可以共享。@ratchetfreak是的,我正在编辑这方面的内容。我不确定他是否想直接返回对象,但如果他需要,他需要创建一个副本,否则另一个类可能会使用get请求您的DoublePoint,然后开始修改它们的状态。除非它们是不可变的,而它们很可能是不可变的。在这种情况下,防御副本是不必要的。在immutable类中,它将使它们更容易公开。在可变类中,它们可能是私有的。不过,这个概念仍然是一样的。我仍然希望在它们之间共享代码,但只共享其中的一些方法。而且,在需要时不要忘记防御性复制。您需要做更多的工作来创建可变类中的getter(如果需要)和setter,但除此之外,所有代码都可以共享。@ratchetfreak是的,我正在编辑这方面的内容。我不确定他是否想直接返回对象,但如果他需要,他需要创建一个副本,否则另一个类可能会使用get请求您的DoublePoint,然后开始修改它们的状态。除非它们是不可变的,而它们很可能是不可变的。在这种情况下,不需要防御副本。DoublePoint是不可变的。但这超出了问题的范围。在可变双线中,点可以是可变线