views:

545

answers:

5

In Java (And in general) is there a way to make a class so public that it's methods etc... are accessible from little classes all around that don't even instantiate it? Ha, what I mean is... If I have a daddy class that has a method draw() and it instantiates a baby class called Hand and one called Deck, and then deck instantiates a babier class called Card that has a method play(), is there a way for Play() to then call Draw() from the daddy class?

The idea here is that... the daddy class says "Deck! play(card)!" and then deck says "Card! play()!" and then play turns around and says "Hey daddy! Draw()!"

PS the idea is that... in a CCG every card has a "play()" method that is different but they are all essentially called in the same way. The opportunity to play the card comes around, and you call play on it. But the card doesn't do anything internal to itself: no no, it calls a number of methods from the rules of the game, which is has visibility to. So, like, a card in MTG that says "draw one card. Deal one damage to target player." is calling draw(player, 1) and dealDamage(player, 1) which are presumably not in the card itself... since they effect variables presumably instantiated by the players when they started the game and agreed on life totals and rules such as what "draw" means?

(meta-question: as usual, could someone please rename this question so that it reflects what I am asking... being a beginner is so frustrating!)

+1  A: 

You can:

  • Pass the object reference through the constructor. Or by getters and setters. Or directly to the function.
  • Use inheritance.
  • Use static classes.
Loki
+4  A: 

When the Daddy class instantiates the Baby classes, it (Daddy) could pass a reference to itself to the Baby constructor, giving Baby access to all of its public methods.

class Daddy {
    public foo(){...}
    public createBaby(){
        Baby baby = new Baby(this);
        // baby now has a reference to Daddy
    }
}


class Baby {
    Daddy daddy;
    public Baby(Daddy daddy){
        this.daddy = daddy;
    }
    ...
    public callDaddy(){
        daddy.foo();
    }
}
Bill the Lizard
OK, so what I've done I guess is: I have made daddy into something like a "rule book" and passes references to it to all the baby classes so that they can do the things that the rules let them do. Actually this is great I think!
Ziggy
Sounds like you're on the right track. :)
Bill the Lizard
A: 

From an OO perspective I would say to use inheritance. One way is to create an abstract class that does not implement methods that will not behave the same by sub-classes; and implements methods that will behave the same for all sub-classes.

rich
A: 

Looks like you are trying to implement some kind of double dispatching.

Peter Severin
A: 

You can also define inner and outer classes. Inner classes then have access to all of the fields of the outer class.

public class OuterClass{
    int x
    private class InnerClass{
        InnerClass(){
         x = 10;
        }
    }
}

However, you're probably going to be better off using either a Singleton pattern, where you have a static reference to a single resource (like the deck for most card games, although CCGs tend to have one per player), or else passing in the shared resource in the object's constructor. In the case of MTG or something similar, I'd probably give each card a cast() method that takes a Player and a list of targets. The Player is the caster, so a spell like Brainstorm could then invoke draw() on the Player to get them to draw cards, while a permanent spell could then assign itself under control of the Player. The targets then would be for any other targets the spell would possibly need and could potentially be null or the empty list (whichever you think is more appropriate).

James