调用方法在对象上的Java
这里的骰子类的相关部分:调用方法在对象上的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这里是如何我试图调用roll
上o
:
o.Dice.roll() ;
在你的其他类,在一些方法,你需要得到你想要的类的实例使用。如果你在另一个包中,你需要一个导入语句。
然后很简单:
// 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();
}
}
您实例化对象,然后调用方法:
Dice redSparklyPair = new Dice();
redSparklyPair.roll();
还是我误解你的问题?
是的,我认为,但这是我的错。查看修改。 – David 2010-04-15 01:17:39
您将获得对象的实例的引用,然后调用卷()
Dice dice = new Dice();
dice.roll();
我调用roll的类是与定义的类不同的类,请参阅编辑。 – David 2010-04-15 01:18:35
我不是你的要求很清楚。如果你有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
一样,只是它在类层次结构上看上去一层。据我所知,没有办法调用特定的超类的方法;你只能看上一层。尽管如此,这通常就足够了。
我调用roll的类是与定义的类不同的类,请参阅编辑。对不起 – David 2010-04-15 01:18:59
使用最新更新的问题,你只需要说o.roll();
如果不工作,然后仔细检查了roll()
方法是公共和不私人。
我只需要做o.roll,即使roll是在一个不同的类中定义的,我在其中调用它。 – David 2010-04-15 01:20:26
是的。因为你正在将实例'o'告诉'roll()'本身。它是一个骰子,所以它知道它必须执行Dice类中定义的'roll()'。 – David 2010-04-15 01:22:46
详细说明:Dice知道如何执行您在Dice类中定义的每种方法。所以骰子实例知道如何roll()。作为其中的一部分,除了Dice类中的任何方法(以及任何Dice的超类)之外,它不能做任何事情。所以你不需要告诉它使用Dice类中的'roll()',因为这是它唯一的'roll()'。 – David 2010-04-15 01:26:02
您必须创建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是如何实现这些概念。
从您的评论回复可以看出,您可能不了解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时,您应该考虑让对象自行打印。这允许不同的子类提供不同的方式来打印自己,而不用试图将所有的逻辑放在一个单独的方法中。这是过度使用静态方法的一个例子,它会降低类的价值和灵活性。
+1你的耐心只能和佛相比。 – 2010-04-15 01:45:12
请注意,(免费)Sun文档包含几个教程,这些教程对于学习像这样的东西非常有用。 http://java.sun.com/docs/books/tutorial/ – atk 2010-04-15 01:10:57
在这篇文章的某处有什么问题吗? – 2010-04-15 02:56:29
@ luis.espinal曾经有过,显然它在编辑中丢失了 – David 2010-04-15 03:42:49