I’m building a “Contact Manager” in Java.
I have a superclass called “Contact which has two base classes; PersonalContact and BusinessContact.
I have an interface called Event, which is implemented by classes Birthday and Meeting. (Birthday contains one DateTime object while Meeting has two for start and end time).
PersonalContact holds a TreeSet of Birthdays and BusinessContact holds a set of Meetings.
Now, in the superclass Contact, I want to create an abstract method called “getEventsWithinPeriod()” which will return a TreeSet of all birthdays and/or meetings within a given time span.
The problem is, I don’t know how to tell the abstract method, and then the base class methods what to return.
For example, this is the code I used in Contact;
public abstract Set<Event> getEventsWithinPeriod(DateTime start, DateTime end);
And in PersonalContact;
public Set<Birthday> getEventsWithinPeriod(DateTime start, DateTime end){
Set<Birthday> birthdaysThatAreWithin = new TreeSet<Birthday>();
//CODE
return birthdaysThatAreWithin;
However, in the compiler, I’m getting an error on Set<Birthday> saying;
“The return type is incompatible with Contact.getEventsWithinPeriod(DateTime, DateTime)”
What are the proper terms and returns I should be using? Why is my current attempt wrong?
You have 3 solutions.
Solution 1
First, you can make your classes generic, like so:
And then in your concrete implementation:
This is the best solution, but you have some alternatives.
Solution 2
You can change the type of your
birthdaysThatAreWithinfield:as well as change the method signature:
and return it like that. This restricts you because you can’t use the events as
Birthdayinstances anymore.Solution 3
You could also change your method signature (in both your abstract and concrete class) to this:
and not change anything else. This has the same problem as solution 2, you won’t be able to use the events as
Birthdayinstances without casting them.Edit: the downsides to 2 and 3 are that they will require casting. For example:
With the first solution, you’d have this:
The code looks cleaner and runs better because you don’t have to do
instanceofchecks to make sure you don’t get aClassCastException. You can also have stuff like this:And if you ever have another implementation of
Contactthat hasBirthdayevents, you can pass them to thatprocessBirthdaysFormethod without making any changes.However, if you only need the events and you don’t care what the types are in the code calling your
Contact.getEventsWithinPeriod, then solutions 2 and 3 are definitely your best bets. I’d personally just use solution 2 if this was the situation.