Вызов методов на объектах в Java - PullRequest
0 голосов
/ 15 апреля 2010

Вот соответствующая часть класса Dice:

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] ++ ;
    }

Я вызываю этот метод в отдельном классе с именем Risk

class Risk 
{

Вот первая строка метода:

public static void IdiceRoll (Dice o)

Таким образом, этот метод принимает кости, которые уже существуют в качестве параметра, поэтому нет необходимости создавать новые кости внутри него.

Наконец, вот как я пытаюсь вызвать roll на o:

o.Dice.roll () ; 

Ответы [ 8 ]

7 голосов
/ 15 апреля 2010

В другом вашем классе, в каком-то методе, вам нужно получить экземпляр класса, который вы пытаетесь использовать. Вам нужен оператор импорта, если вы находитесь в другом пакете.

Тогда все просто:

// Create an instance of class Dice named dice
Dice dice = new Dice();

// call the method on the instance you just created
dice.roll();

Кроме того, обратитесь к документации Sun и попробуйте примеры, чтобы помочь себе.

Ревизия, соответствующая вашим изменениям:

public class Risk
{
   public static void IdiceRoll(Dice o)
   {
      o.roll();
   }
}
3 голосов
/ 15 апреля 2010

Из ответов на ваши комментарии следует, что вы можете не понимать разницу между static и нестатическими методами.

Чтобы вызвать статический метод, вы используете класс и имя метода. Давайте возьмем слегка измененный пример:

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;
        }
    }

}

Теперь я могу создать новый Dice, используя метод статической фабрики, используя форму вызова метода static (имя класса + имя метода):

Dice d = Dice.create(6);

Но для обычных методов вы вызываете их в отношении экземпляра объекта, потому что они могут работать с данными, хранящимися в этом объекте. В этом случае я создал объект, который содержится в ссылочной переменной d, и этот объект содержит число сторон, для которых он должен сгенерировать число. Чтобы позвонить, используйте:

int value = d.roll();

Существует много преимуществ использования обычных методов по сравнению со статическими. Не злоупотребляйте static методами. Статические методы не наследуются и не являются частью объекта - они просто считаются частью класса. Вот почему вы вызываете статические методы, используя имя класса (хотя Java, к сожалению, также допускает использование object.method, но хорошая IDE предупредит вас об этом). Нет связанного состояния памяти. Однако сам объект также имеет состояние памяти, и может быть много разных экземпляров класса с разными значениями. Здесь мы могли бы создать разные двусторонние кости:

Dice six = Dice.create(6);
Dice twenty = Dice.create(20);

// Use the dice for a 1D6 + 1D20 roll.
int value = six.roll() + twenty.roll();

В этом примере я вызвал метод roll для двух разных экземпляров объекта. Использование Dice.roll() не сработает, так как метод крена должен быть вызван по отношению к экземпляру, чтобы он знал, сколько сторон (в данном случае) нужно выполнить крен.

Более продвинутая тема: этот статический метод является фабричным и может создавать подклассы, которые имеют разные особенности / случайность в зависимости от количества сторон. Например, позже я мог создать специальный подкласс игры в кости под названием TrickDice, и каждый раз, когда кто-то запрашивал 5-стороннюю игру в кости, он получал одну из них, просто изменяя метод create:

public static Dice create(int sides) {
    if (sides == 5)
        return new TrickDice(5);
    else
        return new Dice(sides);
}

Это не меняет того, как оно называется ...

Dice d = Dice.create(5); // This really is a TrickDice

Это одно из допустимых применений метода static. Опять же, хотя и не злоупотребляйте статическими методами, старайтесь использовать как можно больше обычных методов при изучении языка.

РЕДАКТИРОВАТЬ : я заметил в другом вопросе , что вы используете этот метод подписи:

public static void printDice (Dice Dice)

Здесь вы назвали класс и переменную, используя один и тот же регистр букв. Я расскажу об этом здесь в этом вопросе, потому что это может помочь вам в некоторой путанице, которую вы выразили здесь. Вы должны быть осторожны с именами, которые вы используете для своих классов и переменных. Странно, но на самом деле Java принимает этот синтаксис. Первый Dice - это имя класса (тип), а второй Dice - это имя параметра. Вместо этого вы должны использовать строчные буквы для имени переменной / параметра, поэтому оно должно выглядеть так:

public static void printDice (Dice dice)

Тогда в методе будет более понятно, когда вы используете ссылку на объект (dice) или имя класса (Dice).

Кроме того, этот метод печати, вероятно, должен быть методом класса Dice. С ООП вы должны подумать о том, чтобы попросить объект напечатать сам. Это позволяет различным подклассам предоставлять разные способы печати, не пытаясь объединить всю логику в одном методе. Это пример чрезмерного использования статического метода, который снижает ценность и гибкость ваших классов.

1 голос
/ 15 апреля 2010

Вы должны создать экземпляр класса Dice и затем вызвать его.

Предположим, у вас есть Game класс:

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 - это имя класса, класс похож на шаблон или чертеж. Он определил вещи (например, переменные и методы).

Чтобы использовать класс, вы обычно создаете объект из него. В этом случае вы можете назвать свой объект как хотите (в данном случае он называется o)

Итак, когда вы заявляете:

Dice o

Вы говорите. Существует переменная с именем o типа Dice, тогда компилятор знает, какие атрибуты и какой метод можно вызвать из этого объекта.

Как вы видели, чтобы вызвать метод для объекта, вы используете . и имя метода, а затем его параметры (если есть)

 o.roll();

Вот как экземпляр (нестатические) методы работают

static (официально методы класса) методы, с другой стороны, работают в самом классе, поэтому им не нужен экземпляр.

So, it is possible to invoke them directly:

 Risk.IdiceRoll( aDiceInstance );

Я думаю, вам действительно нужно уделить время, чтобы прочитать это: http://java.sun.com/docs/books/tutorial/java/concepts/ и понять, как Java реализует эти концепции.

1 голос
/ 15 апреля 2010

В вашем последнем обновлении вопроса вам просто нужно сказать o.roll();

Если это не сработает, проверьте, что метод roll() является public и not private .

1 голос
/ 15 апреля 2010

Мне не совсем понятно, о чем вы спрашиваете. Если у вас есть объект типа Dice, вы можете просто сделать

public class NotDice {
  // ...
  public int method() {
    Dice dice = new Dice();
    dice.roll();
    // ...
  }
  // ...
}

Если вы находитесь в подклассе Dice, то вы можете вызвать метод суперкласса с ключевым словом super:

public class WeightedDice extends Dice {
  // ...
  public void roll() {
    // ...
    super.roll();
    // ...
  }
  // ...
}

super аналогично this, за исключением того, что он выглядит на один уровень выше иерархии классов. Насколько я знаю, нет способа вызвать определенный метод суперкласса; Вы можете посмотреть только на один уровень вверх. Тем не менее, этого обычно достаточно.

1 голос
/ 15 апреля 2010

Вы создаете экземпляр объекта, затем вызываете метод:

Dice redSparklyPair = new Dice();
redSparklyPair.roll();

Или я неправильно понимаю ваш вопрос?

0 голосов
/ 15 апреля 2010

Вам нужно получить ссылку на экземпляр объекта, затем вызвать roll ()

Dice dice = new Dice();
dice.roll();
0 голосов
/ 15 апреля 2010
Dice dice = new Dice();
dice.roll;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...