关于一类变量及其对多态中class的异议

About a type of variable and its objection to a class in polymorphism

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()class,这里没问题,那myPig呢? myPig 是一个 Animal 类型变量但指向 Pig class,这是否意味着 myPig 将使用其 TYPE class 中的任何内容(在本例中为 Animal ), 但由于它指向 Pig class,它正在调用其指向 class right(in Pig class)?

。 . . . .

    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();
        }
    }

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

myPig is an Animal type variable but points to Pig class

最好说 myPig 是一个 Animal reference,它指的是一个 Pig object.

myPig is going to cast or use whatever in its TYPE class (in this case Animal), but because of it points to Pig class, it's invoking in its pointing class right(in Pig class)?

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

  • 虚方法将使用对象类型来解析方法,即"The pig says: wee wee".
  • 非虚拟方法使用引用类型,即"The animal makes a sound".

搜索“动态调度”以进一步阅读。

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

界面类似于基础class。不同的是所有的接口方法都是virtual的,必须在derived中定义class。调度机制在其他方面是相同的。所以你永远不能创建一个 IAnimal 对象,它必须是 PigDog.