Переопределение и наследование в C #

Хорошо, терпите меня, парни и девушки, пока я учусь. Вот мой вопрос.

Я не могу понять, почему я не могу переопределить метод из родительского класса. Вот код из базового класса (да, я украл код Java из книги ООП и пытаюсь переписать его в C #).

using System;

public class MoodyObject
{
    protected String getMood()
    {
        return "moody";
    }

    public void queryMood()
    {
        Console.WriteLine("I feel " + getMood() + " today!");
    }
}

и вот мои два других объекта, которые наследуют базовый класс (MoodyObject):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    public class SadObject: MoodyObject
    {
        protected String getMood()
        {
            return "sad";
        }

        //specialization
        public void cry()
        {
            Console.WriteLine("wah...boohoo");
        }
    }
}

И:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    public class HappyObject: MoodyObject
    {
        protected String getMood()
        {
            return "happy";
        }

        public void laugh()
        {
            Console.WriteLine("hehehehehehe.");
        }
    }
}

и вот мой основной:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            MoodyObject moodyObject = new MoodyObject();
            SadObject sadObject = new SadObject();
            HappyObject happyObject = new HappyObject();

            Console.WriteLine("How does the moody object feel today?");
            moodyObject.queryMood();
            Console.WriteLine("");
            Console.WriteLine("How does the sad object feel today?");
            sadObject.queryMood();
            sadObject.cry();
            Console.WriteLine("");
            Console.WriteLine("How does the happy object feel today?");
            happyObject.queryMood();
            happyObject.laugh();
        }
    }
}

Как видите, довольно простые вещи, но вот результат:

Как чувствует себя настроенный объект сегодня? Сегодня я чувствую себя угрюмо!

Как грустный объект чувствует себя сегодня? Я чувствую себя угрюмым сегодня! вау ... буху

Как чувствует себя счастливый объект сегодня? Я чувствую себя угрюмым сегодня! hehehehehehe. Нажмите любую клавишу для продолжения . , .

Не так, как я ожидал. Я попытался сделать базовый метод виртуальным и вызвать переопределение при попытке переопределить его, и это просто вызывает у меня эту ошибку "не может переопределить унаследованный член" MoodyObject.getMood () ', потому что он не помечен как виртуальный, абстрактный или переопределенный ". Я также попробовал это без виртуального и переопределения, и он думает, что я пытаюсь скрыть базовый метод. Опять же, я новичок в ООП и буду признателен за любые рекомендации.

ИЗДАНО ДЛЯ ДОБАВЛЕНИЯ: Я нашел это! MoodyObject.cs был только «элементом решения» в обозревателе решений, а не элементом «ConsoleApplication1». Я перетащил его туда, где он был в проводнике решений и вуаля! Это работает сейчас. Я пометил ответ Люка ниже как ответ, потому что он предложил помощь, в которой я нуждался, чтобы добраться туда, где я ее решил ... Я здесь многому учусь Это удивительно, и вы, ребята, и девушки сумасшедшие умные!

23
задан Cœur 11 July 2019 в 15:03
поделиться

8 ответов

В методах C# не являются виртуальными по умолчанию, поэтому если Вы разрабатываете некоторый метод, столь же переопределяемый, необходимо определить его как виртуальный:

class Base 
{
  protected virtual string GetMood() {...}
}
114-секундный, необходимо определить, что Вы идете в переопределенный метод от базового класса в производном классе.

class Derived : Base
{
  protected override string GetMood() {...}
}

, Если Вы не определяете ключевое слово "переопределения", Вы получите метод, который скрывает базовый тип (и предупреждение из компилятора для помещения "нового" ключевого слова для метода для явного утверждения так).

, Если Вы хотите остановить цепочку наследования и запретить дальнейшие переопределения метода, необходимо отметить метод, как изолировано, как это:

  protected sealed override string GetMood() {...}
61
ответ дан Ilya Ryzhenkov 11 July 2019 в 15:03
поделиться

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

public class MoodyObject
{
    protected virtual String getMood() 
    { 
        return "moody"; 
    }    
    public void queryMood() 
    { 
        Console.WriteLine("I feel " + getMood() + " today!"); 
    }
}

public class HappyObject : MoodyObject
{
    protected override string getMood()
    {
        return "happy";
    }
}

, Что я рекомендовал бы, вот то, что Вы прочертовский предназначенный для MoodyObject, чтобы быть абстрактным классом. (Необходимо ли было бы изменить основной метод, если Вы делаете это, но необходимо исследовать его), действительно имеет смысл быть в капризном режиме? Проблема с тем, что мы имеем выше, состоит в том, что Ваш HappyObject не обязан обеспечивать реализацию для getMood. Путем создания краткого обзора класса это делает несколько вещей:

  1. Вы не можете новый экземпляр абстрактного класса. Необходимо использовать дочерний класс.
  2. можно вынудить полученных детей реализовать определенные методы.

Так, чтобы сделать это Вы заканчиваете:

public abstract class MoodyObject
{
    protected abstract String getMood();

    public void queryMood() 
    { 
        Console.WriteLine("I feel " + getMood() + " today!"); 
    }
}

Примечание, как Вы больше не обеспечиваете реализацию для getMood.

7
ответ дан JoshBerke 11 July 2019 в 15:03
поделиться

Насколько я знаю в Java, все методы являются виртуальными по умолчанию. Дело обстоит не так с C#, таким образом, необходимо отметить методы базового класса с "виртуальным", например, protected virtual string getMood() ... и переопределения с "переопределением", например, protected override string getMood()....

5
ответ дан Dan C. 11 July 2019 в 15:03
поделиться

Необходимо сказать C#, что объект переопределяет функцию от базового класса.

Вот статья MSDN о синтаксисе, в котором Вы нуждаетесь: http://msdn.microsoft.com/en-us/library/ebca9ah3 (По сравнению с 71) .aspx

public class SadObject: MoodyObject    
{        
    override String getMood()
2
ответ дан Jeremiah 11 July 2019 в 15:03
поделиться

Если Вы хотите переопределить метод базового класса, он должен быть объявлен как virtual. Метод переопределения в производном классе должен быть явно объявлен как override. Это должно работать:

public class BaseObject
{
    protected virtual String getMood()
    {
        return "Base mood";
    }

    //...
}

public class DerivedObject: BaseObject
{
    protected override String getMood()
    {
        return "Derived mood";
    }
    //...
}

Редактирование: я просто попробовал его в c# консольном приложении, и это компилирует. Таким образом, исходный код, который Вы используете, должен отличаться по некоторой крошечной, но важной части от того, что Вы отправили здесь.

Мой program.cs - это:

using System;
using System.Collections.Generic;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {    
            // leaving out your implementation to save space...    
        }
    }    

    public class SadObject : MoodyObject
    {
        protected override String getMood()
        {
            return "sad";
        }

        //specialization
        public void cry()
        {
            Console.WriteLine("wah...boohoo");
        }
    }

    public class HappyObject : MoodyObject
    {
        protected override String getMood()
        {
            return "happy";
        }

        public void laugh()
        {
            Console.WriteLine("hehehehehehe.");
        }
    }
}
3
ответ дан Treb 11 July 2019 в 15:03
поделиться
public class SadObject: MoodyObject
    {
        override String getMood()
1
ответ дан James Curran 11 July 2019 в 15:03
поделиться

Путем создания метода GetMood virtual в Moody и override в производных классах, должен работать код. Вы уверены, что поместили эти ключевые слова, где они принадлежат? Вот полный код, который компилирует и выполненный очень хорошо:

public class MoodyObject
{
    protected virtual String getMood()
    {
        return "moody";
    }

    public void queryMood()
    {
        Console.WriteLine("I feel " + getMood() + " today!");
    }
}

public class SadObject : MoodyObject
{
    protected override String getMood()
    {
        return "sad";
    }

    //specialization
    public void cry()
    {
        Console.WriteLine("wah...boohoo");
    }
}

public class HappyObject : MoodyObject
{
    protected override String getMood()
    {
        return "happy";
    }

    public void laugh()
    {
        Console.WriteLine("hehehehehehe.");
    }
}

class Program
{
    static void Main(string[] args)
    {
        MoodyObject moodyObject = new MoodyObject();
        SadObject sadObject = new SadObject();
        HappyObject happyObject = new HappyObject();

        Console.WriteLine("How does the moody object feel today?");
        moodyObject.queryMood();
        Console.WriteLine("");
        Console.WriteLine("How does the sad object feel today?");
        sadObject.queryMood();
        sadObject.cry();
        Console.WriteLine("");
        Console.WriteLine("How does the happy object feel today?");
        happyObject.queryMood();
        happyObject.laugh();

        Console.Read();
    }
}

, Возможно, Ваша ошибка прибывает из того, что в Java, все методы являются виртуальными, который не имеет место, C# (как указано Dan C.).

2
ответ дан Luc Touraille 11 July 2019 в 15:03
поделиться

Необходимо отметить переопределения getMood с ключевым словом "переопределения". Необходимо будет также отметить основу getMood метод с "виртуальным" ключевым словом.

0
ответ дан Kevin Tighe 11 July 2019 в 15:03
поделиться
Другие вопросы по тегам:

Похожие вопросы: