【发布时间】:2017-06-03 09:43:47
【问题描述】:
注意:这是我的问题的概念版本。我关于这些概念的应用的实际问题显示在此块下方。
我试图弄清楚一个对象何时被认为是它自己的类或类的超类的实例。考虑以下超类 Animal 和子类 Seahorse:
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");
}
}
public class Seahorse extends Animal
{
private int y;
public Seahorse(int a)
{
this.y=a;
}
public void printClass()
{
System.out.println("Seahorse");
}
public void printThisClass()
{
System.out.println("Seahorse");
}
}
输出如下所示:
class Animal //1.
Seahorse //2.
Seahorse //3.
Seahorse //5.
可以看到,虽然 Seahorse 对象存储在 Animal 对象或列表中,但多态性导致 Seahorse 方法被调用。
但是,当我尝试调用一个名称仅存在于伪装成 Animal 对象的 Seahorse 对象的子类中的方法时,编译会引发错误。
问题: 多态性是否仅在方法覆盖时才有效?有没有什么时候
Animal animal = new Seahorse(1);
导致动物只被视为动物(不是海马)?
有什么区别
Animal animal = new Seahorse();
animal.printThisClass();
和
((Seahorse)animal).printThisClass();
最后,什么时候应该使用强制转换?
我正在开发一个 2d 游戏并创建了以下类:
public class Entity
{
}
和
public class Character extends Entity
{
//With bunch of extra fields and methods
}
我还有一个控制器类,它有两个字段:
private List<Entity>;
private List<Character>;
我将它们分开是因为实体(在本例中为箭头、项目符号)仅与字符发生冲突,而不会与其他实体发生冲突。 这就是问题所在:我还有一个渲染方法可以绘制我所有实体的 BufferedImage。现在为了使图表有意义,应按 Y 值的升序呈现实体。(即从最远到最近)。但是,这需要将所有角色和实体放在同一个集合中......
问题是:我应该将它们分开吗?如果我将它们放在同一个 List 中,那会不会因为无法区分 Entities 中的字符而引起混淆?
谢谢:)
【问题讨论】:
-
我强烈建议您退后一步,密切关注
interface- 例如Cat可以是Collide、Animal、Renderable、Movable和可能还有很多其他的东西。interface允许您更好地描述“意图”以及混合和匹配组合,在大多数情况下,您可能无法单独使用扩展。这也意味着Cat可以驻留在用于管理它实现的任何interfaces 的任何集合中。稍微巧妙地使用 Java 8 的Streams,您可以拥有一个可以过滤的“东西”主列表 -
Rock可以在Collide和Renderable中使用,但仅此而已:P。尽可能避免对对象/实体的底层实现做出假设 -
如果你必须投,那你就错了。
-
你要么了解多态性,要么不了解。铸造是你做错了的标志。您应该有一个通用接口,每个实现者都有自己的实现风格。您遍历接口引用类型的列表。当您调用公共方法时,每个具体的子类型都会做正确的事情。
-
我以为您有一个列表并使用 Java 8s
Stream支持来过滤它以满足您的需求。在大多数情况下,你会有一个“更新”通道,它会执行移动、碰撞和其他生命周期处理,然后你会做一个单独的绘制通道,因为更新通道可能会改变绘制的内容和时间,所以你不要不想一次通过它们
标签: java list animation polymorphism overriding