在C#中,我有一个带有公共成员的父类。我想派生父类,然后派生公共成员的类,以便创建和访问新方法,如下所示......
public class Animal { }
public class Sheep : Animal {
public void makeALamb() { }
}
public class Farm
{
public Animal myAnimal;
}
public class SheepFarm : Farm {
public void SheepFarm() {
this.myAnimal = new Sheep();
this.myAnimal.makeALamb();
}
}
此代码无法编译。 “Animal不包含makeALamb()的定义”。但我想做的是多态的本质,不是吗?我错过了什么?我非常期待找到答案。
提前致谢!
答案 0 :(得分:8)
因为myAnimal
的类型为Animal
。因此,它只能访问Animal
的成员...而Animal
没有方法makeALamb
。
这里任务的右侧:
this.myAnimal = new Sheep();
..说出它是什么。左侧显示您的代码所看到的内容。作业的左侧是:
public Animal myAnimal;
// ^^^^^^
现在..假装你尝试过的东西是可能的......考虑一下:
this.myAnimal = new Snake();
this.myAnimal.makeALamb(); // what does it call here?
this.myAnimal = new Giraffe();
this.myAnimal.makeALamb(); // what here?
..在makeALamb
个实例上调用Snake
时会发生什么? ......
答案 1 :(得分:1)
如果我正确猜测您打算做什么,请考虑使用泛型:
public class Farm<TAnimal> where TAnimal : Animal
{
public TAnimal myAnimal;
}
public class SheepFarm : Farm<Sheep>
{
public void SheepFarm()
{
this.myAnimal = new Sheep();
this.myAnimal.makeALamb();
}
}
答案 2 :(得分:0)
makeALamb()
是Sheep
的方法,而非Animal
。 Sheep
来自Animal
,而不是相反。
答案 3 :(得分:0)
this.myAnimal
已定义为Animal
。 Animal
没有makeALamb
方法。由于您将Sheep
放在this.myAnimal
中,
((Sheep)this.myAnimal).makeALamb();
这实际上说:&#34;接受this.myAnimal
,视为Sheep
并在其上调用makeALamb()
&#34;。如果this.myAnimal
在运行时不是真的一只羊,那么您将获得例外。
答案 4 :(得分:0)
如果您想要访问Animal
方法,则必须将Sheep
实例投射到makeALamb
。
public void SheepFarm()
{
this.myAnimal = new Sheep();
((Sheep)this.myAnimal).makeALamb();
}
没有强制转换myAnimal
被视为Animal
的类型,因此您只能访问Animal
的成员和Animal
的基类成员(在这种情况下没有基类olf Animal
。)
另一方面,当然,这不是访问类成员的优雅而安全的方法。如果您想通过基类实例访问某些公共成员,那么您应该在基类中声明成员(可能是 abstract 或 virtual ),然后在派生类中实现(或覆盖)它们。
答案 5 :(得分:0)
这个想法是你的Animal可以被实例化为Sheep,但它只会处理Animal上定义的成员。它很简单:绵羊是一种动物,但动物不是绵羊,所以动物不能制作Alpha():)
答案 6 :(得分:0)
您还没有很好地定义Farm类。这是一个例子:
public class Animal { }
public class Sheep : Animal {
public void makeALamb() { }
}
public class Goat: Animal {
public void makeAGoat() { }
}
public class Farm
{
public Goat myGoat;
public Sheep mySheep;
}
public class MyFarm : Farm {
public void MyFarm() {
this.mySheep= new Animal();
this.mySheep.makeALamb();
}
}
每只动物都不是山羊,但每只山羊都是动物。
答案 7 :(得分:0)
因为,您想使用多态,请将您的代码更改为:
public abstract class Animal
{
public abstract void makeChild();
}
public class Sheep : Animal
{
public override void makeChild()
{
Console.WriteLine("A lamb is born.");
}
}
public class Cow : Animal
{
public override void makeChild()
{
Console.WriteLine("A calf is born.");
}
}
public class Farm
{
public Animal myAnimal;
}
public class SheepFarm : Farm
{
public SheepFarm()
{
this.myAnimal = new Sheep();
this.myAnimal.makeChild();
}
}
public class CowFarm : Farm
{
public CowFarm()
{
this.myAnimal = new Cow();
this.myAnimal.makeChild();
}
}
并使用以下&#34; Main()&#34;方法:
class Program
{
static void Main(string[] args)
{
Farm sf = new SheepFarm();
Farm cf = new CowFarm();
}
}
但是,我应该指出,这不是一个好的用例场景。一个更好更简单的多态性用例是摆脱Farm类并使用以下&#34; Main()&#34;方法而不是前一个方法:
class Program
{
static void Main(string[] args)
{
Animal[] animals = {
new Sheep(),
new Cow(),
new Sheep(),
new Cow(),
new Cow()
};
foreach (Animal animal in animals)
{
animal.makeChild();
}
}
}