【问题标题】:C#: OOP inheritance of propertyC#:属性的 OOP 继承
【发布时间】:2017-07-03 05:20:39
【问题描述】:

我想继承一个类有一个属性,但是这个类的不同实现会对该属性有不同的值,并且该属性应该在不实例化对象的情况下可用。 例如:每只动物都有一个值 numberOfLegs。每只猫是 4,每条蛇是 0。现在我想遍历一些动物类型并打印出动物子类有多少条腿,而无需创建该类的实例。

【问题讨论】:

  • 静态属性不参与继承。
  • “我想循环...而不创建该类的实例”不是真正的要求。
  • 如果腿的数量可以从一种动物变化到另一种动物,那么该属性就不是静态的,因为它可以变化。

标签: c# oop


【解决方案1】:

你可以给以下机会:

首先声明你的 Animal 抽象基类,它将负责存储类型和 numberoflegs

abstract class Animal
    {
        protected readonly static IDictionary<Type, int> _legsDictionary = new Dictionary<Type, int>();
    }

还有一个具有静态属性 NumberOfLegs 的 Animal 抽象类:

abstract class Animal<T> :Animal where T : class
    {
        public static int NumberOfLegs
        {
            get => _legsDictionary.ContainsKey(typeof(T)) ? _legsDictionary[typeof(T)] : -1;
            set
            {
                _legsDictionary[typeof(T)] = value;
            }
        }
    }

然后声明任意数量的 Animals >>>

class Cat : Animal<Cat> { }
class Snake : Animal<Snake> { }
class Human : Animal<Human> { }

和测试:

static void Main(string[] args)
        {
            Cat.NumberOfLegs = 4;
            Snake.NumberOfLegs = 0;
            Human.NumberOfLegs = 2;

            Console.WriteLine(Cat.NumberOfLegs);
            Console.WriteLine(Snake.NumberOfLegs);
            Console.WriteLine(Human.NumberOfLegs);
            Console.ReadLine();
        }

【讨论】:

  • 这符合所要求的限制,但你会想要使用这样的东西吗?
  • 我必须诚实,我永远不会使用这样的东西 =)。我只是在回答他的问题。我认为如果他想询问它的架构或设计,那么他会发布(可能在元中)一个问题。
【解决方案2】:

你想要实现的事情不可能以你想要的方式实现。

static 关键字在每个类之间保持不变。 您可以执行以下操作:

class Animal
{
    public static int LegCount { get { return 0; } }
}

class Snake : Animal
{
    public static new int LegCount { get { return 0; } }
}

class Human : Animal
{
    public static new int LegCount { get { return 2; } }
}

class Cat : Animal
{
    public static new int LegCount { get { return 4; } }
}

使用new 关键字,您可以使每个新类型返回不同的值。

但请注意,List&lt;Animal&gt; 将始终返回 0,因为 new 仅隐藏在类型中,并且与 override 不同。

【讨论】:

  • 在成员之前添加new只会抑制警告,这是一个非常错误的设计这一事实不会改变。
【解决方案3】:

我想您也可以通过实现接口而不是从基类继承来定义您的接口要求(具有numberOfLegs 属性)。这样,您可以将静态值放置在它们不会跨实例更改的抽象级别:

interface IAnimal
{
    int numberOfLegs { get; }
}

class Snake : IAnimal
{
    public static int numberOfLegs = 0;

    int IAnimal.numberOfLegs
    {
        get { return numberOfLegs; }
    }
}

class Cat: IAnimal
{
    public static int numberOfLegs = 4;

    int IAnimal.numberOfLegs
    {
        get { return numberOfLegs; }
    }
}

【讨论】:

  • 接口对类型不起作用,你仍然需要实例来使用它。旁注,=&gt; 你只需要一半的行。
  • 好吧,拥有一个可以改变的静态属性以及枚举不同类型的动物而不实例化动物类的要求是混乱的。老实说,如果我自己遇到类似的情况,我可能会回到绘图板上。感谢您的提示!
猜你喜欢
  • 1970-01-01
  • 2013-04-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-13
  • 2022-07-27
  • 1970-01-01
  • 2021-03-29
相关资源
最近更新 更多