Полное руководство по языку программирования С# 14 и платформе .NET 10 / Объектно-ориентированное программирование

Различие переопределения и скрытия методов

Начальный ⏱ 2 мин чтения 👁 2 🕓 обновлено 11.08.2026

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

Переопределение

Возьмем пример с переопределением методов:


class Person
{
	public string Name { get; set; }
	public Person(string name)
	{
		Name = name;
	}
	public virtual void Print()
	{
		Console.WriteLine(Name);
	}
}
class Employee : Person
{
	public string Company { get; set; }
	public Employee(string name, string company)
		: base(name)
	{
		Company = company;
	}

	public override void Print()
	{
		Console.WriteLine($"{Name} работает в {Company}");
	}
}

Используем классы в программе:


Person tom = new Employee("Tom", "Microsoft");
tom.Print();		// Tom работает в Microsoft

При вызове tom.Print() выполняется реализация метода Print из класса Employee, несмотря на то, что переменная tom - переменная типа Person.

Для работы с виртуальными методами компилятор формирует таблицу виртуальных методов (Virtual Method Table или VMT). В нее записывается адреса виртуальных методов. Для каждого класса создается своя таблица.

Когда создается объект класса, то компилятор передает в конструктор объекта специальный код, который связывает объект и таблицу VMT.

А при вызове виртуального метода из объекта берется адрес его таблицы VMT. Затем из VMT извлекается адрес метода и ему передается управление. То есть процесс выбора реализации метода производится во время выполнения программы. Собственно так и выполняется виртуальный метод. Следует учитывать, что так как среде выполнения вначале необходимо получить из таблицы VMT адрес нужного метода, то это немного замедляет выполнение программы.

Скрытие

Теперь возьмем те же классы Person и Employee, но вместо переопределения используем сокрытие:


class Person
{
	public string Name { get; set; }
	public Person(string name)
	{
		Name = name;
	}

	public void Print()
	{
		Console.WriteLine(Name);
	}
}

class Employee : Person
{
	public string Company { get; set; }
	public Employee(string name, string company)
			: base(name)
	{
		Company = company;
	}
	public new void Print()
	{
		Console.WriteLine($"{Name} работает в {Company}");
	}
}

И посмотрим, что будет в следующем случае:


Person tom = new Employee("Tom", "Microsoft");
tom.Print();		// Tom

Переменная tom представляет тип Person, но хранит ссылку на объект Employee. Однако при вызове метода Print будет выполняться та версия метода, которая определена именно в классе Person, а не в классе Employee. Почему? Класс Employee никак не переопределяет метод Print, унаследованный от базового класса, а фактически определяет новый метод. Поэтому при вызове tom.Print() вызывается метод Print из класса Person.

Проверь себя

📋 Тест по теме «Различие переопределения и скрытия методов» Тест по теме

Практические задания

Лёгкое Ручная проверка Заполните пропуск в коде (1)
+10 XP

В приведённом ниже фрагменте кода из этого урока пропущено одно слово. Определите его и впишите в поле ответа (без кавычек и пробелов).

class _____
{
	public string Name { get; set; }
	public Person(string name)
	{
		Name = name;
	}
	public virtual void Print()
	{
		Console.WriteLine(Name);
	}
}
class Employee : Person
{
	public string Company { get; set; }
	public Employee(string name, string company)
		: base(name)
	{
		Company = company;
	}

	public override void Print()
	{
		Console.WriteLine($"{Name} работает в {Company}");
	}
}
Войдите, чтобы отправить решение
Лёгкое Ручная проверка Заполните пропуск в коде (2)
+10 XP

В приведённом ниже фрагменте кода из этого урока пропущено одно слово. Определите его и впишите в поле ответа (без кавычек и пробелов).

Person _____ = new Employee("Tom", "Microsoft");
tom.Print();		// Tom работает в Microsoft
Войдите, чтобы отправить решение
Лёгкое Ручная проверка Заполните пропуск в коде (3)
+10 XP

В приведённом ниже фрагменте кода из этого урока пропущено одно слово. Определите его и впишите в поле ответа (без кавычек и пробелов).

class Person
{
	public string Name { _____; set; }
	public Person(string name)
	{
		Name = name;
	}

	public void Print()
	{
		Console.WriteLine(Name);
	}
}

class Employee : Person
{
	public string Company { get; set; }
	public Employee(string name, string company)
			: base(name)
	{
		Company = company;
	}
	public new void Print()
	{
		Console.WriteLine($"{Name} работает в {Company}");
	}
}
Войдите, чтобы отправить решение
Лёгкое Ручная проверка Заполните пропуск в коде (4)
+10 XP

В приведённом ниже фрагменте кода из этого урока пропущено одно слово. Определите его и впишите в поле ответа (без кавычек и пробелов).

Person tom = new _____("Tom", "Microsoft");
tom.Print();		// Tom
Войдите, чтобы отправить решение
Лёгкое Ручная проверка Заполните пропуск в коде (5)
+10 XP

В приведённом ниже фрагменте кода из этого урока пропущено одно слово. Определите его и впишите в поле ответа (без кавычек и пробелов).

class Person
{
	public string Name { get; set; }
	public Person(string _____)
	{
		Name = name;
	}
	public virtual void Print()
	{
		Console.WriteLine(Name);
	}
}
class Employee : Person
{
	public string Company { get; set; }
	public Employee(string name, string company)
		: base(name)
	{
		Company = company;
	}

	public override void Print()
	{
		Console.WriteLine($"{Name} работает в {Company}");
	}
}
Войдите, чтобы отправить решение
Среднее Ручная проверка Восстановите код по памяти (1)
+20 XP

В этом фрагменте кода урока пропущены два ключевых элемента. Впишите оба пропущенных значения через запятую в порядке появления (например: x, 5).

class Person
{
	public string Name { get; set; }
	public Person(string name)
	{
		Name = name;
	}
	public virtual void Print()
	{
		Console._____(Name);
	}
}
class _____ : Person
{
	public string Company { get; set; }
	public Employee(string name, string company)
		: base(name)
	{
		Company = company;
	}

	public override void Print()
	{
		Console.WriteLine($"{Name} работает в {Company}");
	}
}
Войдите, чтобы отправить решение
Среднее Ручная проверка Восстановите код по памяти (2)
+20 XP

В этом фрагменте кода урока пропущены два ключевых элемента. Впишите оба пропущенных значения через запятую в порядке появления (например: x, 5).

Person _____ = new Employee("_____", "Microsoft");
tom.Print();		// Tom работает в Microsoft
Войдите, чтобы отправить решение
Сложное Ручная проверка Объясните и модифицируйте пример из урока «Различие переопределения и скрытия методов»
+30 XP

Опишите своими словами, что делает приведённый пример кода из урока «Различие переопределения и скрытия методов», и предложите одно осмысленное изменение (например, другое входное значение или дополнительное условие). Приведите итоговый код.

class Person
{
	public string Name { get; set; }
	public Person(string name)
	{
		Name = name;
	}
	public virtual void Print()
	{
		Console.WriteLine(Name);
	}
}
class Employee : Person
{
	public string Company { get; set; }
	public Employee(string name, string company)
		: base(name)
	{
		Company = company;
	}

	public override void Print()
	{
		Console.WriteLine($"{Name} работает в {Company}");
	}
}
Войдите, чтобы отправить решение
Сложное Ручная проверка Найдите потенциальную проблему в коде урока «Различие переопределения и скрытия методов»
+30 XP

Изучите приведённый фрагмент кода и опишите, при каких входных данных или условиях он может сработать не так, как ожидается (граничный случай, отсутствие проверки и т.п.). Предложите исправленный вариант.

Person tom = new Employee("Tom", "Microsoft");
tom.Print();		// Tom работает в Microsoft
Войдите, чтобы отправить решение
Мини-проект Ручная проверка Мини-проект по теме «Различие переопределения и скрытия методов»
+50 XP

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

Войдите, чтобы отправить решение
Домашнее задание Ручная проверка Домашнее задание по теме «Различие переопределения и скрытия методов»
+25 XP

Напишите собственную небольшую программу, применяющую материал темы «Различие переопределения и скрытия методов». Используйте не менее одной конструкции, показанной в примерах урока. Прикрепите код решения и краткое описание того, что он делает.

Войдите, чтобы отправить решение

Обсуждение (0)

Войдите, чтобы оставить комментарий.