use*_*721 4 java parameters polymorphism factory
我看到的多态方法覆盖的唯一例子涉及不带参数的方法,或者至少具有相同的参数列表.考虑常见的Animal/Dog/Cat示例:
public abstract class Animal
{
public abstract void makeSound();
}
public class Dog extends Animal
{
public void makeSound()
{
System.out.println("woof");
}
}
public class Cat extends Animal
{
public void makeSound()
{
System.out.println("meow");
}
}
public class ListenToAnimals
{
public static void main(String[] args)
{
AnimalFactory factory = new AnimalFactory();
Animal a = factory.getRandomAnimal(); // generate a dog or cat at random
a.makeSound();
}
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,一切都很好.现在让我们添加另一个在抽象类中部分实现的方法,同时在子类中获得更具体的行为:
public abstract class Animal
{
public abstract void makeSound();
public void speak(String name)
{
System.out.println("My name is " + name);
}
}
public class Dog extends Animal
{
public void makeSound()
{
System.out.println("woof");
}
public void speak(String name)
{
super.speak(name);
System.out.println("I'm a dog");
}
}
public class Cat extends Animal
{
public void makeSound()
{
System.out.println("meow");
}
public void speak(String name, int lives)
{
super.speak(name);
System.out.println("I'm a cat and I have " + lives + " lives");
}
}
public class ListenToAnimals
{
public static void main(String[] args)
{
AnimalFactory factory = new AnimalFactory();
Animal a = factory.getRandomAnimal(); // generate a dog or cat at random
a.makeSound();
// a.speak(NOW WHAT?
}
}
Run Code Online (Sandbox Code Playgroud)
在主要方法的最后一个(注释)行中,我不知道该放什么,因为我不知道我有什么类型的动物.之前我没有必要担心,因为makeSound()没有接受任何参数.但是speak()确实如此,而且参数取决于Animal的类型.
我读过一些语言,比如Objective-C,允许变量参数列表,所以不应该出现这样的问题.有人知道在Java中实现这种事情的好方法吗?
您正在混淆方法重写和方法重载.在您的示例中,Cat该类有两种方法:
public void speak(String name) // It gets this from its super class
public void speak(String name, int lives)
Run Code Online (Sandbox Code Playgroud)
重载是一种定义具有类似功能但参数不同的方法的方法.如果你这样命名方法就没有区别了:
public void speakWithLives(String name, int lives)
Run Code Online (Sandbox Code Playgroud)
为避免混淆,java中的建议是@Override在尝试覆盖方法时使用注释.因此:
// Compiles
@Override
public void speak(String name)
// Doesn't compile - no overriding occurs!
@Override
public void speak(String name, int lives)
Run Code Online (Sandbox Code Playgroud)
编辑:其他答案提到这一点,但我重复它的重点.添加新方法使得Cat该类不再能够Animal在所有情况下都被表示为,从而消除了多态性的优势.要使用新方法,您需要将其向下转换为Cat类型:
Animal mightBeACat = ...
if(mightBeACat instanceof Cat) {
Cat definitelyACat = (Cat) mightBeACat;
definitelyACat.speak("Whiskers", 9);
} else {
// Definitely not a cat!
mightBeACat.speak("Fred");
}
Run Code Online (Sandbox Code Playgroud)
我的IDE中的代码检查工具会在instanceof关键字上发出警告,指示可能的多态抽象失败.
| 归档时间: |
|
| 查看次数: |
2035 次 |
| 最近记录: |