Три «кита» ООП. Пример 2

В предыдущем примере были созданы три класса, определяющих три варианта описания одной семьи.

Создание популяции (класс Population) на базе первого класса

Объекты-популяции должны содержать информацию об n семьях (n=0, 1, 2, … ). Кроме того, необходимо предусмотреть различные способы заполнения массива и вывода данных.
Пусть метод Main() в Program.cs будет задан так:

static void Main()
{
   // Два варианта для ввода данных через конструктор для объекта P
      // 1. С клавиатуры 
   Population P = new Population(1);
   Console.Write("Задайте имя ребенка для поиска или укажите 'все': ");
   string name = Console.ReadLine();
   P.OutputResult(name);
      // 2. Из файла
   P = new Population(2);
   Console.Write("Задайте имя ребенка для поиска или укажите 'все': ");
   name = Console.ReadLine();
   P.OutputResult(name);

   Console.ReadKey();
}

Отметим, что конструктор класса Population имеет один параметр — целое число, которое будет задавать тип ввода данных о популяции. То есть, мы можем выбирать, какой способ ввода данных нам удобнее.

Вывод данных (метод OutputResult(string name)) также будет зависеть от параметра name типа string, который также позволяет управлять способом вывода результата.

Класс MFC возьмем из предыдущего примера, поместим его в файл Class2.cs :

using System;
namespace МатьОтецРебенок
{
   // Инкапсуляция в классе MFC
   public class MFC
   {
      protected string mother;
      protected string father;
      protected string child;
      public MFC(string m, string f, string c)
      {
         mother = m;
         father = f;
         child = c;
      }
      // возврат имени ребенка
      public virtual string GetChild()
      {
         return child;
      }
      // вывод имен членов семьи
      public virtual void Output()
      {
         Console.WriteLine("Mать: " + mother + "  отец: " + father + "  ребенок: " + child);
      }
   }
}

Пусть структура текстового файла будет иметь следующий вид:

2
Полина Прасковья Павел
Кузьма Климентина Казимир

где в первой строке указывается количество семей, в последующих — через один пробел — имена ребенка, матери и отца.

И, наконец, текст класса Population (комментарии — в тексте):

using System;
using System.IO;
using System.Text;
namespace МатьОтецРебенок
{
// Класс Популяция
class Population
{
   protected int n; // число семей в популяции
   protected MFC [] M; // имена членов всех семей

   // Это конструктор с параметром int N.
   // Ввод данных: 1 - с клавиатуры, 2 - из файла.
   public Population(int K)
   {
      switch (K)
      {
      case 1:
        Console.Write("Задайте количество семей: ");
        n = Convert.ToInt32(Console.ReadLine());
        M = new MFC[n];
        string m1, f1, c1;
        for (int i = 0; i < n; i++)
        {
           Console.WriteLine("Члены семьи {0}: ", i + 1);
           Console.Write("Ребенок: ");
           c1 = Console.ReadLine();
           Console.Write("Мать: ");
           m1 = Console.ReadLine();
           Console.Write("Отец : ");
           f1 = Console.ReadLine();
           M[i] = new MFC(m1, f1, c1);
       }
       break;
    case 2:
       Console.Write("Задайте имя текстового файла данных без расширения: ");
       string file_name = Console.ReadLine() + ".txt";
       StreamReader sr; // поток для чтения
       try
       {
          // Чтение из файла
          // связывание с файлом, кодировка символов Юникода
          sr = new StreamReader(file_name, UTF8Encoding.Default);
          string t = sr.ReadLine(); // чтение 0-й строки
          n = Convert.ToInt32(t);
          M = new MFC[n];
          string m2, f2, c2;
          int k = -1;
          int i = 0; // счетчик строк
          while ((t != null) && (i < n)) // Чтение из файла
          {
             t = sr.ReadLine(); // чтение строк
             // разбор строки
             k = t.IndexOf(" ");
             c2 = t.Substring(0, k);
             t = t.Remove(0, k + 1);
             k = t.IndexOf(" ");
             m2 = t.Substring(0, k);
             f2 = t.Remove(0, k + 1);
             M[i] = new MFC(m2, f2, c2);
             i++;
          }
          sr.Close(); // закрытие файла "info.txt" для чтения
       }
       catch (Exception ex)
       {
       Console.WriteLine("ОШИБКА: " + ex.Message);
       }
       break;
    default:
       Console.WriteLine("Данный вариант ввода не предусмотрен!");
       break;
    }
 }
 // Вывод результата
 public void OutputResult(string name)
 {
    if (n == 0)
    Console.WriteLine("База данных пуста!");
    else
    {
       if (name == "все")
       {
           for (int i = 0; i < n; i++)
           M[i].Output();
       }
       else // только для ребенка с заданным именем name
       {
          bool b = false;
          for (int i = 0; i < n; i++)
             if (M[i].GetChild().Equals(name))
             {
                b = true;
                M[i].Output();
             }
          if (!b)
             Console.WriteLine("Ребенка с именем '" + name + "' нет в базе данных");
       }
     }
   }
 }
}

Небольшие комментарии к тексту модуля:

1. Конструкторы как и любые перегружаемые методы различаются количеством и/или типом параметров. При вызове конструктора Population(int K) Вы можете выбрать любой из допустимых вариантов. Даже если Вы укажете K, не равное 1 или 2, объект будет создан с помощью конструктора по умолчанию, причем поле n будет равен 0 (пустая база).
2. Метод OutputResult( ) написан по такому же признаку: если база данных пуста, то выводится соответствующее сообщение. Если name = все, то выводится полная информация о семьях, иначе производится поиск семьи, имя ребенка которой, равно name.
3. Метод GetChild() используется для сравнения параметра name с именем поля child в массиве M[]. Напрямую поле нельзя использовать, так как оно объявлено как protected.

Развитие класса Population рассмотрим в следующей статье.
Использование структуры вместо класса рассмотрим в статье «Структура ИЛИ класс. Пример 1».

Оставьте комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Пролистать наверх