C#. Примеры создания иерархий классов с использованием наследования




C#. Примеры создания иерархий классов с использованием наследования

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


Содержание


Поиск на других ресурсах:

1. Пример создания иерархии классов. Классы Student, Aspirant

В примере демонстрируется

  • использование модификатора доступа protected при наследовании;
  • использование ключевого слова base в случае вызова конструктора базового класса.
1.1. Условие задачи

Создать базовый класс Student, который будет содержать информацию о студенте (фамилия, курс обучения, номер зачетной книги). С помощью механизма наследование реализовать класс Aspirant (аспирант – студент, который готовится к защите кандидатской диссертации). Класс Aspirant есть производным от класса Student.
В классах Student и Aspirant необходимо реализовать следующие элементы:

  • конструкторы классов с соответствующим количеством параметров. В классе Aspirant для доступа к методам класса Student нужно использовать ключевое слово base;
  • свойства get/set для доступа к полям класса;
  • метод Print(), который выводит информацию о содержимом полей класса.

 

1.2. Решение. Текст программы

Задача решается для приложения типа Console Application. Ниже приведен полный текст программы.

using static System.Console;

namespace ConsoleApp1
{
  // Базовый класс Student, содержит информацию о студенте
  public class Student
  {
    // 1. Поля класса - объявленные как protected - видимы в производных классах,
    // и невидимы из экземпляра класса
    protected string name; // Фамилия и имя студента
    protected int course; // Курс обучения
    protected string gradeBook; // Номер зачетной книги

    // 2. Конструктор класса с 3 параметрами
    public Student(string Name, int course, string gradeBook)
    {
      this.Name = Name;
      this.course = course;
      this.gradeBook = gradeBook;
    }

    // 3. Свойства доступа к полям класса
    public string Name
    {
      get { return name; }
      set { name = value; }
    }

    public int Course
    {
      get { return course; }
      set { course = value; }
    }

    public string GradeBook
    {
      get { return gradeBook; }
      set { gradeBook = value; }
    }

    // 4. Метод Print() - вывести значения полей на экран
    public void Print()
    {
      WriteLine("The values of fields are:");
      WriteLine($"Name = {name}");
      WriteLine($"Course = {course}");
      WriteLine($"GradeBook = {gradeBook}");
    }
  }

  // Класс Aspirant - наследует возможности класса Student
  public class Aspirant : Student
  {
    // 1. Внутреннее поле класса
    protected string topic; // Тема кандидатской диссертации

    // 2. Конструктор класса Aspirant - с помощью ключевого слова base обращается
    // к конструктору базового класса Student
    public Aspirant(string name, int course, string gradeBook, string topic) :
        base(name, course, gradeBook)
    {
      // Можно изменять protected-члены базового класса
      base.name = name; // доступ к полю name класса Student с помощью base
      this.course = course; // доступ к полю course класса Student с помощью this
      this.gradeBook = gradeBook;

      this.topic = topic; // инициализация внутреннего поля класса Aspirant
    }

    // 3. Свойство для доступа к полю topic
    public string Topic
    {
      get { return topic; }
      set { topic = value; }
    }

    // 4. Метод Print() - печать полей класса Aspirant
    // Имя данного метода перекрывает имя метода Student.Print(),
    // поэтому перед именем метода указывается new
    public new void Print() // new - переопределение метода базового класса
    {
      base.Print(); // вызвать метод Print() базового класса
      WriteLine($"Topic = {topic}");
    }
  }

  class Program
  {
    static void Main(string[] args)
    {
      // Демонстрация работы с классами Student и Aspirant

      // 1. Объявить экземпляр класса Student
      Student st1 = new Student("Ivanov I.I.", 2, "0519");

      // 2. Вывести поля класса Student
      WriteLine("The instance of st1:");
      st1.Print();

      // 3. Объявить экземпляр класса Aspirant
      // При объявлении используется свойство get экземпляра st1
      Aspirant asp1 = new Aspirant(st1.Name, st1.Course, st1.GradeBook, "Hello world!");

      // 4. Вызвать метод Print() экземпляра asp1
      WriteLine("---------------------");
      WriteLine("The instance of asp1:");
      asp1.Print();
    }
  }
}

 



1.3. Результат работы программы
The instance of st1:
The values of fields are:
Name = Ivanov I.I.
Course = 2
GradeBook = 0519
---------------------
The instance of asp1:
The values of fields are:
Name = Ivanov I.I.
Course = 2
GradeBook = 0519
Topic = Hello world!

 

2. Реализация наследования на примере класса Book

2.1. Условие задачи

Задан класс Book, который описывает книгу. Класс содержит следующие элементы:

  • название книги;
  • фамилия и имя автора;
  • стоимость книги.

В классе Book нужно реализовать следующие методы:

  • конструктор с 3 параметрами;
  • свойства get/set для доступа к полям класса;
  • метод Print(), который выводит информацию о книге.

Разработать класс BookGenre, который наследует возможности класса Book и добавляет поле жанра (genre). В классе BookGenre реализовать следующие элементы:

  • конструктор с 4 параметрами – реализует вызов конструктора базового класса;
  • свойство get/set доступа к внутреннему полю класса;
  • метод Print(), который обращается к методу Print() базового класса Book для вывода информации о всех полях класса.

Разработать класс BookGenrePubl, который унаследован от класса BookGenre. Данный класс добавляет поле, которое содержит информацию об издателе. В классе BookGenrePubl реализовать следующие элементы:

  • конструктор с 5 параметрами;
  • свойство get/set для доступа к внутреннему полю класса;
  • метод Print(), который вызывает одноименный метод базового класса и выводит на экран информацию об издателе.

Класс BookGenrePubl сделать таким, что не может быть унаследован.

 

2.2. Решение. Текст программы
using static System.Console;

namespace ConsoleApp1
{
  // Класс Book - базовый класс
  class Book
  {
    // 1. Внутренние поля класса
    string title; // название (заголовок) книги
    string author; // фамилия и имя автора
    double price; // стоимость книги

    // 2. Конструктор с 3 параметрами
    public Book(string _title, string _author, double _price)
    {
      title = _title;
      author = _author;

      // корректировка стоимости книги
      if (price < 0) price = 0.0;
      else price = _price;
    }

    // 3. Свойства типа get/set для доступа к полям класса
    public string Title
    {
      get { return title; }
      set { title = value; }
    }

    public string Author
    {
      get { return author; }
      set { author = value; }
    }

    public double Price
    {
      get { return price; }
      set
      {
        if (price < 0) price = 0.0;
        else price = value;
      }
    }

    // 4. Метод Print() - вывести поля класса
    public void Print()
    {
      WriteLine("title = {0}, author = {1}, price = {2:f2}", title, author, price);
    }
  }

  // Класс, который наследует класс Book - добавляет жанр к книге.
  class BookGenre : Book
  {
    // 1. Внутреннее поле - жанр, к которому относится книга
    string genre;

    // 2. Конструктор с 4 параметрами.
    // Вызывает конструктор базового класса с помощью base(...).
    public BookGenre(string _title, string _author, double _price, string _genre) :
    base(_title, _author, _price)
    {
      genre = _genre;
    }

    // 3. Свойство доступа к полю genre
    public string Genre
    {
      get { return genre; }
      set { genre = value; }
    }

    // 4. Метод Print() - вызывает метод базового класса
    // В заголовке метода используется ключевое слово new. Это
    // есть рекомендация компилятора - подчеркнуть, что данный метод
    // прячет одноименный метод базового класса.
    public new void Print()
    {
      base.Print(); // вызвать метод Print() базового класса Book
      WriteLine("genre = {0}", genre);
    }
  }

  // Класс, который наследует класс BookGenre - добавляет к иерархии классов
  // поле издателя.
  // Перед классом используется ключевое слово sealed - это означает,
  // что данный класс не может быть унаследован другими классами.
  sealed class BookGenrePubl : BookGenre
  {
    // 1. Внутреннее поле - информация об издателе
    private string publisher;

    // 2. Конструктор с 5 параметрами - Вызывает конструктор базового
    // класса BookGenre() с помощью ключевого слова base.
    public BookGenrePubl(string _title, string _author, double _price,
        string _genre, string _publisher) : base(_title, _author, _price, _genre)
    {
      publisher = _publisher;
    }

    // 3. Свойство доступа к полю publisher
    public string Publisher
    {
      get { return publisher; }
      set { publisher = value; }
    }

    // 4. Метод Print() - вызывает метод базового класса.
    // В объявлении метода рекомендуется использовать
    // ключевое слово new, так как данный метод "прячет" метод базового класса.
    public new void Print()
    {
      base.Print();
      WriteLine("publisher = {0}", publisher);
    }
  }

  class Program
  {
    static void Main(string[] args)
    {
      // 1. Объявить экземпляр класса Book
      Book b1 = new Book("Title - 01", "Author - 01", 122.25);

      // 2. Вывести значения полей класса экземпляра b1
      b1.Print();

      // 3. Объявить экземпляр класса BookGenre
      BookGenre bg1 = new BookGenre("Title - BookGenre", "Author - BookGenre", 200.33, "Story");

      // 4. Вывести значения полей экземпляра bg1
      WriteLine("-------------------");
      bg1.Print();

      // 5. Объявить экземпляр класса BookGenrePubl
      BookGenrePubl bp1 = new BookGenrePubl("Title - BookGenrePubl", "Aurhor - BookGenrePubl",
          300.55, "Story", "Pupkin Inc.");

      // 6. Вывести значения полей экземпляра bp1
      WriteLine("-------------------");
      bp1.Print();
    }
  }
}

 

2.3. Результат работы программы
title = Title - 01, author = Author - 01, price = 122.25
-------------------
title = Title - BookGenre, author = Author - BookGenre, price = 200.33
genre = Story
-------------------
title = Title - BookGenrePubl, author = Aurhor - BookGenrePubl, price = 300.55
genre = Story
publisher = Pupkin Inc.

 


Связанные темы