Как я могу использовать переменную производного класса? Переменная базового класса используется автоматически - PullRequest
0 голосов
/ 19 апреля 2019

Я наследую класс Растение и Животное от класса Королевство и класс Млекопитающее от класса Животное.

Я создал булевы переменные fly, молоко и фрукты во всех классах, которые назначаются по-разному в зависимости от классов.

В Королевстве существуют методы, которые проверяют муху, молоко и фрукты и соответственно выдают результат. Методы наследуются всеми классами.

Но когда я использую объект Plant и млекопитающее для использования унаследованных методов, вместо предполагаемой переменной класса используется переменная класса kingdom.

Код немного длинный. Так что извиняюсь.

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]

Ответы [ 3 ]

1 голос
/ 19 апреля 2019

Вам не нужно определять переменные milk, wings и fruit в ваших производных классах, потому что они уже существуют в базовом классе.

Чтобы установить эти переменные из производных классову вас уже есть конструктор, который может сделать это здесь:

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";
    }
}
1 голос
/ 19 апреля 2019

Методы Fly (), Milk () и Fruit () выполняются в контексте базового класса Kingdom и обращаются к локальным переменным частного класса в этом классе.

Проблема в том, чточто у класса Kingdom нет прямого доступа к переопределенным версиям переменных в подклассах, поэтому вы получаете ошибки, которые не используются.

Как уже говорили другие, в идеале вы бы не сталифактически переопределите переменные в каждом дочернем классе, но вместо этого сделайте переменные в Королевстве «защищенными», а не «частными».Затем вы сможете напрямую установить эти переменные в конструкторе каждого подкласса.Однако, чтобы ответить на ваш вопрос о , почему вы получаете предупреждения о том, что переменные в каждом подклассе не используются, пожалуйста, прочитайте ...

Один из способов решить эту проблему - добавить нескольковиртуальные методы доступа Get в классе Kingdom, которые затем могут быть переопределены в подклассах для чтения локальных переопределенных версий переменных.

Обратите внимание: я использовал 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.
1 голос
/ 19 апреля 2019

Удалите поля milk, wings, fruits из каждого подкласса. Они уже унаследованы . Вы объявляете их снова, что скрывает их в классе Kingdom.

По сути, это означает, что поля, которые вы здесь устанавливаете ...

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

не те, что в Kingdom. Поэтому методы в Kingdom не знают об этих новых полях, которые вы создали.

После удаления объявлений полей milk, wings и fruits будут ссылаться на поля, объявленные в классе 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";
    }
}

Кроме того, я думаю, что отношения между вашими классами немного странные. Animal и Plant являются примерами королевств, поэтому они должны быть экземплярами Kingdom, а не наследоваться от него. И Mammalia совсем не Kingdom. Королевства - это архебактерии, эубактерии, протисты, грибы, планты и животные.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...