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

时间:2016-07-17 13:08:40

标签: c# oop

我有一个抽象类Animal,它存储一些常见字段,例如name,health。我有许多动物类别,例如老虎,但我也有一类鱼类,其他动物类别没有其他领域,canSplash

然后我有一个Animal对象列表。我可以访问公共字段,但我无法访问Fish的canSplash字段。我正在寻找帮助从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; }
}

2 个答案:

答案 0 :(得分:4)

简单的答案是,通过安全地投射到它来检查类型并检查它是否不是null

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

如果您只有一个具有此特定行为的子类,那么这是完全可以的。 但是考虑到你还有其他儿童类动物也可以飞溅,就像让我们说一头大象一样,如果你想找到动物园里所有可以飞溅的动物,你还要检查大象班。

更好的方法是使用接口来处理ISplashable

等内容
public interface ISplashable
{
    bool CanSplash { get; }
}

现在在所有应该能够启动的子类中实现此接口:

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

    // ...
}

现在您可以检查该接口而不是具体类:

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

答案 1 :(得分:0)

//删除static关键字,因为你无法访问动物(或动物应该是静态的)

检查a的类型,然后采取行动

方法可以是:

 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);
                }
            }
        }
    }
顺便说一句,你说Animal是抽象类,在Fish类中实现抽象方法:)