c使用子类变量来实现父类方法



我一直面临着一个挑战,质疑我对OOP的信心。如果可能的话,请告诉我:

我有一个父类,它有一个静态列表(用来跟踪创建的所有对象,主要是因为UI DataGrid的原因(和一个引用该列表的方法。类似的东西

abstract class Animal
{
public static List<Animal> objList;
public String Name;
public Animal(String Name)
{
this.Name = Name;
objList.Add(this);
}
public virtual void delete(int i)
{
objList.RemoveAt(i);
}

现在我有一个带有静态列表的子类(相同的名称相同的目的只是不同的类(,但为了让方法引用child.list,我必须重写该方法。就像

class Cat : Animal
{
public static List<Cat> objList;
public Cat(String Name) : base(Name)
{
}
//whould it be possible to ommit this method?
public override void delete(int i)
{
objList.RemoveAt(i);
}
}

这不可能是最好的方式。如果我有5个孩子,他们都会粘贴代码副本的相同部分。父类"delete"方法必须有一种方法,如果从子对象调用,它将从子列表中删除,而不是从父列表中删除。

静态属性和方法不适合以OOP方式重写,尽管它们可以被隐藏。

public class Parent : IDisposable
{
private static List<Parent> objList = new List<Parent>();
private static IReadOnlyList<Parent> readOnlyList = new ReadOnlyCollection<Parent>(objList);
public static IEnumerable<Parent> Instances { get { return readOnlyList; } }
private bool _isDisposed = false;
public bool IsDisposed {  get { return _isDisposed;  } }
public Parent()
{
objList.Add(this);
}
public void Dispose()
{
OnDispose(true);
GC.SuppressFinalize(this);
}
protected virtual void OnDispose(bool disposing)
{
if(disposing) { objList.Remove(this); }
_isDisposed = true;
}
}
public class Child : Parent
{
private static IEnumerable<Child> _instances = Parent.Instances.OfType<Child>();
public new static IEnumerable<Child> Instances { get { return _instances; }}
public Child() : base()
{
}
}

现在,如果您想从列表中删除第i个项,只需使用Parent.Instances(i(.Dispose((

您也可以通过执行Child.Instances(i(.Dispose((来删除第i个子实例

编辑:根据以下注释中的建议,从父级中删除了终结器。

Edit2:按照注释中的建议,简化了Child类中的LINQ表达式以使用.OfType((。

集合不属于基类,当然也不属于任何派生类。

不幸的是,你没有展示你的List<Animal>是如何使用的,所以很难在不推断出你可能不想要的行为的情况下给出有意义的答案。

但是,如果您坚持,您只需要一个集合来容纳所有动物,并声明一个静态属性,该属性根据每个子类中的类型过滤原始集合。

public abstract class Animal
{
// this is the _only_ field that should contain
// a list of all the animals.
protected static readonly List<Animal> animals = new List<Animal>();
// Expose a read-only wrapper as public
public static IReadOnlyList<Animal> AllAnimals => animals.AsReadOnly();
protected Animal(string color)
{
animals.Add(this);
this.Color = color;
}
public string Color { get; }
public void RemoveMe()
{
int index = animals.IndexOf(this);
if (index >= 0)
{
animals.RemoveAt(index);
}
}
}    
public class Cat : Animal
{
public static IReadOnlyList<Cat> AllCats => animals.OfType<Cat>().ToList().AsReadOnly();
public Cat(string name, string color) : base(color)
{
this.Name = name;
}
public string Name { get; }
}
public class Fish : Animal
{
public static IReadOnlyList<Fish> AllFish => animals.OfType<Fish>().ToList().AsReadOnly();
public Fish(string color) : base(color)
{
}
}
static class Program
{
static void Main(string[] args)
{
var cat1 = new Cat("Whiskers", "Tabby");
var fish1 = new Fish("Striped");
var cat2 = new Cat("Snoflake", "White");
var cat3 = new Cat("Midnight", "Black");
cat2.RemoveMe();
// list all remaining cats below
foreach (var cat in Cat.AllCats)
{
Debug.WriteLine($"{cat.Name} is a {cat.Color} cat.");
}
// Result in Output:
//Whiskers is a Tabby cat.
//Midnight is a Black cat.
}
}

最新更新