游戏设计中多态性、投射和方法重写的Java实现
注:这是我问题的概念性版本。关于这些概念的应用,我的实际问题如下所示游戏设计中多态性、投射和方法重写的Java实现,java,list,animation,polymorphism,overriding,Java,List,Animation,Polymorphism,Overriding,注:这是我问题的概念性版本。关于这些概念的应用,我的实际问题如下所示 我试图弄清楚什么时候一个对象被认为是它自己的类或类的超类的实例。考虑下面的超类动物和亚纲海马: import java.util.List; import java.util.ArrayList; public class Animal { public static void main(String[] args) { Animal a= new Animal(); /*1.
我试图弄清楚什么时候一个对象被认为是它自己的类或类的超类的实例。考虑下面的超类动物和亚纲海马:
import java.util.List;
import java.util.ArrayList;
public class Animal
{
public static void main(String[] args)
{
Animal a= new Animal();
/*1. This line prints a's class*/
System.out.println(a.getClass());
List<Animal> animals= new ArrayList<Animal>(1);
animals.add(new Seahorse(1));
//2. Let's see what happens here
animals.get(0).printClass();
for(Animal e : animals)
{
e.printClass(); //3 This is an overriden method
//e.printThisClass(); Compile Time error;
//4. Note this method only exists in subclass
}
Animal hiahiahia = new Seahorse();
hiahiahia.printClass(); //5. Lets see what happens
hiahiahia.printThisClass(); //6.
}
public void printClass()
{
System.out.println("Animal");
}
}
输出结果如下所示:
class Animal //1.
Seahorse //2.
Seahorse //3.
Seahorse //5.
您可以看到,尽管海马对象存储在动物对象或列表中,但多态性导致调用海马方法
然而,当我试图调用一个方法,该方法的名称仅存在于伪装成动物对象的Seahorse对象的子类中时,编译抛出一个错误
问题:
多态性只有在方法重写时才起作用,这是真的吗?有没有时间
Animal animal = new Seahorse(1);
使动物仅被视为动物(不是海马)
两者之间有什么区别
Animal animal = new Seahorse();
animal.printThisClass();
及
最后,我应该什么时候使用铸造
我正在制作一个2d游戏,并创建了以下类:
public class Entity
{
}
及
我还有一个控制器类,它有两个字段:
private List<Entity>;
private List<Character>;
私有列表;
私人名单;
我之所以将它们分开,是因为实体(在本例中为箭头、项目符号)只与字符碰撞,而不与其他实体碰撞。
问题是:我还有一个render方法,可以绘制所有实体的buffereImage。现在,为了使图形有意义,实体应该按照其Y值的升序进行渲染(即从最远到最近)。但是,这需要将所有字符和实体放在同一集合中
问题是:我是否应该将它们分开?如果我把它们放在同一个列表中,会不会因为无法区分字符和实体而引起混淆
谢谢:)第一个问题的答案: 两者之间有什么区别 动物=新海马();animal.printThisClass();及 ((海马)动物) 没有区别。 当你将该动物扔给海马时,它允许你使用海马的方法。例如,如果Seahorse类有一个名为
blowBubble()
的方法,如果您有animal.blowBubble()
(假设animal的定义如上所述),它将给您一个错误,因为animal类没有一个名为blowBubble()
的方法
但是,当您通过执行((Seahorse)animal)
将动物变量转换为Seahorse时,您的意思是我知道这个动物是海马,所以请允许我使用Seahorse的方法
Animal animal = new Seahorse();
animal.method();
((Seahorse)animal).method(); // calls the exact same method even if it was overriden
但是,如果您这样做,您会注意到
Animal animal = new Animal();
((Seahorse)animal).blowBubbles();
((Seahorse)animal).method();
每次你尝试施放它时,它都会给你一个ClassCastException,因为动物无法转化为海马。但是,由于海马始终是和动物的,所以可以在海马实例上调用任何动物方法
Seahorse seahorse = new Seahorse();
seahorse.methodInAnimalClass();
对于下一个问题,字符和实体的两个单独列表完全由您决定。因为你需要做一个简单的排序算法来确定谁拥有最大或最小的y位置,这可能并不重要
您始终可以创建一个名为getAllenties()的方法,该方法返回一个新列表,该列表组合了实体和字符,然后对该列表进行排序并呈现它们
正如评论所说,您还应该查看接口,但我不建议创建大量的接口。我认为从简单开始是一个不错的选择,但是,随着你的游戏变得更高级,你可能需要考虑如何实现它们。我强烈建议退一步,仔细观察
界面
——例如,猫可以碰撞
,成为动物
,可渲染
,可移动的
以及其他一些东西<代码>接口允许您更好地描述“意图”和混合匹配组合,在大多数情况下,您可能无法单独使用扩展。这也意味着Cat
可以驻留在用于管理其实现的任何接口的任何集合中。只要稍微巧妙地使用Java 8的流
s,您就可以拥有一个“东西”的主列表,它可以作为岩石
在这里过滤,可以碰撞
,并且是可渲染的
,但除此之外没有什么:P,您希望避免对对象/实体的底层实现进行假设如果必须强制转换,那么您就错了。您要么理解多态性,要么不理解多态性。选角是你做错了的标志。您应该有一个公共接口,每个实现者都有自己的实现风格。迭代接口引用类型的列表。当您调用公共方法时,每个具体的子类型都做了正确的事情。我认为您有一个列表,并使用Java8SStream
支持根据您的需要对其进行过滤。在大多数情况下,您会有一个“更新”过程,该过程执行移动、碰撞和其他生命周期处理,然后执行单独的绘制过程,因为更新过程可能会更改绘制的内容和时间,因此您不希望在单个过程中对其进行修改。但是如果我想将\\Animal Animal=new Seahorse()\\或\\Seahorse Seahorse=new Seahorse()放入一个或多个列表中,这会有什么区别吗?第一个对象不能放入第二个列表,对吗?你提出的合并列表的建议听起来是可行的,但我能把列表转换成列表吗?谢谢。是的,你不能把动物列入海马名单,因为它不是海马。执行Animal Animal=new Seahorse()或Seahorse Seahorse=new Seahorse()的唯一区别在于,如果要访问Seahorse类中定义的方法,或将其添加到列表中,或将其传递给另一个方法,则必须强制转换它。您不能将列表强制转换为列表,但可以在此处查看
Animal animal = new Seahorse();
animal.method();
((Seahorse)animal).method(); // calls the exact same method even if it was overriden
Animal animal = new Animal();
((Seahorse)animal).blowBubbles();
((Seahorse)animal).method();
Seahorse seahorse = new Seahorse();
seahorse.methodInAnimalClass();