• Post Reply Bookmark Topic Watch Topic
  • New Topic

calling methods and instantiating objects  RSS feed

 
nick woodward
Ranch Hand
Posts: 382
12
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

** oops, just filling the arrays quickly...... hang on....

I think I'm getting myself confused either with method calls generally, or with when objects are instantiated. If anyone could spare a sec it would be great to get a bit of insight into why this code isn't working:

I have two classes, MonsterGame (shown below) and Monster. Monster has a public accessor method to get it's private character variable, which represents the first character of the name of the Monster in question.

I'm just a bit confused as to why am I unable to cycle through the array of Monsters I have in the MonsterGame class and call

m.getCharacter(); (pretty much the last line of code)




I understand that there need to be instances of objects to call methods, but is that not the case here? the Monster objects are have already been created, no?

Do I need to create an index for the array? is the for loop not enough?

No doubt I'm approaching this the wrong way!



 
Paul Clapham
Sheriff
Posts: 22835
43
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I dunno -- that looks sort of okay to me, I guess. So you think you have a problem? Why? What is it that makes you think that?
 
nick woodward
Ranch Hand
Posts: 382
12
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Paul Clapham wrote:I dunno -- that looks sort of okay to me, I guess. So you think you have a problem? Why? What is it that makes you think that?



actually, the easiest way to sum it up is that I'm constantly running into trouble when trying to call a public method in another class.

if 'game' is an instance of MonsterGame that I instantiate using 'MonsterGame game = new MonsterGame()' in the main method, and in the Monster constructor, I call game.increaseMonsterCount() (which is a public method of MonsterGame that changes a private variable), the compiler treats 'game' as a variable of Monster, rather than a call to the method

So I get the error 'symbol not found'

**edit:

if I make the method and variable static and call MonsterGame.increaseMonsterCount() it works, but is that the right solution?
 
Junilu Lacar
Sheriff
Posts: 11494
180
Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
nick woodward wrote:
if 'game' is an instance of MonsterGame that I instantiate using 'MonsterGame game = new MonsterGame()' in the main method, and in the Monster constructor, I call game.increaseMonsterCount() (which is a public method of MonsterGame that changes a private variable), the compiler treats 'game' as a variable of Monster, rather than a call to the method

So I get the error 'symbol not found'

**edit:
if I make the method and variable static and call MonsterGame.increaseMonsterCount() it works, but is that the right solution?

No, it probably isn't the right solution.

A Monster has no business calling the increaseMonsterCount method of a Game object. In fact, the increaseMonsterCount method probably shouldn't be public at all. Since the count of monsters in a Game is an internal state that the Game should be managing itself, only the Game itself should call increaseMonsterCount. That is, whenever a Game creates a new Monster, it should increment its internal state to reflect the new count. Thus, your Game class should have the following code in it:

The effect of this code is essentially what you intended except now the responsibility of calling the increaseMonsterCount method is in the correct place, the Game class, not the Monster class.

This is what object-oriented programming is about: behaviors and responsibilities. These are assigned appropriately in good OO programs.
 
Mike. J. Thompson
Bartender
Posts: 689
17
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Making things static may seem like it works but it is almost always the wrong thing to do. The very first program I wrote was a game of Othello, and I ended up making everything static too just because it worked. Functiinally it did work fine, but as a design principle its wrong.

When you make something static it belongs to the class, not instances of the class. All instances of the class can see the same variable. In your case this means that if you were to have multiple MonsterGame instances they would all share the same monster count. This would mean that the count would either be wrong for some of the games, or all games would have to have exactly the same number of monsters.

The reason you were having problems calling the method on the game variable from the Monster constructor is because the game variable is defined in the scope of the main method. Nothing outside of the main method can refer to that variable. The compiler is telling you that inside the Monster constructor there is no symbol called game, so it doesn't know what you are trying to do.

Now you could solve the problem by adding a parameter to the constructor of type MonsterGame, and in the main method you then pass the MonsterGame into the MonsterConstructor. In general this is how one object can call methods on another object; it needs to have a reference to the object it wants to call methods on.

In your case though I would question whether the Monster class should know anything about the MonsterGame. The MonsterGame should be capable of counting the Monsters it knows about without the Monsters having to prompt it.

As to your original problem, I too can't see anything wrong with the code. I haven't compiled it though. Do you get a compilation error? If so, what does the text say?
 
Junilu Lacar
Sheriff
Posts: 11494
180
Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
What you have there is actually a "code smell" that involves Monster having "inappropriate intimate contact" with Game and Game "inappropriately exposing" intimate details of itself.

A similar situation would occur if you have a Vendor and Customer. A Vendor will naturally want to track how many Customers he has, right? Imagine a Vendor has a little notebook in his pants pocket where he keeps that tally. Now, imagine a new person comes along and completes a purchase, thus becoming a new Customer. What would you think about having that guy reach into the Vendor's pants pocket, pull out the little notebook and add a new mark to the tally of that Vendor's customers, then put the notebook back in the Vendor's pocket? That would be weird and inappropriate, right?

Two weird "smells" in that scenario:
1. Why is the Customer doing that?
2. Why does the Vendor allow it?

Same deal for your Monster and Game classes.
 
Junilu Lacar
Sheriff
Posts: 11494
180
Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Alternatively to what I gave before, the code in the Game class could be something like this:
 
nick woodward
Ranch Hand
Posts: 382
12
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Honestly guys, you've just added a load of value to the work I was doing last night.

@Mike - Thank you for explaining that part so thoroughly. I had many of those thoughts last night, but it's good to know there's some sense behind them! (I thought it may have been a visibility issue and did consider passing somesort of reference to the Monster of what board it was playing on, and did also consider the problem with new GameBoard instances).

@Junilu - you are completely correct thank you, Monster need not know about the count (in fact it doesn't, it just increments at the end of its constructor - but still you're right it shouldn't - I initially thought this would be a good way to auto count, something that I'm sure would have raised its head when I added an 'addMonster' method to the GameBoard)

Loving the customer going into someone else's pocket example!
Incidently this is actually my attempt at redesigning a tutorial whose class definitions were WAY too intimate with each other so I'm trying to fix it
 
With a little knowledge, a cast iron skillet is non-stick and lasts a lifetime.
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!