Наследование как средство изменения базового класса
Реализуется через переопределение полей, методов и свойств базо- вого класса в классе-потомке. На практике чаще всего используется из- менение поведения – т.е. переопределение методов.
Синтаксически это реализуется как определение в классе-потомке метода с тем же именем, составом параметров и возвращаемым значени- ем, что и в базовом классе.


ссылка ссылка
![]() |
|||
Рис.6
С# поддерживает два способа переопределения метода, определен- ного в базовом классе на метод, определенный в классе-потомке (Рис.6):
1. new – новая версия метода. Решение о вызываемом методе прини- мается по типу ссылки. Через ссылку класса-предка вызывается метод, определенный в классе предке, а через ссылку класса-потомка вызыва- ется метод, определенный в классе-потомке.
2. override – метод, заменяющий метод предка. Метод может быть вы- зван через ссылку класса-потомка или ссылку базового класса. Решение о вызываемом методе принимается по типу объекта, на который указы- вает ссылка. Для реализации этого способа метод в классе-предке дол- жен быть объявлен как виртуальный (virtual).
class Человек
{
protected string фам; public Человек(string фам)
{
this.фам = фам;
}
public virtual void Показать()
{
Console.WriteLine("Я - человек: " + фам);
}
}
class Студент:Человек
{
private string вуз;
public Студент(string фам, string вуз):base(фам)
{
this.вуз = вуз;
}
}
class Владелец: Человек
{
private string ном;
public Владелец(string фам, string ном): base(фам)
{
this.ном = ном;
}
public new void Показать()
{
Console.WriteLine("Я - владелец: " + фам + " --> " + ном);
}
}
class Служащий: Человек
{
private string фирма;
public Служащий(string фам, string фирма): base(фам)
{
this.фирма = фирма;
}
public override void Показать()
{
Console.WriteLine("Я - служащий: "+фам +"
}
}
"+ фирма);
class Program
{
static void Main(string[] args)
{
Человек ч;
Студент ст = new Студент("Иванов","ВШЭ");
Владелец вл = new Владелец("Петров", "A777AA-99RUS");
Служащий сл = new Служащий("Сидоров", "Рога и копыта");
ч = ст;
ч.Показать(); //Вызов метода предка
//Я - человек: Иванов
ст.Показать(); //Вызов метода предка
//Я - человек: Иванов
ч = вл;
ч.Показать(); //Вызов метода предка
//Я - человек: Петров
вл.Показать(); //Вызов метода наследника
//Я - владелец: Петров --> A777AA-99RUS
ч = сл;
ч.Показать(); //Вызов метода наследника
//Я - служащий: Сидоров Рога и копыта
сл.Показать(); //Вызов метода наследника
//Я - служащий: Сидоров
}
}
Рога и копыта
Применение вызова переопределенного метода override позволяет просто решить проблему определения вызываемого метода при хранении в массиве объектов разного типа. Массив организуется как массив ссы- лок базового типа. Вызываемый метод определяется автоматически по типу объекта, на который указывает ссылка.
Метод в базовом классе может быть объявлен как абстрактный. Такой метод не содержит реализации – тела. Это только заголовок. Другими словами, базовый класс только декларирует общее поведение, а реали- зовать его обязаны потомки. В этом отличие абстрактных методов от виртуальных. Виртуальный метод может, но не обязан быть переопреде- лен в потомках. Абстрактный метод должен быть переопределен в клас- се-потомке в обязательном порядке.
Класс, содержащий хотя бы один абстрактный метод, является абст- рактным, о чем должно быть указано в определении класса
abstract class ИмяКласса
{
……………………………
}
Потомки обязаны переопределять абстрактный метод с модификатором override (new невозможно, т.к. у предка нет никакой версии реализации метода).
abstract class Человек
{
protected string фам; public Человек(string фам)
{
this.фам = фам;
}
public abstract void Показать();
}
class Студент:Человек
{
private string вуз;
public Студент(string фам, string вуз):base(фам)
{
this.вуз = вуз;
}
public override void Показать()
{
Console.WriteLine("Я - студент: " + фам + " " + вуз);
}
}
class Владелец: Человек
{
private string ном;
public Владелец(string фам, string ном): base(фам)
{
this.ном = ном;
}
public override void Показать()
{
Console.WriteLine("Я - владелец: " + фам + " --> " + ном);
}
}
class Служащий: Человек
{
private string фирма;
public Служащий(string фам, string фирма): base(фам)
{
this.фирма = фирма;
}
public override void Показать()
{
Console.WriteLine("Я - служащий: "+фам + "
}
}
" + фирма);
class Program
{
static void Main(string[] args)
{
Человек ч;
Студент ст = new Студент("Иванов","ВШЭ");
Владелец вл = new Владелец("Петров", "A777AA-99RUS"); Служащий сл = new Служащий("Сидоров", "Рога и копыта"); ч = ст;
ч.Показать(); //Вызов метода наследника
//Я - студент: Иванов ВШЭ
ст.Показать(); //Вызов метода наследника
//Я - студент: Иванов ВШЭ
ч = вл;
ч.Показать(); //Вызов метода наследника
//Я - владелец: Петров --> A777AA-99RUS
вл.Показать(); //Вызов метода наследника
//Я - владелец: Петров --> A777AA-99RUS
ч = сл;
ч.Показать(); //Вызов метода наследника
//Я - служащий: Сидоров Рога и копыта
сл.Показать(); //Вызов метода наследника
//Я - служащий: Сидоров
}
}
Рога и копыта
Объекты абстрактного класса создать невозможно.
Материалы на данной страницы взяты из открытых источников либо размещены пользователем в соответствии с договором-офертой сайта. Вы можете сообщить о нарушении.