Автор работы: Пользователь скрыл имя, 25 Мая 2012 в 23:51, контрольная работа
Проще всего понять, как создается класс, на примере. Создадим простой класс по имени Authenticator. Предположим, что мы разрабатываем большое приложение, которое требует, чтобы в определенное время пользователь зарегистрировался (вошел) в программе, указав пароль. Класс Authenticator будет заниматься этим аспектом программы.
Проще всего понять, как создается класс, на примере. Создадим простой класс по имени Authenticator. Предположим, что мы разрабатываем большое приложение, которое требует, чтобы в определенное время пользователь зарегистрировался (вошел) в программе, указав пароль. Класс Authenticator будет заниматься этим аспектом программы. Разумеется, нам не нужно беспокоиться об остальной части приложения — мы сконцентрируемся на построении этого класса. Напишем также небольшой тестовый код, который проверит, что класс Authenticator работает должным образом.
Authenticator позволяет выполнить две вещи: установить новый пароль и проверить, что пароль правильный. Код С#, необходимый для определения класса, выглядит следующим образом:
public class Authenticator{
private string Password;
public bool IsPasswordCorrect(string password){
return (password == Password) ? true : false;
}
public bool ChangePassword(string oldPassword, string NewPassword){
if (oldPassword == Password){
Password = newPassword; return true;
}
else
return false;
}
}
По используемому здесь синтаксису вы можете понять, что происходит. Ключевое слово class в С# показывает, что мы собираемся определить новый класс (тип объекта). Слово, следующее за class, является именем, которое мы хотим дать классу. Затем в фигурных скобках идет собственно определение объекта. Обычно оно состоит из некоторого числа переменных (полей) и методов, в нашем случае — из одного поля и двух методов.
Повсеместность классов
иллюстрируется тем фактом, что
в данном примере мы
Единственное поле в Authenticator, Password, хранит текущий пароль. Оно отмечено ключевым словом private. Это означает, что поле невидимо за пределами класса — компилятор и платформа .NET не позволят никакому коду получить доступ к этому полю, кроме кода, который сам является частью класса Authenticator. Определение поля или метода как private гарантирует, что это поле или метод будет частью внутренней структуры класса, в отличие от внешнего интерфейса. Преимущество здесь в том, что если вы решите изменить внутреннюю логику (возможно, вы захотите использовать для хранения Password не строку, а некоторый другой, более специализированный тип данных), то сможете сделать это, будучи уверены в том, что изменение не испортит и не затронет никакой другой код вне определения класса Authenticator. Это происходит потому, что никакой иной код не может получить доступ к этому полю данных.
Отметим, что в данном
примере мы воспользовались
Любой код, использующий класс Authenticator, может получить доступ только к методам, отмеченным ключевым словом public, т.е. в нашем случае к методам IsPasswordCorrect() и ChangePassword(). Оба метода реализованы таким образом, что ничего не происходит (кроме возврата true или false), если код не передает корректный текущий пароль — это и обязано делать программное обеспечение, реализующее безопасность. Обе функции имеют доступ к полю Password, что допустимо, поскольку этот код является частью самого класса Authenticator. Отметим, что эти открытые функции одновременно предоставляют интерфейс для внешнего мира (другими словами, для остального кода, использующего класс Authenticator) и определяют, какие действия класса Authenticator видны внешнему миру.
Private и public не единственные модификаторы, которые доступны для определения того, что может знать код о существовании члена. Ниже в этой статье мы используем protected, который делает члена доступным в данном классе и в некоторых связанных классах, а в других статьях познакомимся с internal и protected internal, запрещающими доступ со стороны другого кода внутри одной сборки.
Итак, мы объявили класс Authenticator. Как можно использовать его в коде? Чтобы понять это, предположим, что класс является новым типом переменной. Вы уже применяли предопределенные типы переменных. В С# это int, float, double и т.п. Определяя класс Authenticator, мы говорим компилятору, что существует новый тип переменной, называемый Authenticator. Под этим подразумевается, что мы создаем новый, более сложный тип переменной, которая состоит из соединенных вместе других переменных (полей класса), и говорим компилятору, что может делать этот новый тип переменной (методы).
Определение класса
содержит все, что требуется
знать компилятору для
Мы определили класс как новый тип переменной, однако более общим термином является тип данных или просто тип.
Если Authenticator является еще одним типом переменной, то его можно использовать в коде следующим образом:
Authenticator Simon = new Authenticator();
bool Done;
Done = Simon.ChangePassword(”", “MyNewPassword”);
if (Done == true)
Console.WriteLine(”Password for Simon changed”);
else
Console.WriteLine(”Failed to change password for Simon”);
Done = Simon.ChangePassword(”", “AnotherPassword”);
if (Done == true)
Console.WriteLine(”Password for Simon changed”);
else
Console.WriteLine(”failed to change password for Simon”);
if (Simon.isPasswordCorrect(”
Console.WriteLine(”Verified Simon\’s password”);
else
Console.WriteLine(”Failed to verify Simon\’s password”);
Другими словами, мы определяем переменную типа Authenticator и используем ее подобно другим переменным, указывая точку (.), сообщающую о том, что вызывается метод класса.
Этот код демонстрирует
различие между классом и
В большинстве случаев
необходимо создавать
Часть строки “= new Authenticator () “, в которой мы определяем переменную, предназначена для выделения памяти под Authenticator. В С# переменная, типом которой является определенный вами класс, на самом деле содержит только ссылку на то место, где в памяти хранятся данные для этой переменной. Память сама по себе должна распределяться отдельно, что и делается с помощью ключевого слова new.
Программисты на С++ могут сравнить это с хранением указателя на объект. Для программистов на Java это то же самое, что и ссылка Java. Программисты на VB могут сопоставить это с хранением ссылки на объекты ActiveX. В данном контексте ключевое слово new в С# делает практически то же самое, что и в С++, а это в свою очередь похоже на то, что делает new в VB6.
Как упоминалось выше,
вызов методов класса
string SimonsPassword = Simon.Password;
Этот код вызовет ошибку на этапе компиляции по причине того, что поле Password явно отмечено как private, поэтому другой код не может получить доступ к нему. Нельзя делать и так:
Authenticator Simon = new Authenticator();
Authenticator Karli = new Authenticator();
Authenticator Result = Simon + Karli;// Неверно!
Первые две строки кода будут восприняты нормально, но третья строка вызовет ошибку компиляции, поскольку компилятор не знает, как складывать объекты Authenticator. Компилятору не известно, что делать с таким выражением. Это не слишком важно для Authenticator, так как для этого класса сложение не имеет какого-либо видимого смысла. Однако в коде вы можете определить классы, для которых операции сложения и умножения будут уместны (например, можно написать класс, представляющий денежную сумму или математическую матрицу). В следующей статье мы рассмотрим перегрузку операций и покажем, как можно сообщить компилятору, что означают математические действия для класса, который был определен, так что можно будет написать код, который складывает, вычитает, умножает, делит или выполняет другие операции с классами.
Для завершения примера
приведем код программы,
using System;
namespace Wrox.ProfessionalCSharp.
class ProgramEntryPoint{
static void Main(string[] args) {
Authenticator Simon = new Authenticator();
bool Done;
Done = Simon.ChangePassword(”", “MyNewPassword”);
if (Done == true)
Console.WriteLine(”Password for Simon changed”);
else
Console.WriteLine(”Failed to change password for Simon”);
Done = Simon.ChangePassword(”", “AnotherPassword”);
if (Done == true)
Console.WriteLine(”Password for Simon changed”);
else
Console.WriteLine(”Failed to change password for Simon”);
if (Simon.IsPasswordCorrect(”
Console.WriteLine(”Verified Simon\’s password “);
else
Console.WriteLine(”Failed to verify Simon\’s password”);
}
}
public class Authenticator {
private string Password;
public bool IsPasswordCorrect(string password) {
return (password == Password) ? true : false;
}
public bool ChangePassword(string oldPassword, string NewPassword) {
if (oldPassword == Password) {
Password = newPassword;
return true;
}
else
return false;
}
}
}
Выполнение этой программы дает результат, который, если проследить по логике программы, соотносится с ожидаемым при условии, что Simon имеет в качестве первоначального пароля пустую строку символов.
Отметим несколько
моментов. Во-первых, в этом примере
нет ничего нового, все это
уже рассматривалось нами
Во-вторых, в примере класс Authenticator используется внутри одного исходного файла. Часто требуется писать классы, применяемые в других проектах, над которыми работаете вы или ваши коллеги. В этом случае необходимо писать класс точно так же, как в приведенном примере, но компилировать его в библиотеку.
В-третьих, в коде
существует второй класс,