2010-04-15 85 views
0

这里的骰子类的相关部分:调用方法在对象上的Java

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) 

所以这个方法需要一个已经存在的paramater所以世界上没有必要创建里面一个新的骰子骰子。

Finaly这里是如何我试图调用rollo

o.Dice.roll() ; 
+4

请注意,(免费)Sun文档包含几个教程,这些教程对于学习像这样的东西非常有用。 http://java.sun.com/docs/books/tutorial/ – atk 2010-04-15 01:10:57

+1

在这篇文章的某处有什么问题吗? – 2010-04-15 02:56:29

+0

@ luis.espinal曾经有过,显然它在编辑中丢失了 – David 2010-04-15 03:42:49

回答

7

在你的其他类,在一些方法,你需要得到你想要的类的实例使用。如果你在另一个包中,你需要一个导入语句。

然后很简单:

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

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

同时,请参阅Sun's documentation和尝试的例子让你在你的脚下。

修订,以配合您的更改:

public class Risk 
{ 
    public static void IdiceRoll(Dice o) 
    { 
     o.roll(); 
    } 
} 
+0

对不起,我应该更清楚的问题。我调用这个方法的方法需要一个名为o的Dice作为参数,所以骰子不需要被创建。另外在骰子。骰子不需要大写? – David 2010-04-15 01:17:19

+0

我确实发布了更多的代码。 – David 2010-04-15 01:21:28

+0

@David我更新了,以显示你描述的情况。不,你必须在调用方法时使用*变量名称*,而不是*骰子*名称,它是** Dice **。唯一不是这样的情况是,如果您调用的方法是* static *方法,但您现在不需要担心。 – 2010-04-15 01:21:57

0
Dice dice = new Dice(); 
dice.roll; 
+0

缺少'roll'方法调用的括号... – masher 2010-04-15 01:10:27

+0

该方法卷是在一个不同类的形式,但我在做这件事。请参阅编辑。 – David 2010-04-15 01:18:03

+0

-1对于学习语言和询问语法(如提问者在这里)的人们,在答案中出现sytax错误可能会带来更多的负面影响。 – David 2010-04-15 01:41:57

1

您实例化对象,然后调用方法:

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

还是我误解你的问题?

+0

是的,我认为,但这是我的错。查看修改。 – David 2010-04-15 01:17:39

0

您将获得对象的实例的引用,然后调用卷()

Dice dice = new Dice(); 
dice.roll(); 
+0

我调用roll的类是与定义的类不同的类,请参阅编辑。 – David 2010-04-15 01:18:35

1

我不是你的要求很清楚。如果你有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一样,只是它在类层次结构上看上去一层。据我所知,没有办法调用特定的超类的方法;你只能看上一层。尽管如此,这通常就足够了。

+0

我调用roll的类是与定义的类不同的类,请参阅编辑。对不起 – David 2010-04-15 01:18:59

1

使用最新更新的问题,你只需要说o.roll();

如果不工作,然后仔细检查了roll()方法是公共私人

+0

我只需要做o.roll,即使roll是在一个不同的类中定义的,我在其中调用它。 – David 2010-04-15 01:20:26

+0

是的。因为你正在将实例'o'告诉'roll()'本身。它是一个骰子,所以它知道它必须执行Dice类中定义的'roll()'。 – David 2010-04-15 01:22:46

+0

详细说明:Dice知道如何执行您在Dice类中定义的每种方法。所以骰子实例知道如何roll()。作为其中的一部分,除了Dice类中的任何方法(以及任何Dice的超类)之外,它不能做任何事情。所以你不需要告诉它使用Dice类中的'roll()',因为这是它唯一的'roll()'。 – David 2010-04-15 01:26:02

1

您必须创建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 

你说。有一个类型为Dice的名为o的变量,那么编译器知道哪些属性以及可以从该对象调用哪些方法。

正如你所看到的,调用一个方法,你使用.的对象和方法,其次是它的参数那怎么实例(非静态)名称(如果有的话)

o.roll(); 

上方法工作

静态(类方法正式)方法在另一方面,在类本身操作,这就是为什么他们不需要一个实例。

So, it is possible to invoke them directly: 

Risk.IdiceRoll(aDiceInstance); 

我想你应该花点时间来阅读:http://java.sun.com/docs/books/tutorial/java/concepts/和理解Java是如何实现这些概念。

+0

我试图调用roll的方法需要一个骰子作为参数,所以我不需要先创建一个Dice的实例。对困惑感到抱歉。请看我编辑的问题。 – David 2010-04-15 01:19:52

+0

@David:有..见更新的答案 – OscarRyz 2010-04-15 01:22:17

3

从您的评论回复可以看出,您可能不了解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; 
     } 
    } 

} 

现在,我可以使用使用static方法调用的形式(类名+方法名)的静态工厂方法创建一个新的Dice

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方法的有效用法之一。再说一次,尽管不要过度使用静态方法,但应尽量使用正常方法,因为您正在学习语言。

编辑:我在另一个question您使用此方法签名注意到:

public static void printDice (Dice Dice) 

在这里,你必须使用相同的字母大小写命名类和变量。我在这个问题中解决这个问题,因为这可能会帮助你解决你在这里表达的一些困惑。你应该小心你用于类和变量的名字。奇怪的是,Java实际上接受这种语法。第一个Dice是类名(类型),第二个Dice是参数名称。相反,你应该使用小写字母的变量/参数名,所以它应该是这样的:

public static void printDice (Dice dice) 

然后,它会在你使用一个对象引用(dice)是在方法中更清晰或班级名称(Dice)。

此外,此打印方法可能应该是Dice类中的方法。使用OOP时,您应该考虑让对象自行打印。这允许不同的子类提供不同的方式来打印自己,而不用试图将所有的逻辑放在一个单独的方法中。这是过度使用静态方法的一个例子,它会降低类的价值和灵活性。

+0

+1你的耐心只能和佛相比。 – 2010-04-15 01:45:12

相关问题