I'm very new to Java programming and I'm currently doing an assignment where I'm supposed to change a bit of code to allow reference of a class-instance within another instance but not allow any change of this value after its been initialized. There is another class named "Date" which I'm not allowed to change at all so I will not post it here.
This is the class that i need to change. Under this i am going to write out my test-code to show how ToDo works.
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 ();
}
}
Test-code:
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 As you can see in the test run I am currently allowed to change the Date-class within ToDo-class. I want to make changing these values illegal and only allow referencing the Date values within the ToDo class.
What I have tried without success is:
Removing setters from Date-Class(i was not allowed to do this).
Trying to make Date a final so that I cant change value of it after(didnt make it work).
Now I am stuck, any ideas or solutions that can make my mind go to peace?
I guess this is assignment for encapsulation - one of important OOP concepts.
Marking private final Date when;
field as final
does not work as this means that reference to object when
won't change - though instance itself might be change.
So final
field would prevent you doing something like:
public void setWhen(Date when) {
this.when = when; // Compile-time error, this.when has been already initialized
}
As we want to expose Date
outside of class we must to create a new copy:
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
}
Equivalent solution/view might be, not to create Date
instance at all in ToDo
constructor, but in the getWhen()
getter.
This way somehow "highlights" encapsulation - but in practice, returning new instance would be preferred way (opinion based).
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 ();
}
}