简体   繁体   English

从抽象类对象列表访问子类的属性

[英]Accessing properties of a child class from list of abstract class objects

I have an Abstract class Animal, which stores some common fields, eg name, health. 我有一个Abstract类Animal,它存储一些通用字段,例如名称,健康状况。 I have a number of animal classes eg Tiger, but I also have a class Fish which has an additional field the other animal classes don't have, canSplash . 我有许多动物类,例如Tiger,但是我也有Fish类,它有其他动物类没有的其他字段canSplash

I then have a list of Animal objects. 然后,我有一个动物对象列表。 I can access the common fields, but I cannot access the canSplash field for Fish. 我可以访问公共字段,但是不能访问Fish的canSplash字段。 I am looking for help to accessing a concrete classes specific fields from an Abstract Class. 我正在寻找有关从抽象类访问具体类特定字段的帮助。

class Zoo
{
    public List<Animal> animals = new List<Animal>();

    public Zoo()
    {
        animals.Add(new Monkey());
        animals.Add(new Tiger());
        animals.Add(new Fish());
    }

    public static void displayZooPopulation()
    {
        foreach (var a in animals)
        {
            if (a.species == "fish" && a.CanSplash)
            {
                Console.WriteLine("{0} can splash",a.Name);
            }
        }
    }
}

class Fish : Animal {
    private bool canSplash
    public bool CanSplash { get; set; }
}

Simple answer would be, check the type by safely cast to it and check if it is not null : 简单的答案是,通过安全地强制转换为类型来检查类型,并检查它是否不为null

var fish = a as Fish;
if (fish != null && fish.CanSplash)
{
    Console.WriteLine("{0} can splash",a.Name);
}

This is perfectly okay if you only have one child class which has this specific behavior. 如果您只有一个具有此特定行为的子类,则完全可以。 But consider you have other child classes of animals which also are able to splash, like let's say an elephant, then you have to check for the elephant's class also if you want to find all animals in your zoo which can splash. 但是,请考虑您还有其他能够飞溅的动物子类,比如说一头大象,那么,如果您想在动物园中找到所有可能飞溅的动物,则还必须检查大象的类。

A better approach is to use an interface for such things like ISplashable : 更好的方法是将接口用于ISplashable类的事情:

public interface ISplashable
{
    bool CanSplash { get; }
}

Now implement this interface in all of your child classes which should be able to splash: 现在,在您应该能够使用的所有子类中实现此接口:

public class Fish : Animal, ISplashable
{
    // ...

    public bool CanSplash { get; set; }  // this also implements CanSplash { get; }

    // ...
}

public class Elephant : Animal, ISplashable
{
    // ...

    public bool CanSplash { get { return true; } }

    // ...
}

Now you can check against that interface instead of the concrete class: 现在,您可以对照该接口而不是具体的类进行检查:

var splasher = a as ISplashable;
if (splasher != null && splasher.CanSplash)
{
    Console.WriteLine("{0} can splash",a.Name);
}

//remove the static keyword, for you can't access animals (or animals should be static) //删除static关键字,因为您无法访问动物(或动物应该是静态的)

check type of a , and take your action 检查的类型,然后采取措施

The method can be: 该方法可以是:

 public   void displayZooPopulation() 
    {
        foreach (var a in animals)
        {
            if ( a is Fish)
            {
//here sure "a" is not null, no need to check against null
                var fish = a as Fish;
                //  if (a.species == "fish" && (Fish) a.CanSplash)
                if ( fish.CanSplash)
                {
                    Console.WriteLine("{0} can splash", a.Name);
                }
            }
        }
    }

BTW, you say that Animal is abstract class , where is implementation of abstract methods in Fish class :) 顺便说一句,你说Animal是抽象类,在Fish类中抽象方法的实现在哪里:)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM