【问题标题】:How can I use the derived class variable? Base class variable is being used automatically如何使用派生类变量?基类变量正在自动使用
【发布时间】:2019-04-19 16:11:56
【问题描述】:

我从王国类继承植物和动物类,从动物类继承哺乳动物类。

我在所有类中创建了布尔变量 fly、milk 和 fruits,它们根据类分配不同。

王国中有一些方法可以检查苍蝇、牛奶和水果并相应地给出输出。方法被所有类继承。

但是当我使用植物和哺乳动物的对象来使用继承方法时,使用王国类变量而不是预期的类变量。

代码有点长。所以很抱歉。

class Kingdom
{
    private bool milk, wings, fruits;

    public Kingdom() : this(true, true, true) {}
    public Kingdom(bool m, bool w, bool f)
    {
        milk = m;
        wings = w;
        fruits = f;
    }

    public virtual string me()
    {
        return "Kingdom Member";
    }

    public virtual void Fly()
    {
        if(this.wings)
        {
            Console.WriteLine(me() + " may Fly.");
        }
        else
        {
            Console.WriteLine(me() + " can not Fly.");
        }
    }

    public virtual void Fruit()
    {
        if(this.fruits)
        {
            Console.WriteLine(me() + " may bear Fruits.");
        }
        else
        {
            Console.WriteLine(me() + " can not bear Fruits.");
        }
    }

    public virtual void Milk()
    {
        if(this.milk)
        {
            Console.WriteLine(me() + " may produce milk.");
        }
        else
        {
            Console.WriteLine(me() + " can not produce milk.");
        }
    }
}

class Plant : Kingdom
{
    private bool milk, wings, fruits;

    public Plant()
    {
        milk = false;
        wings = false;
        fruits = true;
    }

    public override string me()
    {
        return "Plants";
    }
}

class Animelia : Kingdom
{
    private bool milk, wings, fruits;

    public Animelia()
    {
        milk = true;
        wings = true;
        fruits = false;
    }

    public override string me()
    {
        return "Animals";
    }
}

class Mamalia : Animelia
{
    private bool milk, wings, fruits;

    public Mamalia()
    {
        milk = true;
        wings = false;
        fruits = false;
    }

    public override string me()
    {
        return "Mamals";
    }
}

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("Hello World!\nLets learn Basic Kingdoms.\n");

        Kingdom p1 = new Plant();
        Kingdom m1 = new Mamalia();

        p1.Fly();
        p1.Milk();
        p1.Fruit();
        Console.WriteLine();
        m1.Fly();
        m1.Milk();
        m1.Fruit();
    }
}

这些是我担心的警告:

Program.cs(80,35):警告 CS0414:已分配字段“Animelia.fruits”,但从未使用过其值 [E:\VS Code Programms\C#\Assignment\Q5\Q5.csproj]

Program.cs(80,28): 警告 CS0414: 字段 'Animelia.wings' 已分配,但其值从未使用过 [E:\VS Code Programms\C#\Assignment\Q5\Q5.csproj]

Program.cs(97,28): 警告 CS0414: 字段 'Mamalia.wings' 已分配,但从未使用其值 [E:\VS Code Programms\C#\Assignment\Q5\Q5.csproj]

Program.cs(63,28):警告 CS0414:已分配字段“Plant.wings”,但从未使用其值 [E:\VS Code Programms\C#\Assignment\Q5\Q5.csproj]

Program.cs(97,35):警告 CS0414:“Mamalia.fruits”字段已分配,但从未使用过其值 [E:\VS Code Programms\C#\Assignment\Q5\Q5.csproj]

Program.cs(63,22):警告 CS0414:已分配字段“Plant.milk”,但从未使用其值 [E:\VS Code Programms\C#\Assignment\Q5\Q5.csproj]

Program.cs(63,35):警告 CS0414:已分配字段“Plant.fruits”,但从未使用其值 [E:\VS Code Programms\C#\Assignment\Q5\Q5.csproj]

Program.cs(80,22):警告 CS0414:已分配字段“Animelia.milk”,但从未使用其值 [E:\VS Code Programms\C#\Assignment\Q5\Q5.csproj]

Program.cs(97,22): 警告 CS0414: 字段 'Mamalia.milk' 已分配,但其值从未使用 [E:\VS Code Programms\C#\Assignment\Q5\Q5.csproj]

【问题讨论】:

    标签: c# inheritance


    【解决方案1】:

    请从每个子类中删除 milkwingsfruits 字段。它们已经继承。您再次声明它们,这隐藏了 Kingdom 类中的那些。

    基本上,这意味着您在此处设置的字段...

    public Plant()
    {
        milk = false;
        wings = false;
        fruits = true;
    }
    

    Kingdom 中的不同。因此Kingdom 中的方法不知道您创建的这些新字段。

    删除字段声明后,milkwingsfruits 将引用 Kingdom 类中声明的字段。

    您的代码应如下所示:

    class Plant : Kingdom
    {
    
        public Plant()
        {
            milk = false;
            wings = false;
            fruits = true;
        }
    
        public override string me()
        {
            return "Plants";
        }
    }
    
    class Animelia : Kingdom
    {
        public Animelia()
        {
            milk = true;
            wings = true;
            fruits = false;
        }
    
        public override string me()
        {
            return "Animals";
        }
    }
    
    class Mamalia : Animelia
    {
        public Mamalia()
        {
            milk = true;
            wings = false;
            fruits = false;
        }
    
        public override string me()
        {
            return "Mamals";
        }
    }
    

    另外,我认为你的班级之间的关系有点奇怪。 AnimalPlant 是王国的示例,因此它们应该是 Kingdom 的实例,而不是继承自它。而Mammalia 根本不是Kingdom。这些王国是古细菌、真细菌、原生生物、真菌、植物和动物界。

    【讨论】:

      【解决方案2】:

      您不需要在派生类中定义milkwingsfruit 变量,因为它们已经存在于基类中。

      要从派生类中设置这些变量,您已经有一个可以在此处执行此操作的构造函数:

      public Kingdom(bool m, bool w, bool f)
      {
          milk = m;
          wings = w;
          fruits = f;
      }
      

      您需要做的就是使用base 关键字从您的基类中使用该构造函数。例如:

      class Plant : Kingdom
      {    
          public Plant() : base(false, false, true)
          {
          }
      
          public override string me()
          {
              return "Plants";
          }
      }
      

      【讨论】:

        【解决方案3】:

        Fly()、Milk() 和 Fruit() 方法在 Kingdom 基类的上下文中运行,它们正在访问该类中的本地私有类变量。

        问题在于,Kingdom 类无法直接访问子类中变量的重新定义版本,因此您会收到未使用它们的错误。

        正如其他人所说,理想情况下,您实际上不会重新定义每个子类中的变量,而是使 Kingdom 中的变量“受保护”而不是“私有”。然后,您将能够直接在每个子类的构造函数中设置这些变量。但是,为了解决您的为什么您收到警告说每个子类中的变量没有被使用的问题,请继续阅读...

        解决此问题的一种方法是在 Kingdom 类中添加一些虚拟 Get 访问器方法,然后可以在子类中覆盖这些访问器方法,以便读取本地重新定义的变量版本。

        请注意:我在这里使用了 lamda 的“表达式主体方法”语法,因为它使 GetWings()、GetMilk() 和 GetFruit() 方法既美观又紧凑。如果您愿意,可以将这些扩展为完整的方法。

        class Kingdom
        {
            private bool milk, wings, fruits;
        
            public Kingdom() : this(true, true, true) { }
            public Kingdom(bool m, bool w, bool f)
            {
                milk = m;
                wings = w;
                fruits = f;
            }
        
            public virtual string me()
            {
                return "Kingdom Member";
            }
        
            protected virtual bool GetMilk() => milk;
            protected virtual bool GetWings() => wings;
            protected virtual bool GetFruits() => fruits;
        
            public virtual void Fly()
            {
                if (GetWings())
                {
                    Console.WriteLine(me() + " may Fly.");
                }
                else
                {
                    Console.WriteLine(me() + " can not Fly.");
                }
            }
        
            public virtual void Fruit()
            {
                if (GetFruits())
                {
                    Console.WriteLine(me() + " may bear Fruits.");
                }
                else
                {
                    Console.WriteLine(me() + " can not bear Fruits.");
                }
            }
        
            public virtual void Milk()
            {
                if (GetMilk())
                {
                    Console.WriteLine(me() + " may produce milk.");
                }
                else
                {
                    Console.WriteLine(me() + " can not produce milk.");
                }
            }
        }
        
        class Plant : Kingdom
        {
            private bool milk, wings, fruits;
        
            public Plant()
            {
                milk = false;
                wings = false;
                fruits = true;
            }
        
            public override string me()
            {
                return "Plants";
            }
        
            protected override bool GetMilk() => milk;
            protected override bool GetWings() => wings;
            protected override bool GetFruits() => fruits;
        }
        
        class Animelia : Kingdom
        {
            private bool milk, wings, fruits;
        
            public Animelia()
            {
                milk = true;
                wings = true;
                fruits = false;
            }
        
            public override string me()
            {
                return "Animals";
            }
        
            protected override bool GetMilk() => milk;
            protected override bool GetWings() => wings;
            protected override bool GetFruits() => fruits;
        }
        
        class Mamalia : Animelia
        {
            private bool milk, wings, fruits;
        
            public Mamalia()
            {
                milk = true;
                wings = false;
                fruits = false;
            }
        
            public override string me()
            {
                return "Mamals";
            }
        
            protected override bool GetMilk() => milk;
            protected override bool GetWings() => wings;
            protected override bool GetFruits() => fruits;
        }
        
        class Program
        {
            static void Main(string[] args)
            {
                Console.WriteLine("Hello World!\nLets learn Basic Kingdoms.\n");
        
                Kingdom p1 = new Plant();
                Kingdom m1 = new Mamalia();
        
                p1.Fly();
                p1.Milk();
                p1.Fruit();
                Console.WriteLine();
                m1.Fly();
                m1.Milk();
                m1.Fruit();
            }
        }
        

        我用上面修改的代码得到了以下结果:

        Hello World!
        Lets learn Basic Kingdoms.
        
        Plants can not Fly.
        Plants can not produce milk.
        Plants may bear Fruits.
        
        Mamals can not Fly.
        Mamals may produce milk.
        Mamals can not bear Fruits.
        

        【讨论】:

          猜你喜欢
          • 2018-05-19
          • 1970-01-01
          • 1970-01-01
          • 2018-01-20
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-07-16
          • 2023-03-15
          相关资源
          最近更新 更多