Почему базовый класс = новый производный класс не может вызывать метод производного класса? - PullRequest
0 голосов
/ 04 января 2019

У нас есть два класса A и B, B Получено из A, я создал A a = new B(); Почему в моем коде, когда я вызываю метод B, который не содержит AI, возникает ошибка.Означает ли это, что указатель типа объекта имеет тип A?и во-вторых, почему, когда я вызываю SomeMethod, он вызывает метод A, а не B?

В куче в этой ситуации при создании экземпляра объекта указатель типа объекта указывает на A или B?

class A
{
    public void SomeMethod()
    {
        Console.Write("This is A");
    }
}

class B : A
{
    public void SomeMethod()
    {
        Console.Write("This is B");
    }

    public void OtherMethod()
    {
        Console.Write("This is New method");
    }
}
class Program
{
    static void Main(string[] args)
    {
        A a = new B();

        a.SomeMethod(); // This is A method
        a.OtherMethod(); // I get error here that a does not contain definition for this method

    }
}

Ответы [ 3 ]

0 голосов
/ 04 января 2019

Вы должны указать, что хотите переопределить виртуальную функцию.Попробуйте это:

class A
{
    public virtual void SomeMethod()
    {
        Console.Write("This is A");
    }
}

class B : A
{
    public override void SomeMethod()
    {
        Console.Write("This is B");
    }

    public void OtherMethod()
    {
        Console.Write("This is New method");
    }
}
0 голосов
/ 04 января 2019

Чтобы получить доступ к OtherMethod там, где в данный момент происходит сбой, вы должны указать своему A действовать как B.

Изменить

a.OtherMethod();

на

(a as B).OtherMethod();
0 голосов
/ 04 января 2019

Поскольку вы пропускаете явное предупреждение в IDE

Код серьезности Описание Код проекта: Состояние подавления строки файла Предупреждение CS0108 «B.SomeMethod ()» скрывает унаследованный элемент «A.SomeMethod ()».Используйте новое ключевое слово, если было скрыто.

Предупреждение компилятора (уровень 2) CS0108

'member1' скрывает унаследованный член 'member2'.Используйте ключевое слово new, если было скрыто.

Была объявлена ​​переменная с тем же именем, что и переменная в базовом классе.Однако новое ключевое слово не использовалось.Это предупреждение информирует вас о том, что вы должны использовать новый;переменная объявляется так, как если бы new использовался в объявлении.

Если вы хотите скрыть это, используйте ключевое слово new

Однако, если вы хотите вызвать егозатем используйте virtual и override его или просто измените имя метода, чтобы не скрывать его

class A
{
   public virtual void SomeMethod()
   {
      Console.Write("This is A");
   }
}

class B : A
{
   public override void SomeMethod()
   {
      base.SomeMethod();
      Console.Write("This is B");
   }

   public void OtherMethod()
   {
      Console.Write("This is New method");
   }
}

virtual (C # Reference)

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

override (C # Reference)

Модификатор переопределения требуется длярасширить или изменить абстрактную или виртуальную реализацию унаследованного метода, свойства, индексатора или события.

Полиморфизм (Руководство по программированию в C #)


В куче в этой ситуации при создании экземпляра объекта указатель типа объекта указывает на A или B?

Вам не нужно беспокоиться о том, что происходит в куче (это детали реализации), только то, что позволяет язык.

Однако технически A не существует, есть только экземпляр B, который имеет всю реализацию A (если вам это нужно)

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