关于多态性中的一类变量及其对一类的反对


class Animal {
public void animalSound() {
System.out.println("The animal makes a sound");
}
}
class Pig extends Animal {
public void animalSound() {
System.out.println("The pig says: wee wee");
}
}
class Dog extends Animal {
public void animalSound() {
System.out.println("The dog says: bow wow");
}
}
class MyMainClass {
public static void main(String[] args) {
Animal myAnimal = new Animal();  // Create a Animal object
Animal myPig = new Pig();  // Create a Pig object
Animal myDog = new Dog();  // Create a Dog object
myAnimal.animalSound();
myPig.animalSound();
myDog.animalSound();
}
}

所以我的问题是;myAnimal是一个Animal类型的变量,指向Animal((类,这里没问题,myPig呢?myPig是一个Animal类型的变量,但指向Pig类,这是否意味着myPig将在其type类(在本例中为Animal(中投射或使用任何东西,但因为它指向Pig类别,所以它在其指向类别右侧调用(在Pig类别中(?

。。。.

interface IAnimal
{
void animalSound(); // interface method (does not have a body)
}
class AnimalSound
{
private IAnimal _animal;
public AnimalSound(IAnimal animal)
{
_animal = animal;
}
public void animalVoice()
{
_animal.animalSound();
}
}
class Pig : IAnimal
{
public void animalSound()
{
Console.WriteLine("Pig pig!");
}
}
class Dog : IAnimal
{
public void animalSound()
{
Console.WriteLine("Dog dog!");
}
}
class Program
{
static void Main(string[] args)
{
AnimalSound myAnimal = new AnimalSound(new Dog());  // Create a Pig object
myAnimal.animalVoice();
}
}

最后,我不明白这个模式,它需要我们一个接口来工作,但我们给了它一个实现接口的类,这是如何工作的,为什么工作?

myPig是一个动物类型变量,但指向Pig类

最好说myPig是一个动物引用,指的是Pig对象

myPig将在其TYPE类(在本例中为Animal(中投射或使用任何内容,但因为它指向Pig类,所以它在其指向类中调用权限(在Pig类中(?

没有进行强制转换。强制转换将一种类型的引用转换为另一种类型。在这种情况下,我们只是在引用上调用一个方法。行为将取决于该方法是否为虚拟

  • 虚拟方法将使用对象类型来解析该方法,即"猪说:
  • 非虚拟方法使用引用类型,即";动物发出一种声音">

搜索";"动态调度";以供进一步阅读。

在c中,方法默认情况下是非虚拟的,在java中,它们默认情况下都是虚拟的。Java用final声明了非虚拟方法,而c#在基类中用virtual和派生类中用override声明了虚拟方法。

接口类似于基类。不同之处在于,所有接口方法都是虚拟的,并且必须在派生类中定义。调度机制在其他方面是相同的。因此,永远不能创建IAnimal对象,它必须是PigDog

最新更新