在另一个实例中引用实例化 class 但不允许在初始化后更改此类值

Referencing an instanced class inside another instance but not allowing change of such value after its been initialized

我是 Java 编程的新手,我目前正在做一项作业,我应该更改一些代码以允许在另一个中引用 class-实例实例,但不允许在初始化后对该值进行任何更改。还有一个 class 名为“Date”,我根本不允许更改它,所以我不会在这里 post 它。

这是我需要更改的 class。在此之下,我将写出我的测试代码来展示 ToDo 是如何工作的。

public class ToDo
{    
    private String what;
    private Date when;
    public ToDo (String what,int year,int month,int day)
    {
    this.what = what;
    when = new Date (year, month, day);
    }
    public String getWhat () { return what; }
    public Date getWhen () { return when; }
    public String toString ()
    {
    return "Todo: " + what + "; date: " + when.toString ();
    }
}

测试代码:

public class hej1{
    public static void main (String[] args){
    ToDo important = new ToDo ("Tentamen", 2022, 1, 10);
    System.out.println (important);
    Date d = important.getWhen ();
    d.setMonth (5);
    d.setDay (35);
    System.out.println (important);
    }
}

Output of test 正如您在测试 运行 中看到的那样,我目前可以在 ToDo-class 中更改 Date-class。我想让更改这些值成为非法,并且只允许在 ToDo class.

中引用日期值

我试过没有成功的是:

正在从日期中删除设置器-Class(不允许我这样做)。

尝试将 Date 设置为最终日期,这样我就无法在之后更改它的值(没有让它工作)。

现在我卡住了,有什么想法或解决办法可以让我的心平静下来吗?

我想这是封装赋值 - 重要的 OOP 概念之一。

private final Date when; 字段标记为 final 不起作用,因为这意味着对对象 when 的引用不会更改 - 尽管实例本身可能会更改。

所以 final 字段会阻止你做类似的事情:

public void setWhen(Date when) {
   this.when = when; // Compile-time error, this.when has been already initialized
}

解决方案

因为我们想要在 class 之外公开 Date,所以我们必须创建一个新副本:

public Date getWhen () {
    return new Date(when.getYear(), when.getMonth(), when.getDay());
}
// OR
public Date getWhen () {
    return new Date(when); // if your Date class have so called "copy" constructor
}

等价于 solution/view 可能根本不是在 ToDo 构造函数中创建 Date 实例,而是在 getWhen() getter.

这种方式以某种方式“突出”了封装——但在实践中,返回新实例将是首选方式(基于意见)。

public class ToDo {
    private final String what;

    private final int year;
    private final int month;
    private final int day;

    public ToDo(String what,int year,int month,int day) {
        this.what = what;
        this.year = year;
        this.month = month;
        this.day = day;
    }

    public Date getWhen() {
        return new Date(year, month, day);
    }

    public String toString() {
        return "Todo: " + what + "; date: " + getWhen().toString ();
    }
}