我一直面临挑战,质疑我对OOP的信念。请让我知道这怎么可能:
我有一个带有静态列表的父类(用于跟踪创建的所有对象,主要是出于UI DataGrid的原因),还有一个引用该列表的Method。像这样
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个孩子,他们将粘贴同一部分代码副本。 父类“删除”方法必须有一种方法,如果从子对象中调用该方法,则会从子列表中删除,而不是从父列表中删除。
答案 0 :(得分:0)
尽管静态属性和方法可能会被遮盖,但它们不适合以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个Child实例。编辑:终结器已从“父级”中删除,如以下注释中所述。
Edit2 :按照注释中的建议,将Child类中的LINQ表达式简化为使用.OfType()。
答案 1 :(得分:-1)
该集合不属于基类,当然,它也不属于任何派生类。
不幸的是,您没有展示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.
}
}