【问题标题】:Referencing an instanced class inside another instance but not allowing change of such value after its been initialized引用另一个实例中的实例类,但在初始化后不允许更改此类值
【发布时间】:2021-12-28 17:52:08
【问题描述】:

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

这是我需要更改的课程。在此我将写出我的测试代码来展示 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 类中更改日期类。我想更改这些值是非法的,并且只允许在 ToDo 类中引用 Date 值。

我没有成功的尝试是:

从 Date-Class 中删除 setter(我不允许这样做)。

试图让 Date 成为最终的,这样我就不能在之后更改它的值(没有让它工作)。

现在我被困住了,有什么想法或解决方案可以让我平静下来吗?

【问题讨论】:

  • getWhen() 可以返回when 的副本吗?
  • 也更喜欢最新的 java.time.LocalDate 而不是旧的 java.util.Date

标签: java reference constants instance


【解决方案1】:

我猜这是对封装的赋值——重要的 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
}

解决方案

由于我们想在课堂之外公开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
}

等效的解决方案/视图可能是,根本不在 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 ();
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-05-11
    • 1970-01-01
    • 1970-01-01
    • 2018-08-14
    • 2014-11-09
    • 1970-01-01
    相关资源
    最近更新 更多