不知道如何从 C# 中声明为抽象 class 类型的对象中检索属性

Don't kwow how to retrieve properties from objects declared as abstract class type in C#

我正在学习 C#,我对 classes 中继承的使用有疑问,我希望有人能帮助我。

如果我有一些从抽象 class 继承的 class 对象,我可以将次要 class 的对象声明为主要抽象 [=31] 的类型=],像这样:

Animal leopard = new Mammal();

其中 Mammal 是继承自抽象 class Animal 的 class。在这种情况下,我如何访问 Mammal class 独有的属性?查看以下代码以获得更好的理解:

        static void Main(string[] args)
        {
            Animal leopard = new Mammal("leopard", "mammal", "yellow", 80);
            Bird falcon = new Bird("falcon", "bird", "black", 300);
            Fish shark = new Fish("shark", "fish", "white", 80);
            List<Animal> animalList = new List<Animal>();            

            animalList.Add(leopard);
            animalList.Add(falcon);
            animalList.Add(shark);

            Console.WriteLine("Name: {0}, Class: {1}, Fur Collor: {2}, Running Speed: {3} km/h.",
                leopard.name, leopard.animalClass, leopard.furColor, leopard.runningSpeed);
            
            Console.ReadLine();
        }

        public abstract class Animal
        {
            public string name { get; set; }
            public string animalClass { get; set; }
        }

        public class Mammal : Animal
        {
            public string furColor { get; set; }
            public double runningSpeed { get; set; }

            public Mammal(string name, string animalClass,
                string furColor, double runningSpeed)
            {
                this.name = name;
                this.animalClass = animalClass;
                this.furColor = furColor;
                this.runningSpeed = runningSpeed;
            }
        }

        public class Bird : Animal
        {
            public string featherColor { get; set; }
            public double flightSpeed { get; set; }

            public Bird(string nam, string animalClass,
                string featherColor, double flightSpeed)
            {
                this.name = name;
                this.animalClass = animalClass;
                this.featherColor = featherColor;
                this.flightSpeed = flightSpeed;
            }
        }

        public class Fish : Animal
        {
            public string scaleColor { get; set; }
            public double swimmingSpeed { get; set; }

            public Fish(string name, string animalClass,
                string scaleColor, double swimmingSpeed)
            {
                this.name = name;
                this.animalClass = animalClass;
                this.scaleColor = scaleColor;
                this.swimmingSpeed = swimmingSpeed;
            }
        }

在这个例子中,因为所有 classes 继承自 Animal class 我可以将它们添加到 List<Animal>,但是当我尝试访问属性时 furColorrunningSpeed 是 Mammal class 独有的,我有一个错误,因为它们不属于 Animal class。这些属性到哪里去了?我怎样才能找回它们?

此致,

法比亚诺。

您可以将其声明为 Mammal leopard = new Mammal(); 以访问它。否则你需要将 leopard 转换回哺乳动物来检索它们,因为 Animal 没有你需要的属性。

    Console.WriteLine("Name: {0}, Class: {1}, Fur Collor: {2}, Running Speed: {3} km/h.",
        leopard.name, leopard.animalClass, ((Mammal)leopard).furColor, ((Mammal)leopard).runningSpeed);

您还可以在要访问派生的 class 方法的位置使用 as 运算符。

Animal leopard = new Mammal();
Mammal mam = leopard as Animal;
if( mam != null)
{ 
    var fur = mam.furColor();
}

或者更简洁的语法。

Animal leopard = new Mammal();
var fur = (leopard as Mammal)?.furColor();

使用第二种方式,如果 leopard 被创建为 Fish,那么 fur 将为 null。这可能是一个问题,具体取决于您的 furColor 方法在哺乳动物可能没有毛皮的情况下如何工作。 IE。没有毛皮意味着 furColor 为空。在这种情况下,您可能无法判断派生类是鱼还是没有毛的哺乳动物。

这是多态性(多种形式)的一个例子。

使用任何语言我们都可以断言以下内容:

  1. 所有哺乳动物都是动物 - 但并非所有动物都是哺乳动物;
  2. 所有的鸟都是动物——但不是所有的动物都是鸟;
  3. 所有的鱼都是动物——但不是所有的动物都是鱼;

摘要class可以定义为蓝图

根据定义,蓝图只能用于构建具体对象。

对于一个Abstract也是一样的class——是否有被继承(inheritance)用于构建一个对象——可以被实例化(initialised)。

此处的多态性可以看作是将派生的 class 哺乳动物分配给抽象的 class 动物的能力 - 因为哺乳动物可以是动物。

哺乳动物 class 可以有多种形式 - 它可以被视为动物或哺乳动物。

Animal leopard = new Mammal();
Mammal leopard = new Mammal();

根据上面的多态解释,两个实例化都是正确的 - 但是 Animal leopard 将按照其 class 属性(封装)nameanimalClass.

同时 Mammal leopard 将按照他的 class 属性 + 继承 nameanimalClassfurColorrunningSpeed 进行操作。