Лабораторная работа № 1.




Постройте создайте проект, в котором содержатся (рис.1):

1. Абстрактный класс с именем HotDrink, у которого имеются

- методы типа stringDrink() (выпить), AddMilk() (добавить молоко), AddSugar() (добавить сахар);

- защищенные поля sugar, milk (значения по умолчанию);

- свойства для этих полейMilk и Sugar.

2. Интерфейс с именем ICup, у которого имеются

- методы Refill() (наполнить повторно), Wash() (вымыть),

- свойства Type (тип) и Capacity (Объем).

3. Класс с именем CupOfCoffee, который является наследником класса HotDrink, поддерживает интерфейс ICup и обладает дополнительным свойством BeanType (тип зерен).

4. Класс с именем CupOfTea, который является производным от класса HotDrink, поддерживает интерфейс ICup и обладает дополнительным свойством LeafType (тип чая).

5. Класс с функцией Main(), а также с функциейProcessCup, которая получает в качестве параметра объект одного из классов CupOfCoffee или CupOfTea, по выбору пользователя (чай или кофе). Далее функция должна вызывать все методы и свойстваабстрактного класса и интерфейса для любого объекта, переданного ей в качестве параметра (т.е. в качестве формального параметра используется абстрактный тип).

Запускаем Visual Studio и создаем консольное приложение(.Net Framework):

Добавляем класс HotDrink(правый клик по проекту -> Добавить -> Создать элемент…). Это будет наш абстрактный класс.

 

 

Код класса HotDrink:

abstract class HotDrink

{

protected int sugar = 3;

public int Sugar

{

get { return sugar; }

set

{

if (value < 0) sugar = 0;

if (value > 10) sugar = 10;

if (value >= 0 && value <= 10) sugar = value;

}

}

 

protected int milk = 3;

public int Milk

{

get { return milk; }

set

{

if (value < 0) milk = 0;

if (value > 5) milk = 5;

if (value >= 0 && value <= 5) milk = value;

}

}

 

public abstract void Drink();

 

public void AddMilk(int milk)

{

Milk += milk;

}

 

public void AddSugar(int sugar)

{

Sugar += sugar;

}

}

 

Зачем нужны абстрактные классы? Допустим, в нашей программе требуется определить две основных сущности: чашка чая и чашка кофе. Каждая из этих сущностей будет отличаться, например, для кофе надо определить тип зерен, а для чая - тип чая. Т. е. будут созданы отдельные классы CupOfCoffee и CupOfTea. В то же время обе этих сущности могут иметь что-то общее, например, объем добавленного молока и количество кубиков сахара, какую-то другую общую функциональность. И эту общую функциональность лучше вынести в какой-то отдельный класс, например, HotDrink, который описывает некоторый горячий напиток. То есть классы CupOfCoffee и CupOfTea будут производными от класса HotDrink. И так как все объекты в нашей системе будут представлять либо чай, либо кофе, то напрямую экземпляры объекта HotDrink создаваться не будут. Поэтому имеет смысл сделать его абстрактным. Стоит отметить, что метод Drink() в классе HotDrink помечен ключевым словом abstract. Это значит, что во всех классах наследниках потребуется описать свою реализацию метода Drink(). Пример будет приведен ниже в классах CupOfCoffee и CupOfTea. В классе HotDrink также Определены методы AddSugar(), AddMilk() и свойства Milk и Sugar. Свойства обеспечивают простой доступ к полям классов и структур, позволяют узнать их значение или выполнить их установку.

 

Добавляем в проект интерфейс ICup со следующим кодом(правый клик по проекту -> Добавить -> Создать элемент…):

interface ICup

{

void Refill();

void Wash();

 

string Type { get; set; }

double Capacity { get; set; }

}

Интерфейс ICup определяет некоторый функционал - набор методов и свойств без реализации. Этот функционал реализуют классы и структуры, в нашем случае CupOfCoffee и CupOfTea.

Добавляем класс CupOfTea:

class CupOfTea: HotDrink, ICup

{

protected string leafType = "черный";

public string LeafType

{

get { return leafType; }

set

{

if (value.Equals("зеленый"))

leafType = value;

}

}

 

protected string type = "пластик";

public string Type

{

get { return type; }

set

{

if (value == "стекло")

type = value;

}

}

protected double capacity = 0.2;

public double Capacity

{

get { return capacity; }

set

{

if (value <= 0.2) capacity = 0.2;

if (value > 0.2) capacity = 0.3;

}

}

 

public override void Drink()

{

Console.WriteLine("Какой вкусный чай!");

}

 

public void Refill()

{

Console.WriteLine("Повторить чай {4} объемом {0}\n" +

"Молоко: {1}\n" +

"Сахар: {2}\n" +

"Тип стакана: {3}\n", Capacity, Milk, Sugar, Type, leafType);

}

 

public void Wash()

{

Console.WriteLine("Вымыть {0} чашку с чаем\n", Type);

}

}

В классе CupOfTea мы добавили свойство «тип зерна» LeafType и соответствующее защищенное поле leafType. leafType с модификатором доступа protected будут иметь доступ все классы наследники от класса CupOfTea (возможно в будущем потребуется добавить еще несколько типов чая). В классе CupOfTea переопределен метод Drink():

public override void Drink(){ Console.WriteLine("Какой вкусный чай!"); }

 

Если динамическим типом объекта будет CupOfTea, то будет вызвана версия из данного класса(CupOfTea). Например

HotDrink c = new CupOfTea();

c.Drink();// будет вызвана версия CupOfTea(динамический тип переменной с – CupOfTea, статический - HotDrink)

c = new CupOfCoffee();

c.Drink();// будет вызвана версия CupOfCoffee(динамический тип переменной с – CupOfCoffee, статический – HotDrink)

 

Добавляем класс CupOfCoffee со следующим кодом(весь код аналогичен предыдущему):

class CupOfCoffee: HotDrink, ICup

{

protected string beanType = "арабика";

public string BeanType

{

get { return beanType; }

set

{

if (value.Equals("робуса"))

beanType = value;

}

}

 

protected string type = "пластик";

public string Type { get { return type; }

set {

if (value is string)

if (value == "стекло")

type = value;

}

}

 

protected double capacity = 0.2;

public double Capacity { get { return capacity; }

set {

if (value <= 0.2) capacity = 0.2;

if (value > 0.2) capacity = 0.3;

}

}

 

public override void Drink()

{

Console.WriteLine("Какое вкусное кофе!");

}

 

public void Refill()

{

Console.WriteLine("Повторить кофе {4} объемом {0}\n" +

"Молоко: {1}\n" +

"Сахар: {2}\n" +

"Тип стакана: {3}\n", Capacity, Milk, Sugar, Type, BeanType);

}

 

public void Wash()

{

Console.WriteLine("Вымыть {0} чашку с кофе\n", Type);

}

}

 

Используем приведенные выше классы для создания требуемого напитка(в классе Program)

class Program

{

static void Main(string[] args)

{

Console.WriteLine("Выберите напиток: кофе <1> или чай <2>: ");

switch (int.Parse(Console.ReadLine()))

{

case 1:

ProcessCup(new CupOfCoffee());

break;

case 2:

ProcessCup(new CupOfTea());

break;

default:

Console.WriteLine("Такого нет");

break;

}

Console.ReadLine();

}

 

static void ProcessCup(CupOfCoffee cup)

{

Console.WriteLine("Тип зерна: арабика или робуса <по умолчанию арабика>;\n" +

"Сахар: 0...10 <по умолчанию 2>;\n" +

"Молоко: 0...5 <по умолчанию 2>;\n" +

"Тип стакана: пластик или стекло <по умолчанию пластик>;\n" +

"Объем 0,2 или 0,3 <по умолчанию 0,2>;\n");

 

 

Console.WriteLine("Тип зерна: ");

cup.BeanType = Console.ReadLine();

Console.WriteLine("Молоко: ");

cup.Milk = int.Parse(Console.ReadLine());

Console.WriteLine("Сахар: ");

cup.Sugar = int.Parse(Console.ReadLine());

Console.WriteLine("Тип стакана: ");

cup.Type = Console.ReadLine();

Console.WriteLine("Объем <мл>: ");

cup.Capacity = double.Parse(Console.ReadLine());

 

Console.WriteLine("--------------\n" +

"В кофе добавлен сахар: {0}\n" +

"В кофе добавлено молоко: {1}\n" +

"Получите кофе: {2}\n", cup.Sugar, cup.Milk, cup.BeanType);

 

cup.Drink();

cup.Wash();

cup.Refill();

}

 

static void ProcessCup(CupOfTea cup)

{

Console.WriteLine("Тип чая: зеленый или черный <по умолчанию черный>;\n" +

"Сахар: 0...10 <по умолчанию 2>\n" +

"Молоко: 0...5 <по умолчанию 2>\n" +

"Тип стакана: пластик или стекло <по умолчанию пластик>\n" +

"Объем 0,2 или 0,3 <по умолчанию 0,2>\n");

 

Console.WriteLine("Тип чая: ");

cup.LeafType = Console.ReadLine();

Console.WriteLine("Молоко: ");

cup.Milk = int.Parse(Console.ReadLine());

Console.WriteLine("Сахар: ");

cup.Sugar = int.Parse(Console.ReadLine());

Console.WriteLine("Тип стакана: ");

cup.Type = Console.ReadLine();

Console.WriteLine("Объем <мл>: ");

cup.Capacity = double.Parse(Console.ReadLine());

 

Console.WriteLine("--------------\n" +

"В чай добавлен сахар: {0}\n" +

"В чай добавлено молоко: {1}\n" +

"Получите чай: {2}\n", cup.Sugar, cup.Milk, cup.LeafType);

 

cup.Drink();

cup.Wash();

cup.Refill();

}

}

УПРАЖНЕНИЕ

Мы написали версию программы с двумя методами ProccessCup. Один из них принимает в качестве аргумента класс CupOfTea, а другой принимает в качестве аргумента класс CupOfCoffee. Требуется объединить приведенные выше две версии метода ProccessCup в одну. Подсказка: метод ProccessCup в качестве аргумента должен принимать HotDrink и внутри можно использовать конструкции RTTI из С#, например операторы is и as.



Поделиться:




Поиск по сайту

©2015-2024 poisk-ru.ru
Все права принадлежать их авторам. Данный сайт не претендует на авторства, а предоставляет бесплатное использование.
Дата создания страницы: 2021-06-09 Нарушение авторских прав и Нарушение персональных данных


Поиск по сайту: