Наследование в C#: концепции, виды и практические примеры
Наследование в C#
Это руководство охватывает основы наследования в C#, его разновидности и практические примеры кода.
Наследование в C# позволяет создать новый класс, производный от существующего, формируя отношения родительский (базовый) и дочерний (производный) классы. Эта мощная возможность ООП способствует повторному использованию кода и логической организации.
Базовый класс предоставляет поля, свойства и методы, которые наследует производный класс, позволяя дочернему расширять или настраивать поведение, сохраняя общую логику в одном месте.
Как объявить наследование в C#
В C# двоеточие (:) указывает на наследование:
class Animal {
// поля и методы
}
// Dog наследует от Animal
class Dog : Animal {
// поля и методы Animal
// поля и методы Dog
}
Здесь Dog расширяет Animal, получая доступ к его членам. Диаграмма ниже иллюстрирует отношение.

Пример: Базовое наследование
using System;
namespace Inheritance {
// Базовый класс
class Animal {
public string name;
public void Display() {
Console.WriteLine("I am an animal");
}
}
// Производный класс
class Dog : Animal {
public void GetName() {
Console.WriteLine("My name is " + name);
}
}
class Program {
static void Main(string[] args) {
Dog labrador = new Dog();
labrador.name = "Rohu";
labrador.Display();
labrador.GetName();
Console.ReadLine();
}
}
}
Вывод
I am an animal My name is Rohu
В примере Dog наследует поле name и метод Display() от Animal. Производный класс также может добавлять свои члены, например GetName().
Отношение «is-a» (является)
Наследование представляет отношение «is-a». Используйте его, когда один класс логически является специализированной формой другого.
- Dog is an Animal
- Apple is a Fruit
- Car is a Vehicle
Эти отношения оправдывают наследование Dog от Animal, Apple от Fruit, Car от Vehicle.
Защищенные члены (protected) в наследовании
Когда поле или метод объявлен protected, он доступен внутри своего класса и во всех производных классах, но скрыт от внешнего кода.
Пример: Использование protected методов
using System;
namespace Inheritance {
class Animal {
protected void Eat() {
Console.WriteLine("I can eat");
}
}
class Dog : Animal {
static void Main(string[] args) {
Dog labrador = new Dog();
labrador.Eat();
Console.ReadLine();
}
}
}
Вывод
I can eat
Так как Eat() защищен, класс Dog может вызвать его, но код вне иерархии — нет.
Виды наследования
Наследование проявляется в нескольких паттернах:
1. Одиночное наследование (Single Inheritance)
Один производный класс наследует от одного базового.

2. Многоуровневое наследование (Multilevel Inheritance)
Цепочка наследования: класс наследует от базового, затем другой класс наследует от этого производного.

3. Иерархическое наследование (Hierarchical Inheritance)
Несколько производных классов разделяют один базовый класс.

4. Множественное наследование (Multiple Inheritance)
C# не поддерживает наследование от нескольких классов, но интерфейсы предоставляют гибкую альтернативу для достижения похожего поведения.

5. Гибридное наследование (Hybrid Inheritance)
Комбинация двух и более видов наследования, например, многоуровневое плюс иерархическое.

Переопределение методов (Method Overriding)
Когда производный класс объявляет метод с той же сигнатурой, что и метод базового класса, помеченный virtual, производный метод может переопределить его с помощью override. Это обеспечивает полиморфное поведение.
using System;
namespace Inheritance {
class Animal {
public virtual void Eat() {
Console.WriteLine("I eat food");
}
}
class Dog : Animal {
public override void Eat() {
Console.WriteLine("I eat dog food");
}
}
class Program {
static void Main(string[] args) {
Dog labrador = new Dog();
labrador.Eat();
}
}
}
Вывод
I eat dog food
Метод Eat() в Dog переопределяет метод в Animal. Ключевое слово virtual разрешает переопределение, а override сигнализирует о замещении.
Использование ключевого слова base
Иногда нужно вызвать реализацию базового класса из переопределяющего метода. Ключевое слово base позволяет это сделать.
Пример: Вызов базовых методов
using System;
namespace Inheritance {
class Animal {
public virtual void Eat() {
Console.WriteLine("Animals eat food.");
}
}
class Dog : Animal {
public override void Eat() {
base.Eat();
Console.WriteLine("Dogs eat dog food.");
}
}
class Program {
static void Main(string[] args) {
Dog labrador = new Dog();
labrador.Eat();
}
}
}
Вывод
Animals eat food. Dogs eat dog food.
Здесь base.Eat() вызывает реализацию Animal перед выполнением логики производного класса.
Почему наследование важно в C#
Наследование позволяет повторно использовать логику между связанными классами. Рассмотрим геометрические фигуры, где расчет периметра использует общую формулу.
- Создайте базовый класс RegularPolygon с методом CalculatePerimeter().
- Произведите Square и Rectangle от него, добавив специфические свойства вроде Length и Sides.
- Каждый производный класс может реализовать свой расчет площади, повторно используя логику периметра.
Иллюстративный пример
using System;
namespace Inheritance {
class RegularPolygon {
public void CalculatePerimeter(int length, int sides) {
int result = length * sides;
Console.WriteLine("Perimeter: " + result);
}
}
class Square : RegularPolygon {
public int Length = 200;
public int Sides = 4;
public void CalculateArea() {
int area = Length * Length;
Console.WriteLine("Area of Square: " + area);
}
}
class Rectangle : RegularPolygon {
public int Length = 100;
public int Breadth = 200;
public int Sides = 4;
public void CalculateArea() {
int area = Length * Breadth;
Console.WriteLine("Area of Rectangle: " + area);
}
}
class Program {
static void Main(string[] args) {
Square s1 = new Square();
s1.CalculateArea();
s1.CalculatePerimeter(s1.Length, s1.Sides);
Rectangle t1 = new Rectangle();
t1.CalculateArea();
t1.CalculatePerimeter(t1.Length, t1.Sides);
}
}
}
Вывод
Area of Square: 40000 Perimeter: 800 Area of Rectangle: 20000 Perimeter: 400
Этот паттерн показывает, как наследование уменьшает дублирование и повышает поддерживаемость.
Язык C
- Классы и объекты в C#: Фундаменты надёжного ООП
- Модификаторы доступа в C#: public, private, protected, internal и другие
- Ключевое слово static в C#: статические переменные, методы и классы
- Абстрактные классы и методы в C#: практическое руководство
- Вложенные классы в C#: определение, использование и наследование
- Частичные классы и методы в C#: понимание и применение
- Sealed-классы и sealed-методы в C#: когда использовать, примеры и повышение безопасности кода
- Полиморфизм в C++: практическое руководство
- Абстракция данных в C++: разделение интерфейса и реализации
- Структура программы на C#: основные компоненты и пример Hello World