在另一个实例中引用实例化 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 ();
}
}
我是 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 ();
}
}