Invoking methods on objects in java
Here's the开发者_如何学运维 relevant part of the Dice class:
import java.util.*;
class Dice
{
String name ;
int x ;
int[] sum ;
...
public Dice (String name)
{
this.name = name ;
this.x = 0 ;
this.sum = new int[7] ;
}
...
public void roll ()
{
this.x = randNum(1, this.sum.length) ;
this.sum[x] ++ ;
}
I am invoking this method in a separate class named Risk
class Risk
{
Heres the first line of the method:
public static void IdiceRoll (Dice o)
So this method takes a dice that already exists as a paramater so theres no need to create a new dice inside it.
Finaly here is how i'm trying to invoke roll
on o
:
o.Dice.roll () ;
In your other class, in some method, you need to get an instance of the class you're trying to use. You need an import statement if you're in another package.
Then it's simple:
// Create an instance of class Dice named dice
Dice dice = new Dice();
// call the method on the instance you just created
dice.roll();
Also, refer to Sun's documentation and try examples to get your feet under you.
Revision to match your changes:
public class Risk
{
public static void IdiceRoll(Dice o)
{
o.roll();
}
}
It appears from your comment responses that you may not understand the difference between static
and non-static methods.
To invoke a static method, you use the class and method name. Let's take a slightly modified example:
public class Dice {
private static final Random RANDOM = new Random();
private int sides;
protected Dice(int sides) {
this.sides = sides;
}
public static Dice create(int sides) {
return new Dice(sides);
}
public int roll() {
synchronized(RANDOM) {
return RANDOM.nextInt(sides) + 1;
}
}
}
Now, I can create a new Dice
using the static factory method using the static
method call form (class name + method name):
Dice d = Dice.create(6);
But for normal methods you call them in relation to an instantiated object because they may operate on data stored with that object. In this case, I have created an object that is held in the reference variable d
and this object contains the number of sides that it should generate a number for. To call it, use:
int value = d.roll();
There are many advantages to using normal methods over static ones. Do not overuse static
methods. Static methods are not inherited and are not part of an object - they are just considered part of the class. This is why you call static methods using the class name (though Java does unfortunately allow the object.method usage as well but a good IDE will warn you about that). There is no related memory state. However, an object itself also has memory state and there may be many different instances of the class with different values. Here we could create different sided dice:
Dice six = Dice.create(6);
Dice twenty = Dice.create(20);
// Use the dice for a 1D6 + 1D20 roll.
int value = six.roll() + twenty.roll();
In this example, I've called the roll
method on two different object instances. Using Dice.roll()
will not work since the roll method must be called in relation to the instance so it knows how many sides (in this case) to do the roll for.
More advance topic: That static method is a factory and could create sub-classes that have different features/randomness based on the number of sides. For example, later I could create a special sub-class of Dice called TrickDice and any time someone asked for a 5 sided dice they get one of those simply by changing the create
method:
public static Dice create(int sides) {
if (sides == 5)
return new TrickDice(5);
else
return new Dice(sides);
}
This does not change how it is called...
Dice d = Dice.create(5); // This really is a TrickDice
This is one of the valid usages of a static
method. Again, though do not overuse static methods, try to use normal methods as much as possible as you are learning the language.
EDIT: I noticed in another question that you use this method signature:
public static void printDice (Dice Dice)
Here you have named the class and variable using the same letter case. I address this here in this question because this may help you with some of the confusion you expressed here. You should be careful about the names you use for your classes and variables. Strangely, Java actually accepts this syntax. The first Dice
is the class name (type) and the second Dice
is the parameter name. Instead, you should use lower case letters for the variable/parameter name, so it should look like this:
public static void printDice (Dice dice)
Then it will be more clear within the method when you are using an object reference (dice
) or the class name (Dice
).
Also, this print method probably should be a method on the Dice
class. With OOP you should think of asking the object to print itself. This allows different sub-classes to provide different ways to print themselves without trying to put all the logic in a single method. This is an example of overusing a static method which diminishes the value and flexibility of your classes.
You instantiate the object, then call the method:
Dice redSparklyPair = new Dice();
redSparklyPair.roll();
Or am I misunderstanding your question?
I'm not quite clear on what you're asking. If you have an object of type Dice
, you can just do
public class NotDice {
// ...
public int method() {
Dice dice = new Dice();
dice.roll();
// ...
}
// ...
}
If you're in a subclass of Dice
, then you can call the superclass method with the super
keyword:
public class WeightedDice extends Dice {
// ...
public void roll() {
// ...
super.roll();
// ...
}
// ...
}
super
is just like this
, except that it looks one level up the class hierarchy. As far as I know, there's no way to call a specific superclass's method; you can only look one level up. Nevertheless, that's usually sufficient.
With your latest question update you just need to say o.roll();
If that doesn't work then double-check that the roll()
method is public and not private.
You have to create an instance of the Dice
class and then invoke it.
Suppose you have a Game
class:
class Risk {
public static void IdiceRoll (Dice o) {
// You have to roll the dice
// The dice already exist, you just... roll it!!
o.roll();
// And that's it
}
}
Dice
is the name of the class, the class is just like a template or a blueprint. It defined things ( like variables and methods ).
To use a class you usually create object from it. In this case you can name your object whatever you want ( in this case it is named o
)
So when you declare:
Dice o
You're saying. There is a variable named o
of type Dice
then the compiler know what attributes and what method can be invoked from that object.
As you saw, to invoke a method on an object you use the .
and the name of the method followed by its parameters ( if any )
o.roll();
That's how instance ( non-static ) methods work
static ( class methods officially ) methods in the other hand, operate in the class itself, that's why they don't need an instance.
So, it is possible to invoke them directly:
Risk.IdiceRoll( aDiceInstance );
I think you should really take a moment to read this: http://java.sun.com/docs/books/tutorial/java/concepts/ and understand how Java implements those concepts.
Dice dice = new Dice();
dice.roll;
You will have to get a reference to the instance of the object then invoke roll()
Dice dice = new Dice();
dice.roll();
精彩评论