Java参数多态性示例
我有一个关于参数多态性的问题。如果我有一个混合了子类型的集合,如何确定实际类型并避免强制转换。比如说Java参数多态性示例,java,generics,polymorphism,Java,Generics,Polymorphism,我有一个关于参数多态性的问题。如果我有一个混合了子类型的集合,如何确定实际类型并避免强制转换。比如说 class Animal{ } class Bird extends Animal{ void fly(){} } class Dog extends Animal{ void bark(){} } ArrayList<Animal> list = new ArrayList<
class Animal{
}
class Bird extends Animal{
void fly(){}
}
class Dog extends Animal{
void bark(){}
}
ArrayList<Animal> list = new ArrayList<Animal>();
如果你需要这样做,这意味着这是一个常见的行为。您通常会有以下情况:
abstract class Animal {
abstract void act();
}
class Bird extends Animal{
void fly(){}
void act(){
fly();
}
}
class Dog extends Animal{
void bark(){}
void act(){
bark();
}
}
在循环中,您只需调用act
方法:
for(Animal animal : list){
animal.act();
}
如果你需要这样做,这意味着这是一个常见的行为。您通常会有以下情况:
abstract class Animal {
abstract void act();
}
class Bird extends Animal{
void fly(){}
void act(){
fly();
}
}
class Dog extends Animal{
void bark(){}
void act(){
bark();
}
}
在循环中,您只需调用act
方法:
for(Animal animal : list){
animal.act();
}
你不应该有这样的清单。另一个选项是使用(或
.getClass()
)的instanceof,然后是downcast。您不应该有这样的列表。另一种方法是使用instanceof
(或.getClass()
),然后进行向下转换。使用instanceof
将无法达到泛型的目的。泛型的要点是定义行为,这样您就不必关心类型是什么。例如:
public interface Animal {
void speak();
void fly();
}
public class Dog implements Animal {
public void speak() {
System.out.println("Woof!");
}
// Do nothing!
public void fly() { }
}
public class Bird implements Animal {
public void speak() {
System.out.println("Tweet!");
}
public void fly() {
System.out.println("I'm flying!!");
}
}
public static void main (String[] args) {
// list populating removed
for(Animal animal : list) {
animal.speak();
animal.fly();
}
}
看到了吗?实际上,您并不关心动物在运行时是什么类型。你让对象做他们应该做的
顺便说一句,如果您只想
Bird
拥有fly()
方法,那么您不会尝试在Animal
的所有实例上调用fly()
方法。。。使用instanceof
将有一个不同的列表,这将违背泛型的目的。泛型的要点是定义行为,这样您就不必关心类型是什么。例如:
public interface Animal {
void speak();
void fly();
}
public class Dog implements Animal {
public void speak() {
System.out.println("Woof!");
}
// Do nothing!
public void fly() { }
}
public class Bird implements Animal {
public void speak() {
System.out.println("Tweet!");
}
public void fly() {
System.out.println("I'm flying!!");
}
}
public static void main (String[] args) {
// list populating removed
for(Animal animal : list) {
animal.speak();
animal.fly();
}
}
看到了吗?实际上,您并不关心动物在运行时是什么类型。你让对象做他们应该做的
顺便说一句,如果您只想Bird
拥有fly()
方法,那么您不会尝试在Animal
的所有实例上调用fly()
方法。。。您将有一个不同的列表
,理想情况下,您将对每个可以在基类上声明并在子类中重写的项执行类似的操作(例如speak()
)。那么你就不必担心类型了。如果按原样进行,那么是的,您需要强制转换以调用该方法。(我有意识地排除了使用反射来调用方法的选项)除非将bark()
和fly()
移动到超类Animal
,否则无法避免。理想情况下,对于可以在基类上声明并在子类中重写的每个项,都可以执行类似的操作(例如speak()
)。那么你就不必担心类型了。如果按原样进行,那么是的,您需要强制转换以调用该方法。(我有意识地排除了使用反射调用方法的选项)除非将bark()
和fly()
移动到超级类Animal
,否则您无法避免。您是说将它们分为2个列表吗?您是说将它们分为2个列表吗?