OriginalGriff
Вы можете просто ввести это:
Circle c = new Circle();
(Shape)c;
И это действительно C# - он просто не делает ничего полезного, потому что вы отбрасываете значение, которое вы бросили.
Когда вы это сделаете:
Circle c = new Circle();
Shape s = c;
Вы создаете две переменные
c
и
s
, и вы заставляете их обоих ссылаться на один и тот же объект. Это как автомобили: "эта машина "и" моя машина " могут по-разному относиться к одному и тому же автомобилю.
При создании класса, производного от базового класса, как это делается с Circle и Shape, переменная Shape может содержать ссылку на любой экземпляр объекта Shape,
включая все объекты, которые относятся к классу, производному от формы потому что действие получения класса говорит: "этот новый класс является базовым классом, но он может сделать и больше".
В результате вы можете использовать свойства, методы и события из базового класса в любом экземпляре производного класса. Возвращаясь на мгновение к автомобилям. Если существует базовый класс автомобилей, то вы получаете производителя от него: Mercedes происходит от автомобиля, как и Ford, Ferrari и Audi. Это означает, что каждый автомобиль, производимый Mercedes, является автомобилем, но не означает, что каждый Ford - это Ferrari, потому что у них общая база. Переменная, содержащая автомобиль (например, «эта машина» или «эта машина», «моя машина» или «ваша машина», может делать все, что является общим для всех автомобилей): CountTheWheels (всегда возвращает 4), GetTheColour (потому что все автомобили имеют цвет), Drive (потому что все автомобили управляются очень похожим образом). Но вы не можете взять переменную Mercedes и выполнить для нее метод Ford: ServiceMyFord не существует для моей машины, потому что не было мистера Форда. Я не успел, мистер Бенц сделал это, а требования к обслуживанию другие.
Система использует фактический экземпляр, чтобы определить, какой он на самом деле тип, и вызвать правильный метод.
Например, у Car может быть метод DriveTo по умолчанию, который Mercedes переопределяет, но который Ford переопределяет по-другому - когда вы вызываете DriveTo для переменной Car, система просматривает содержимое, находит, что это Ford, и автоматически вызывает версию метода Ford.
Есть ли в этом смысл?
The_Unknown_Member
Да, это имеет смысл. Вы дали мне реальный пример и очень благодарны за это. Но я спрашивал не об этом. Я ужасно умею объяснять людям разные вещи и ненавижу себя за это. Просто посмотрите на этот код и я думаю вы поймете о чем я спрашиваю:
использование системы;
использование системы.Коллекции.Общий;
программа занятий
{
статический недействительным Главная()
{
List & lt;Person> people = новый список & lt;Person>();
люди.Добавить (новый сотрудник());
люди.Добавить (новый студент());
Человек п = нового сотрудника();
Employee e = p as Employee; / / я хочу спросить, что происходит в этом коде строки, когда я выполняю приведение в части назначения
}
}
класс person
{
public string Name { get; set; }
public int Age { get; set; }
}
классный работник: человек
{
public string ID { get; set; }
общественного недействительными IntroduceSelf()
{
Приставка.Метода WriteLine("Привет, меня зовут {0} и мой паспорт {1}", название, ID);
}
}
ученик класса: человек
{
public int GradeLevel { get; set; }
}
OriginalGriff
Это немного сложнее, чем ваш первоначальный пример: поскольку Employee происходит от Person, не каждый экземпляр Person является Employee - не больше, чем каждое транспортное средство является автомобилем; некоторые из них являются автобусом, грузовиком или мотоциклом.
Поэтому, когда вы используете "как":
Сотрудник e = p как сотрудник;
Значение в e может быть одним из двух разных:
1) это может быть экземпляр работника, если должность занимал сотрудник.
Или
2) это может быть нуль, если П был нулем, или P содержится некий человек, который не был сотрудником:
Студент = новый студент();
Человек p = s;
Сотрудник e = p как сотрудник;
В этом случае задействованный экземпляр является студентом - что означает, что это человек, - поэтому его можно хранить в переменной Person.
Но студент не является сотрудником, у них просто есть "общий предок" - человек, поэтому оператор "as" возвращает null, потому что студент не может быть преобразован в сотрудника.
Подумайте об этом: это единственное разумное решение. Если вы сохранили студента в переменной Employee, вы можете попытаться вызвать "PayWages" для студента - а студент не определяет метод PayWages, потому что никто не хочет ничего платить студентам! :смеяться:
Возвращаясь к автомобильным терминам, и Ford, и Ferrari являются примерами автомобиля - но вы не можете превратить Ford Ka в Ferrari, просто поменяв значки! (И люди будут много смеяться над вами, если вы это сделаете.)
The_Unknown_Member
Я думаю, что понял это.:
Человек п = нового сотрудника();
Сотрудник e = p как сотрудник;
Итак, в первой строке я делаю ссылку на человека с именем "p" и делаю эту ссылку, указывающую на экземпляр объекта Employee. Но поскольку ссылочная переменная имеет тип Person, я могу видеть только конкретные вещи для класса Person. Простыми словами: Я смотрю глазами человека. И во второй строке я делаю ссылочную переменную сотрудника с именем " e "и делаю эту переменную" e", указывающую на тот же адрес, на который указывает" p", но рассматриваемую как сотрудник.
Правильно ли я это понял ?
OriginalGriff
В значительной степени, да!
Единственная разница заключается в том, что даже если ваша переменная p является человеком, ссылающимся на сотрудника, система будет использовать методы сотрудника, если они переопределяют методы человека. Другими словами, если ваш класс Person имеет метод DoIt:
public virtual void DoIt () { консоль.WriteLine ("DoIt Person!"); }
И ваш класс сотрудников переопределяет это:
public override void DoIt () { консоль.WriteLine ("DoIt Employee"); }
Тогда этот код:
Человек п = нового сотрудника();
p. DoIt();
Все равно позвонит сотрудник версии и распечатает:
Сотрудник Доить
Поскольку система знает, что экземпляр является производным классом и имеет более релевантный метод, она использует его.