Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Questions

.pdf
Скачиваний:
9
Добавлен:
11.03.2016
Размер:
1.14 Mб
Скачать

Закомментируйте операторы == и !=. После этого скомпилируйте и запустите пример еще раз.

Введите одинаковые значения для полей p1.x, p2.x и p1.y, p2.y. Почему p1 != p2 несмотря на то, что p1.x == p2.x и p1.y == p2.y?Потому, что по умолчанию проверка операторами == и !=

проверяет условие указания операндов на один и разные объекты соответственно, а не равности значений их полей.

2. Когда Вы скомпилируете пример, вы увидите, что компилятор выдает предупреждение, которое говорит, что класс Point определяет операторы == и !=, но не переопределяет Object.Equals и Object.GetHashCode. Как Вы думаете, по какой причине это предупреждение, а не ошибка? Дело в том, что метод Equals() должен реализовывать ту же логику, что и оператор ==.

Закомментируйте оператор != в классе Point. Пересоберите приложение и объясните, что происходит и почему это происходит. Компилятор выдает ошибку о том, что оператор ==

переопределен, но требует также переопределить оператор !=.

3. Создайте новое консольное приложение с классом, который перегружает какие-либо операторы.

Постарайтесь придумать класс, полезный другим учащимся. Поделитесь вашей реализацией на форуме.

Пример:

using System;

class Program

{

public static void Main()

{

Random r = new Random();

int a_rows, a_collumns, b_rows, b_collumns;//размерности входных матриц Console.ForegroundColor = ConsoleColor.White;

for(;;)//while(true)

{

Console.WriteLine(

"\nПомните, что количество столбцов первой матрицы\n" + "должно совпадать с количеством строк второй матрицы!\n\n");

try

{

Console.WriteLine("\nВведите количество строк первой матрицы a:"); a_rows = Convert.ToInt32(Console.ReadLine());

Console.WriteLine("\nВведите количество столбцов первой матрицы a:"); a_collumns = Convert.ToInt32(Console.ReadLine());

Console.WriteLine("\nВведите количество строк второй матрицы b:"); b_rows = Convert.ToInt32(Console.ReadLine());

if (a_collumns != b_rows) continue;

Console.WriteLine("\nВведите количество столбцов второй матрицы b:"); b_collumns = Convert.ToInt32(Console.ReadLine());

break;

}

catch

{

Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("\nИспользуйте только цифры!"); Console.ForegroundColor = ConsoleColor.White;

}

}

Matrix a = new Matrix(a_rows, a_collumns);//первая матрица Matrix b = new Matrix(b_rows, b_collumns);//вторая матрица Matrix c = new Matrix(a_rows, b_collumns);//третья матрица

//заполнение данными входных матриц for (int i = 0; i < a_rows; i++)

for (int j = 0; j < a_collumns; j++) a[i,j] = r.Next(100);

for (int i = 0; i < b_rows; i++)

for (int j = 0; j < b_collumns; j++) b[i,j] = r.Next(100);

Console.WriteLine(); a.Show();//отображаем первую матрицу b.Show();//отображаем вторую матрицу

c.Show();//отображаем результирующую матрицу

c = a * b;

Console.WriteLine("После переумножения матриц а и b матрица с:\n"); c.Show();//отображаем результирующую матрицу

}

}

class Matrix

{

int[,] array;//объявление массива (матрицы)

int rows, collumns;//количество строк и столбцов матрицы

public int Rows//количество строк

{

get { return rows; } set

{

if (value > 0) rows = value;

}

}

public int Collumns

{

get { return collumns; } set

{

if (value > 0) collumns = value;

}

}//количество столбцов

public int this[int i, int j]//индексатор

{

get { return array[i, j]; } set { array[i, j] = value; }

}

public Matrix(int countOfRows, int countOfCollumns)

{

Rows = countOfRows;

Collumns = countOfCollumns;

array = new int[Rows, Collumns];//создание массива (матрицы)

}

public void Show()

{

for (int i = 0; i < Rows; i++)

{

for (int j = 0; j < Collumns; j++)

{

Console.Write("{0,6}",array[i, j]);

}

Console.WriteLine();

}

Console.ReadLine();

}

public static Matrix operator *(Matrix a, Matrix b)

{

Matrix multy = new Matrix(a.Rows,b.Collumns); for (int i = 0; i < a.Rows; i++)

for (int k = 0; k < b.collumns; k ++ ) for (int j = 0; j < a.Collumns; j++)

multy[i, k] += a[i, j] * b[j, k]; return multy;

}

}

5.Предопределение методов. Свойства.

1.Что такое переопределение (overriding) методов? Приведите пример с двумя классами (первый класс – базовый, второй от него унаследован).

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

Пример:

class Animal

{

public virtual void Run()

{

return;

}

}

class Tiger: Animal

{

public int i;

public override void Run()

{

base.Method();

}

}

2. В чем ошибка в нижеприведенном коде? Исправьте код и объясните ошибку.

using System;

class SQLServerDb

{

// Bunch of other nonsalient members. public static void RepairDatabase()

{

Console.WriteLine("repairing database..."); Console.ReadLine();

}

}

class StaticMethod1App

{

public static void Main()

{

SQLServerDb classSQL = new SQLServerDb(); classSQL.RepairDatabase();

}

}

Ошибка заключается в вызове статического метода через объектную ссылку. Необходимо либо пометить метод как динамический (убрать из определения метода модификатор static), либо для его вызова использовать имя его класса, а не имя ссылки на объект этого класса.

using System;

class SQLServerDb

{

// Bunch of other nonsalient members. public void RepairDatabase()

{

Console.WriteLine("repairing database..."); Console.ReadLine();

}

public static void Main()

{

SQLServerDb classSQL = new SQLServerDb(); classSQL.RepairDatabase();

}

}

3. Могут ли виртуальные методы быть объявлены защищенными? Какие ключевые слова нужно писать в базовом и производном классе, чтобы реализовать виртуальный вызов?

Privat – не могут, protected - могут. Ключевые слова для реализации виртуального вызова:

сlass, virtual, :, override.

Теперь давайте обсудим вопросы, связанные со свойствами.

5. В каких случаях надо использовать не методы, а свойства?

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

Однако свойства нельзя передавать методам посредством ref и out способом, а также свойства нельзя перегружать.

Что такое свойство только для чтения и свойство только для записи?

Это свойства, в которых определены лишь getили set-аксессоры. Соответственно, такие свойства позволяют либо считывать значение поля, либо устанавливать его.

Что такое функции для доступа (accessor functions)?

Средства доступа представляют собой функции, чьи задачи сводятся к доступу членам

(чаще закрытым) класса и выполнения определенных действий над ними. Get и Set – и есть функции доступа.. Аксессор подобен методу за исключением того, что в нем отсутствует объявление типа возвращаемого значения и параметров. В остальном, синтаксически очень схож с методом.

Какие еще есть способы использования свойств?

Еще свойства можно переопределять с использованием ключевых слов virtual и override.

6. Напишите программу, которая реализует два класса – Invoice и LineItem. Invoice должен содержать общедоступное поле – массив LineItem. Во время исполнения вы должны создать массив

LineItem и присвоить его в поле объекта Invoice. Добавьте в класс Invoice свойство Total, доступное только для чтения. Опубликуйте свое решение в форуме.

Пример: using System;

namespace Invoice

{

class Program

{

static void Main(string[] args)

{

Invoice invoice = new Invoice(); invoice.li = new LineItem[5];

}

}

class Invoice

{

public LineItem[] li; int total;

public int Total

{

get { return total; }

}

}

class LineItem

{

}

}

6. Интерфейсы. Атрибуты.

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

Ну а пока - рассмотрим интерфейсы. Посмотрите на следующий код:

using System;

public interface ITelephone

{

bool offHook

{

get;

}

void PickUpReceiver(); // поднятие трубки void HangUpReceiver(); // опускание трубки void Dial(string n); // набор

}

// POTSPhone implements the ITelephone interface public class POTSPhone : ITelephone

{

//private members holds state about the hook

//status of the receiver and if we're in a

//call or not.

private bool m_offHook; private bool m_activeCall;

//read only property as required by ITelephone

//returns the boolean state of the hook status

//of the receiver.

public bool offHook

{

get { return m_offHook; }

}

//constructor to initialize the POTSPhone public POTSPhone()

{

m_offHook = false; m_activeCall = false;

}

//take the receiver

public void PickUpReceiver()

{

m_offHook = true;

}

//return the phone to on hook and end any

//active calls

public void HangUpReceiver()

{

m_offHook = false; m_activeCall = false;

}

//dial a phone number

//requires that the phone be off hook

//requires that we're not already in an active call public void Dial(string n)

{

if (!this.offHook)

{

Console.WriteLine("Phone must be off-hook before dialing."); return;

}

if (m_activeCall)

{

Console.WriteLine("Already in a call."); return;

}

m_activeCall = true;

Console.WriteLine("Dialing " + n);

}

}

----

using System;

class InterfaceExample

{

static void Main()

{

POTSPhone t = new POTSPhone();

//try dialing before we pick up the receiver t.Dial("555-1212");

//dial according to the interface for a POTS phone t.PickUpReceiver();

t.Dial("555-1212"); t.HangUpReceiver();

}

}

using System;

public class AutoDialer

{

public void Call(string[] numbers, string message, ITelephone phone)

{

foreach (string n in numbers)

{

phone.PickUpReceiver();

phone.Dial(n);

Console.WriteLine("Reading \"" + message + "\" to " + n); phone.HangUpReceiver();

}

}

}

class Telemarketer

{

static void Main()

{

POTSPhone t = new POTSPhone(); CordlessPhone c = new CordlessPhone();

string[] numbers = new string[4];

numbers[0] = "555-1211"; numbers[1] = "555-1212"; numbers[2] = "555-1213"; numbers[3] = "555-1214";

AutoDialer a = new AutoDialer();

a.Call(numbers, "Hello. Am I interrupting dinner?", t); a.Call(numbers, "Hello. Am I interrupting dinner?", c);

}

}

Теперь вопросы к обсуждению.

1. Как Вы можете заметить, здесь отсутствует класс CordlessPhone. Создайте новый класс

CordlessPhone, который реализует интерфейс ITelephone способом совершенно отличным от имплементаци в классе POTSPhone, а затем скомпилируйте программу Telemarketer и проследите как она работает.

Пример:

using System;

using System.Collections.Generic; using System.Text;

namespace Telephone

{

public interface ITelephone

{

bool offHook

{

get;

}

void PickUpReceiver(); // поднятие трубки void HangUpReceiver(); // опускание трубки void Dial(string n); // циферблат

}

// POTSPhone implements the ITelephone interface public class POTSPhone : ITelephone

{

//private members holds state about the hook

//status of the receiver and if we're in a

//call or not.

private bool m_offHook;//Состояние поднятости трубки (поднята, опущена) private bool m_activeCall;//Состояние режима телефона (активный вызов и нет)

//read only property as required by ITelephone

//returns the boolean state of the hook status

//of the receiver.

public bool offHook

{

get { return m_offHook; }

}

//constructor to initialize the POTSPhone public POTSPhone()

{

m_offHook = false; m_activeCall = false;

}

//take the receiver

public void PickUpReceiver()

{

m_offHook = true;

}

//return the phone to on hook and end any

//active calls

public void HangUpReceiver()

{

m_offHook = false; m_activeCall = false;

}

//dial a phone number

//requires that the phone be off hook

//requires that we're not already in an active call public void Dial(string n)

{

if (!this.offHook)

{

Console.WriteLine("Phone must be off-hook before dialing."); return;

}

if (m_activeCall)

{

Console.WriteLine("Already in a call."); return;

}

m_activeCall = true;

Console.WriteLine("Dialing " + n);

}

}

public class CordlessPhone : ITelephone

{

//private members holds state about the hook

//status of the receiver and if we're in a

//call or not.

private bool m_on_off;//Состояние включенности трубки (включена, выключена) private bool m_activeCall;//Состояние режима телефона (активный вызов и нет) private bool m_on_zone;//Факт нахождения трубки в зоне действия станции private bool battary;//Уровень заряда батареи

//read only property as required by ITelephone

//returns the boolean state of the hook status

//of the receiver. public bool offHook

{

get { return m_on_off; }

}

//constructor to initialize the POTSPhone public CordlessPhone()

{

battary = false;//Состояние заряда батареи

m_on_zone = false;//Состояние нахождения в зоне действия станции m_on_off = false;//Состояние трубки (вкл/выкл)

m_activeCall = false;//Состояние активного звонка

}

//take the receiver

public void PickUpReceiver()

{

m_on_off = true;

}

//return the phone to on hook and end any

//active calls

public void HangUpReceiver()

{

m_on_off = false; m_activeCall = false;

}

//Вхождение в зону действия станции public void OnZone()

{

m_on_zone = true;

}

//Процесс заряда батареи public void Charge_Battary()

{

battary = true;

}

//dial a phone number

//requires that the phone be off hook

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]