Я новичок в C # (и ООП ). Когда у меня есть такой код:
class Employee
{
// some code
}
class Manager : Employee
{
//some code
}
Вопрос 1 : Если у меня есть другой код, который делает это:
Manager mgr = new Manager();
Employee emp = (Employee)mgr;
Вот Employee
он Manager
, но когда я его вот так Employee
передаю, это означает, что я его повышаю?
Вопрос 2 :
Когда у меня есть несколько Employee
объектов класса, и некоторые из них, но не все, являются объектами Manager
, как я могу их уменьшить, где это возможно?
Employee emp= mgr;
должно хватить.Ответы:
Это правильно. Когда вы это делаете, вы преобразуете его в
employee
объект, а это значит, что вы не можете получить доступ ни к чему конкретному менеджеру.При понижении качества вы берете базовый класс, а затем пытаетесь превратить его в более конкретный класс. Этого можно добиться с помощью is и явного приведения типа:
if (employee is Manager) { Manager m = (Manager)employee; //do something with it }
или с таким
as
оператором:Manager m = (employee as Manager); if (m != null) { //do something with it }
Если что-то непонятно, буду рад исправить!
источник
as
оператор вместоis
, за которым следует приведение.Апкастинг (использование
(Employee)someInstance
) обычно прост, поскольку компилятор может сообщить вам во время компиляции, является ли тип производным от другого.Однако обычно понижающее преобразование должно выполняться во время выполнения, поскольку компилятор не всегда может знать, относится ли рассматриваемый экземпляр к заданному типу. C # предоставляет для этого два оператора - is, который сообщает вам, работает ли понижающее преобразование, и возвращает true / false. И as which пытается выполнить приведение и возвращает правильный тип, если это возможно, или null, если нет.
Чтобы проверить, является ли сотрудник менеджером:
Employee m = new Manager(); Employee e = new Employee(); if(m is Manager) Console.WriteLine("m is a manager"); if(e is Manager) Console.WriteLine("e is a manager");
Вы также можете использовать это
Employee someEmployee = e as Manager; if(someEmployee != null) Console.WriteLine("someEmployee (e) is a manager"); Employee someEmployee = m as Manager; if(someEmployee != null) Console.WriteLine("someEmployee (m) is a manager");
источник
В твоем случае
Employee emp = (Employee)mgr; //mgr is Manager
вы делаете апкастинг.
Приведение вверх всегда успешно, в отличие от понижающего, которое требует явного приведения, поскольку оно потенциально может завершиться ошибкой во время выполнения ( InvalidCastException ).
C # предлагает два оператора, чтобы избежать генерации этого исключения:
Начиная с:
Employee e = new Employee();
Первый:
Manager m = e as Manager; // if downcast fails m is null; no exception thrown
Второй:
if (e is Manager){...} // the predicate is false if the downcast is not possible
Предупреждение : когда вы выполняете апкастинг, вы можете получить доступ только к методам, свойствам суперкласса и т. Д.
источник
Если вам нужно проверить каждый объект Employee, является ли он объектом Manager, используйте метод OfType:
List<Employee> employees = new List<Employee>(); //Code to add some Employee or Manager objects.. var onlyManagers = employees.OfType<Manager>(); foreach (Manager m in onlyManagers) { // Do Manager specific thing.. }
источник
Ответ 1: Да, это называется апкастингом, но то, как вы это делаете, не современно. Повышение качества может выполняться неявно, вам не нужно никакого преобразования. Так что просто напишите Employee emp = mgr; достаточно для апкастинга.
Ответ 2: Если вы создаете объект класса Manager, мы можем сказать, что менеджер является сотрудником. Потому что класс Manager: Employee отображает отношения Is-A между классом Employee и классом Manager. Таким образом, можно сказать, что каждый менеджер - это сотрудник.
Но если мы создаем объект класса Employee, мы не можем сказать, что этот сотрудник является менеджером, потому что класс Employee - это класс, который не наследует какой-либо другой класс. Таким образом, вы не можете напрямую преобразовать этот объект класса Employee Class в объект класса Manager.
Итак, ответ таков: если вы хотите преобразовать объект класса Employee в объект класса диспетчера, сначала вы должны иметь объект класса диспетчера, затем вы можете его преобразовать, а затем вы можете уменьшить его.
источник
Повышение и понижение:
Повышение качества: приведение от производного класса к базовому классу. Приведение вниз: приведение от базового класса к производному классу
Разберем то же самое на примере:
Рассмотрим два класса Shape как родительский класс и Circle как производный класс, определенные следующим образом:
class Shape { public int Width { get; set; } public int Height { get; set; } } class Circle : Shape { public int Radius { get; set; } public bool FillColor { get; set; } }
Апкастинг:
Форма s = новая форма ();
Круг c = s;
И c, и s ссылаются на одну и ту же ячейку памяти, но оба они имеют разные представления, т.е. используя ссылку «c», вы также можете получить доступ ко всем свойствам базового и производного классов, но используя ссылку «s», вы можете получить доступ к свойствам единственного родительского класса.
Практическим примером апкастинга является класс Stream, который является базовым классом для всех типов потокового считывателя фреймворка .net:
StreamReader reader = новый StreamReader (новый FileStreamReader ());
здесь FileStreamReader () преобразован в streadm reder.
Понижение:
Форма s = новый круг (); здесь, как объяснено выше, представление s является единственным родителем, чтобы сделать его и для родителя, и для ребенка, нам нужно его уменьшить
var c = (Круг) s;
Практическим примером Downcasting является класс кнопок WPF.
источник