繁体   English   中英

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

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

我有一个Abstract类Animal,它存储一些通用字段,例如名称,健康状况。 我有许多动物类,例如Tiger,但是我也有Fish类,它有其他动物类没有的其他字段canSplash

然后,我有一个动物对象列表。 我可以访问公共字段,但是不能访问Fish的canSplash字段。 我正在寻找有关从抽象类访问具体类特定字段的帮助。

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

简单的答案是,通过安全地强制转换为类型来检查类型,并检查它是否不为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);
}

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

检查的类型,然后采取措施

该方法可以是:

 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类中抽象方法的实现在哪里:)

暂无
暂无

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

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