Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.75/8: Рейтинг темы: голосов - 8, средняя оценка - 4.75
6 / 6 / 5
Регистрация: 21.03.2014
Сообщений: 18
1

Не вызывается метод из базового типа после приведения типов?

23.03.2015, 10:46. Показов 1569. Ответов 10
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
При приведении типов от производного класса Manager к базовому классу Employee, у объекта "e" к которому был приведен Manager, вызывается метод из производного класса.
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
class Employee{
   public int Id { get; set; }
 
   public virtual void Foo(){
      Console.WriteLine("Hello Employee");
  }
}
 
class Manager : Employee{
   public string Name { get; set; }
 
   public virtual void Foo(){
      Console.WriteLine("Hello Manager");
  }
}
...   
   static void Main(){
      Manager m = new Manager();
      Employee e = m;
      
      e.Id = 10;//объект e содержит собственное свойство Id
      e.FirstName = "Foo";//объект e не содержит FirstName, из класса Manager
 
      e.Foo();//output: Hello Manager
 
      Console.WriteLine(e);//output: Manager
   }
Почему не вызывается метод из базового типа после приведения?
0
Лучшие ответы (1)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
23.03.2015, 10:46
Ответы с готовыми решениями:

Вызывается метод из базового класса
Имеется 2 класса: В 1 классе Data имеются такие методы: private string GetUpdateQuerryString()...

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

Как сделать явное приведения переменной типа класса-наследника к типу базового класса?
Читал, что для этого нужно явное приведение к типу, но на практике выдаёт ошибку. Вот код: using...

Почему при восходящем приведении типов вызывается метод класса потомка?
class T1 { public virtual void P() { Console.WriteLine(1); } } class T2 : T1...

10
211 / 201 / 63
Регистрация: 24.09.2014
Сообщений: 532
23.03.2015, 10:50 2
так и задумано. дока
1
6 / 6 / 5
Регистрация: 21.03.2014
Сообщений: 18
23.03.2015, 12:01  [ТС] 3
Сорри, опечатался.
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
//метод переопределяется в производном классе Manager
public override void Foo(){
      Console.WriteLine("Hello Manager");
  }
...
//приведение типов
Manager m = new Manager();
Employee e = m;
 
e.Foo();//после приведения вызывается метод Manager.Foo();
 
//после приведения к Employee, тип объекта по прежнему Manager
Console.WriteLine(e);//output: Manager
По идеи после приведения, должна подцепляться базовая реализация метода Foo().
0
Эксперт .NET
5546 / 4309 / 1218
Регистрация: 12.10.2013
Сообщений: 12,371
Записей в блоге: 2
23.03.2015, 12:16 4
Цитата Сообщение от ALGORE Посмотреть сообщение
после приведения
А где вы тут усмотрели приведение типов? Я вот его никак не вижу...
Вижу создание экземпляра производного класса. Вижу создание ссылки типа родителя класса с присвоением ей ссылки на экземпляр наследника. Все. Ни о каком приведении типов речи тут нет.
0
Эксперт Python
4640 / 2056 / 363
Регистрация: 17.03.2012
Сообщений: 10,139
Записей в блоге: 6
23.03.2015, 12:26 5
Так и надо. Переопределили в потомке - значит, работает потомок. Грош цена была бы всему этому наследованию с переопределением, если бы вызывались методы предка.
0
6 / 6 / 5
Регистрация: 21.03.2014
Сообщений: 18
23.03.2015, 12:31  [ТС] 6
C#
1
2
3
4
5
6
7
8
9
10
//создаем экземпляр Manager
Manager m = new Manager();
//Создаем экземпляр Employee
Employee e = new Employee;
 
//присвоить объекту e объект m
//явное преобразование
e = (Employee) m;
 
e.Foo();////output: Hello Manager
0
Эксперт .NET
5546 / 4309 / 1218
Регистрация: 12.10.2013
Сообщений: 12,371
Записей в блоге: 2
23.03.2015, 12:41 7
ALGORE, не совсем понятно, что вы пытаетесь сделать? Добраться до реализации метода в базовом классе?
0
6 / 6 / 5
Регистрация: 21.03.2014
Сообщений: 18
23.03.2015, 13:04  [ТС] 8
Понятно, что с помощью virtual и override мы можем переопределять в наследниках члены.

Вопрос в другом.
Почему преобразуя производный тип к базовому, сохраняется переопределенный метод производного типа, мы же по сути отбрасываем наследника.

Почему метод ToString()/GetType() преобразованного объекта, возвращает имя производного типа, а не базового.
C#
1
2
3
Console.WriteLine(e);//output: Manager
//Console.WriteLine(e.ToString());//output: Manager
//Console.WriteLine(e.GetType());//output: Manager
0
Эксперт .NET
5546 / 4309 / 1218
Регистрация: 12.10.2013
Сообщений: 12,371
Записей в блоге: 2
23.03.2015, 13:10 9
Лучший ответ Сообщение было отмечено ALGORE как решение

Решение

Цитата Сообщение от ALGORE Посмотреть сообщение
Почему метод ToString()/GetType() преобразованного объекта, возвращает имя производного типа, а не базового.
А с какой стати он должен так делать? Его тип - тип наследника, и то что вы можете в ссылке типа родителя хранить ссылку на объект наследника (что работает благодаря неявному преобразованию типов сверху вниз), не значит что метод GetType() скажет, что объект стал типа родителя.
А что касается метода - тоже вполне ожидаемо. Наследник переопределил метод родителя, и он будет вызываться, какая бы ссылка не указывала на этот объект - наследника или родителя. До "собственной" реализации метода в родителе вы никак не доберетесь, объект-то создан наследником, и метод уже переопределен.
1
Эксперт .NET
17794 / 12945 / 3381
Регистрация: 17.09.2011
Сообщений: 21,228
23.03.2015, 13:11 10
Цитата Сообщение от ALGORE Посмотреть сообщение
Почему преобразуя производный тип к базовому, сохраняется переопределенный метод производного типа, мы же по сути отбрасываем наследника.
Потому что если обращаться к вам как к примату, выполнять действие "ходить" вы все равно будете как человек.
0
Эксперт .NET
5546 / 4309 / 1218
Регистрация: 12.10.2013
Сообщений: 12,371
Записей в блоге: 2
23.03.2015, 13:18 11
ALGORE, если вам надо обязательно добираться до реализации метода в родителе, то следует изменить в реализации метода наследника модификатор override на new. Тогда это возможно. Примерно вот так.
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace ConsoleApplication2 {
    class Program {
        static void Main(string[] args) {
            Manager m = new Manager();
            Employee e = new Employee();
 
            m.Foo();
            ((Employee)m).Foo();
        }
    }
    class Employee {
        public int Id { get; set; }
 
        public virtual void Foo() {
            Console.WriteLine("Hello Employee");
        }
    }
 
    class Manager : Employee {
        public string Name { get; set; }
 
        public new void Foo() {
            Console.WriteLine("Hello Manager");
        }
    }
}
0
23.03.2015, 13:18
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
23.03.2015, 13:18
Помогаю со студенческими работами здесь

Вызов оператора приведения базового класса
Добрый день. У меня есть иерархия классов. class A: B { ... operator...

Почему если при вызове метода Foo от типа B, в объекте класса FooImp вызывается метод от А?
Поясните пожалуйста, почему если при вызове метода Foo от типа B, в объекте класса FooImp...

Метод в конструкторе вызывается задолго после создания объекта
Не знаю как загуглить это, поэтому обращаюсь к живым людям. Есть классы Group, Student, Subject....

Метод вызывается только после второго нажатия на кнопку
есть метод import com.github.nkzawa.emitter.Emitter; import...

Не вызывается конструктор базового класса
Доброго времени суток. У меня проблема:в производном классе не вызывается конструктор базового...

Не вызывается нужный конструктор базового класса
Здравствуйте. Я пока в процессе изучения С++. Имеется следующая структура классов: Базовый:...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
11
Ответ Создать тему
Новые блоги и статьи
Как запретить подсветку выделенного текста с помощью CSS
InfoMaster 20.01.2025
Подсветка текста при выделении является стандартным поведением браузера, которое не всегда соответствует дизайнерским решениям или функциональным требованиям веб-приложения. Выделение текста может. . .
Как выполнить другую программу или системную команду из Python
InfoMaster 20.01.2025
Python предоставляет мощные инструменты для выполнения системных команд и управления внешними процессами, что делает его идеальным выбором для автоматизации различных задач системного. . .
Как узнать директорию bash-скрипта из самого bash-скрипта
InfoMaster 20.01.2025
При разработке bash-скриптов одной из важных задач является определение директории, в которой находится исполняемый скрипт. Это критически важно для корректной работы с файлами, загрузки конфигураций. . .
В чем разница между let и var в JavaScript
InfoMaster 20.01.2025
JavaScript прошел длинный путь эволюции с момента своего создания в 1995 году. Одним из важнейших аспектов развития языка стало совершенствование механизмов объявления и управления переменными. . . .
Эффективная работа со строками в Go
InfoMaster 20.01.2025
Язык программирования Go предлагает уникальный подход к работе со строками, который существенно отличается от многих других языков программирования. В Go строки представляют собой неизменяемые. . .
Как проверить, что отображение (map) содержит ключ в Go
InfoMaster 20.01.2025
Отображения (maps) в языке программирования Go представляют собой мощные структуры данных, которые позволяют хранить пары ключ-значение и обеспечивают быстрый доступ к данным по уникальным. . .
Как организовать домашнее хранилище фильмов с общим доступом для всей семьи
InfoMaster 20.01.2025
Преимущества домашнего медиасервера В современном мире, где цифровой контент стал неотъемлемой частью нашей жизни, организация домашнего медиасервера становится все более актуальной задачей. . . .
Перспективы развития жестких дисков: есть ли у них будущее?
InfoMaster 20.01.2025
История и эволюция жестких дисков История развития жестких дисков начинается в 1956 году, когда компания IBM представила первое устройство для хранения данных на магнитных пластинах - IBM 350. . .
Распознавание изображений (компьютерное зрение) на C++
InfoMaster 20.01.2025
Введение в компьютерное зрение и основы работы с изображениями Компьютерное зрение представляет собой одну из наиболее динамично развивающихся областей информационных технологий, позволяющую. . .
Какой язык программировани­я лучший для разработки нейронных сетей
InfoMaster 20.01.2025
В современном мире технологий искусственные нейронные сети становятся неотъемлемой частью множества инновационных решений, от распознавания речи до автоматического управления транспортными. . .
Как подключить JavaScript файл в другом JavaScript файле
InfoMaster 20.01.2025
В современной веб-разработке организация кодовой базы играет ключевую роль в создании масштабируемых и поддерживаемых приложений. Модульность и правильное структурирование кода стали неотъемлемыми. . .
Как откатить изменения в исходниках, не внесенные в Git
InfoMaster 20.01.2025
При работе с системой контроля версий Git разработчики часто сталкиваются с необходимостью отменить внесенные изменения в исходном коде. Особенно актуальной становится ситуация, когда изменения еще. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru