• Post Reply Bookmark Topic Watch Topic
  • New Topic

HAS-A relationship / Composition  RSS feed

 
Andy Perry
Greenhorn
Posts: 6
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,

I am just learning Java at the moment and am struggling with relationships between 2 classes.

I have my 2 classes and one of them has an attribute which is an instance of the other class, but where I am losing it is getting back the information from the second class to use as this attribute in the first.

So in my example, I have a RaceEvent Class and an Athlete class. My RaceEvent class will (hopefully!) include the full name of the Athlete who won this race. This is the attribute that I have set up as the link and I have defined it as:

private Athlete winningAthlete;

I have a method in the Athlete Class which simply concatenates firstName and surname and returns the fullname (with a space in the middle).

I have a method in the RaceEvent that allows the population of an event by passing in parameters for the attributes of RaceEvent, including what I would like to be the full name of the winning athlete.

So, I want to call the method in Athlete, whilst setting the event, and it store the full name as winningAthlete.

When I try to call the method, i get an error about incompatible types implying that String (for the returned full name) can not be converted to type Athlete. It makes sense, but I can't figure out how to get this information back from the method call and store it.

I hope I have explained it ok :-(

Thanks

Andy
 
Carey Brown
Saloon Keeper
Posts: 3329
46
Eclipse IDE Firefox Browser Java MySQL Database VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Can you post your code (with code tags)?
 
Paul Clapham
Sheriff
Posts: 22841
43
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Andy Perry wrote:So in my example, I have a RaceEvent Class and an Athlete class. My RaceEvent class will (hopefully!) include the full name of the Athlete who won this race. This is the attribute that I have set up as the link and I have defined it as:

private Athlete winningAthlete;

I have a method in the Athlete Class which simply concatenates firstName and surname and returns the fullname (with a space in the middle).

I have a method in the RaceEvent that allows the population of an event by passing in parameters for the attributes of RaceEvent, including what I would like to be the full name of the winning athlete.


You have two desires there which are conflicting. First of all your RaceEvent contains a reference to the Athlete who won the event. This makes a lot of sense in an object-oriented design. But then... you want the RaceEvent to contain only the name of the athlete who won the event? Why? You can always get the athlete's name whenever you want from the Athlete reference, and you can also get the athlete's age or club affiliation or whatever else you have in your Athlete class. So why would you limit yourself to keeping only the name in the RaceEvent class?

So what I'm saying here (in the absence of any code samples) is that you should just have your RaceEvent contain a reference to the Athlete who won. If you want to get the Athlete's name, well, you know how to do that.
 
Andy Perry
Greenhorn
Posts: 6
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks for the replies. Here is the code I have so far.

Class RaceEvent



Class Athlete



@Paul - I guess I just wanted the information about the winning athlete to make sense to people, and the best way I could think of that was a name rather than an ID, but I kinda see where this is where I am getting myself in a muddle and not understanding properly. I kind of know what I was after, but I couldn't get the concept, and I think you have answered why :-)

In a sense, I have answered the question asked of me by having this link between the classes, but what I am missing is the value in that attribute that allows the link to that Athlete.

I am still playing with the code, so whilst it currently compiles, there will likely be issues in there.

Thanks

Andy
 
Paul Clapham
Sheriff
Posts: 22841
43
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Well, from the data model point of view the RaceEvent needs to know the Athlete who won. The view part of your application would certainly want to display the athlete's name, and possibly other data about the athlete as well. But that's a question which you should address while designing the view, not while designing the model.

I used the words "model" and "view" there, and maybe you aren't familiar with those as technical terms. Have a look at Model–view–controller for a not too heavy-duty explanation; even the section headed "Components" should give you the general idea. The design rule which arises from that separation of concerns is that when you design the data structures, you shouldn't be concerned too much about exactly how data derived from them is going to be displayed to the user.
 
Andy Perry
Greenhorn
Posts: 6
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hmmm, ok but what I still don't get is how do i set the attributes of a race event and record such marker/reference/id or whatever links it to the actual athlete, as without putting anything in for this, to me it has no link. So I need to record who the winning athlete is, whether I use a name or something else.

If for example, I wanted to use the existing classes to get the first name of the winning athlete from a particular instance of RaceEvent, how does it know unless i give it some form of reference to the specific athlete?
 
Stefan Evans
Bartender
Posts: 1837
10
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
In terms of your Model objects, you look to have it right. An Event has a reference to the Athlete who won it.
Possibly what is explicitly missing is a method on event: public Athlete getWinningAthlete()
I kind of assumed it was there at first glance (because I always put getters/setters on attributes) but just in case...

Now if you are thinking down to a persistence layer (e.g. database) You could store Events (by id) in one table, Athletes (by id) in another, and use a foreign key reference from the Event Table to Athlete to indicate who won the event.
But that's the database. Those ids live there, but don't necessarily have to be in your model. In the object just HAVING that property is enough of a reference.

Did that answer your question?


 
Andy Perry
Greenhorn
Posts: 6
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I think so :-)

With regards to the missing method though, how would i "get" the winning Athlete if there is no athlete in there? This is what is baffling me...how do i tell that event who the winner is. I can't help thinking that before i get the winner, i need to set it within the event.

I do think that as you say, the model i have is what is required, but I can't get where the "link" is stored in the attribute winningAthlete.

So, if I created an object "Bill" as an instance of Athlete and then called the setNewAthlete method to populate Bill attributes, how do I do the same for a new event but populate "Bill" as a reference as the winning Athlete?

I think you are right with the Database thing. My thinking is along the lines of if I look in a table Event, I will see a reference which links to that same reference in Athlete and therefore I can form that link to a winning Athlete as it is stored there.

Maybe I will just submit what I have got, as that is only the first of 3 questions, all of which are due by mid-day tomorrow (or should I say today! )

Thanks

Andy
 
Carey Brown
Saloon Keeper
Posts: 3329
46
Eclipse IDE Firefox Browser Java MySQL Database VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Your RaceEvent.setNewEvent() method looks like it should have been the RaceEvent constructor. There is also an implication that a RaceEvent HAS-A 'numberOfAthletes' leading me to think that the RaceEvent object should have a Collection (e.g. ArrayList) of Athlete objects. You may then need an add(Athlete) method to add Athletes to the collection.

You are missing a third class (your controller) that has a main() method and perhaps prompts a user for the data or perhaps the data is (for now) hard coded. This controller class will be responsible for creating instances of Athlete objects and a RaceEvent object and also be responsible for presenting your data to the user. This 'link' you are confused about is currently being passed in to the setNewEvent() method. This 'link' would be passed in to the RaceEvent.setNewEvent() method from whatever controller class you decide to make. This reference (a better name than 'link') is generated when you invoke: "new Athlete(...)", again, in your controller class.
 
Andy Perry
Greenhorn
Posts: 6
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks Corey,

Yes, the method currently serves as a way to test the program and populate an instance of the object. We are using an IDE as part of the course where we can enter commands, and the idea behind that was a method where I could run a command and pass the values in order to create a 'record' so to speak. So, by default, the constructor would only complete the odd 1 or 2 values (and those are only really in to be honest to satisfy the requirements of the question).

It is this command that I was trying to run and pass "something" for the end parameter which would hopefully bond the reference to a specific Athlete, and this is where I was getting confused :-(

I have seen the 3rd class on other posts and was wondering about that, and this is making sense, but what it is making me think is that for the purpose of the question I have, I believe I only need to provide that reference in the constructor, which is what I currently have, as the question only ever mentions to write 2 classes. So I think what I am trying to make it do is actually beyond the scope of the question.

However, this is great, as it is starting to make sense now, and at least for my own sanity, I can work on this third controller class to test the functionality further. I am sure it will creep in to the further assignments we get, including inheritance! :-)

Thanks everyone for the help, and I'm sure I will be back soon!

Andy
 
Junilu Lacar
Sheriff
Posts: 11494
180
Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Good object orientation is about assigning responsibilities properly. Let's look at some of the responsibilities that you're trying to figure out:

1. Who should know the Athlete's name?
2. Who should know the Athlete's rank?
3. Who should know if a new record has been set?
4. Who should know if an Athlete is a record holder?

It makes sense for the Athlete to know its own name. Any other object that needs that name should just ask the Athlete.

Should an Athlete know its own rank? Is that a property that's intrinsic to an Athlete? I would say it's not. Rank is relative to other Athletes. Should the Event know the Athlete's rank? Maybe. Are we talking about the rank for a particular event, e.g. who can in first, second, third, etc. or is this a rank of all athletes who have ever participated in this event? If the former, then you probably should have a list of Athletes who participated in the event rather than just the winner. This way, you can compare the times of all the participating Athletes and then declare a winner. The rank really should be a calculated value, not a value that is given to the Event. If you have an Event hold a list of Athletes participating in the event, the number of participants can also be calculated from the list of Athletes instead of being set via a setter method.

If the latter, that is you want to know what the rank of an Athlete is relative to all Athletes who have ever ran that particular event, then you should probably have an EventHistory that stores a record of all events and can calculate over this cumulative record where a given Athlete stands among all the other Athletes who have participated in the Event. It also makes more sense if the EventHistory class is the one that can say whether or not a new record has been set because it has information about all events that have been run and can do the calculation based on that information.

As for knowing if a particular Athlete is a record holder, well that depends. Are you wanting to know if the Athlete is a current record holder or a past record holder? It shouldn't be the Athlete who is responsible for answering this since again, this is not an intrinsic attribute of Athlete but rather something determined relative to other information. Besides, some athletes are quite egotistical and will always answer "Yes" to that question Also, being a record holder could change over time as new records are set. Again, I would probably prefer to have the EventHistory answer this question, e.g.:
 
Andy Perry
Greenhorn
Posts: 6
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,

I don't need to know any of this, it is just answering a question in an assignment.

The main objectives of the question was to have 2 classes, each having setters and getters along with a suitable amount of attributes relevant to the class, and for which one had an attribute which referenced the other class to form a composition type relationship.

I am sure that I could have developed this MUCH better, but I don't need to, as I just needed to satisfy the question.

All I was wanting to know was how I set a "reference" to the winning athlete in the event (which was the reference to satisfy the question) so that it was possible for "someone" i.e. me to inspect the object and to check that I was correctly referencing the winner of the event.

I also wanted to know how (assuming I am the user by means of testing my code) could find out who the winner is. I assume I should know since I wrote the code, and at this stage I have no need to implement security over who should or shouldn't see the information, just how I COULD do it so that I could test and make sure that reference was indeed correct allowing me to be able to get at the information should I desire.

As for Rank, it was just created as an attribute as a "possible" attribute that would likely be included for an Athlete. It was intended as a Rank of the person, in other words, that person is ranked number 1 in the world, for example, but the intention wasn't there to go so deep. I just wanted to get at the information I had irrelevant as to whether it was legally or politically or logistically correct.

However, If I should ever need to design a full system for this type of scenario, then of course the information is extremely useful and I would certainly consider in much more detail.

Thanks

Andrew
 
Junilu Lacar
Sheriff
Posts: 11494
180
Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Andy Perry wrote:
The main objectives of the question was to have 2 classes, each having setters and getters along with a suitable amount of attributes relevant to the class, and for which one had an attribute which referenced the other class to form a composition type relationship.

Well, that's kind of what I was getting at with assigning responsibilities properly. You asked "how do I tell that event who the winner is" -- the answer is "You don't." It's better if you give the event the information it would need to calculate who the winner is. As Corey was saying, you should probably have a collection of Athletes who participated in the event and you should have a way to tell the event (like a setter or something) what each athlete's time for that event was. Then the event can calculate the winner and even give back a reference to that particular Athlete.

The relationship that makes most sense here is "an Event has a group of participating Athletes". Whether this is aggregation or composition is a different discussion.
 
It is sorta covered in the JavaRanch Style Guide.
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!