С# и ООП Формальное определение класса с C# Класс в C# - это пользовательский тип данных (user defined type), который состоит из данных (часто называемых атрибутами и свойствами) и функциями для выполнения с этими данными различных действий (эти функции обычно называются методами). class Employee { private string fullName; private int empID; private float currPay; } public Employee() {} public Employee (string fullName, int empID, float currPay) { ○ this. fullName = fullName; ○ this.empID = empID; ○ this. currPay = currPay: } public void GiveBonus (float amount) { ○ currPay += amount; } public virtual void DisplayStats() { ○ Console. WriteLine ("Name: {0}", fullName); ○ Console.WriteLine (“Pay: {0}”, currPay); ○ Console.WriteLine (“ID: {0}“, empID); ○ Console.WriteLine (“SSN: {0}". ssn); } // Вызываем конструктор по умолчанию Employee e = new Employee(): // Вызываем пользовательский конструктор public static void Main() { Employee e = new Employee (“Joe”, 80, 30000); e.GiveBonus (200); Employee e2; e2 = new Employee ("Beth“, 81, 50000); e2.GiveBonus (1000); e2.DisplayStats(), } Ссылки на самого себя В определениях пользовательских конструкторов часто используется зарезервированное слово this public Employee (string fullName, int empID, float currPay) { tnis.fullName = fullName; this.enpID = empID; this.currPay = currPay; } Перенаправление вызовов конструктора с использованием слова this class Employee { public Employee (string fullName, int empID, float currPay) { this.fullName = fullName; this.empID = empID; this.currPay = currPay; } public Employee (string fullName) :this(fullName, IDGenerator.GetNewEmpID(), O.OF) {} } Определение открытого интерфейса по умолчанию Открытый интерфейс по умолчанию для класса – это набор открытых членов данного класса. это набор тех переменных, свойств и методов-членов, к которым можно обратиться в формате имя_объекта.член_класса (с точки зрения обращения к членам класса). это набор тех членов класса, которые объявлены с использованием ключевого слова public (с точки зрения определения класса). В C# открытый интерфейс по умолчанию для класса может состоять из следующих членов этого класса: • Методов • Свойств • Полей // Теперь этот класс можно создавать из-за пределов сборки, в которой он определен public class HelloClass { // Любое количество методов с любым количеством параметров // Конструктор по умолчанию и пользовательские конструкторы // Если в этом классе определена и точка входа для всей программы, // то еще и статический метод Main () } // Внутренние классы могут использоваться только внутри той сборки, в которой они определены internal class HelloClassHelper { } Важнейшие «столпы» объектно-ориентированного программирования • инкапсуляция • наследование • полиморфизм Инкапсуляция // Класс DBReader скрывает за счет инкапсуляции подробности открытия // и закрытия баз данных DBReader f = new DBReader(); f.Open ("C:\foo.mdf"); // выполняем с базой данных нужные нам действия f.Close(); Для обращения к внутренним данным можно использовать один из двух способов: • создать традиционную пару методов — один для получения информации (accessor), второй — для внесения изменений (mutator); • определить именованное свойство. Реализация инкапсуляции при помощи традиционных методов доступа и изменения // Определение традицонных методов доступа и изменения //для закрытой переменной public class Employee { private string fullName; // Метод доступа public string GetFullName() {return fullName; } // Метод изменения public void SetFullName (string n). { // Логика для удаления неположенных символов (!, @, #, $, % и прочих // Логика для проверки максимальной длины и прочего full Name = n; } } Второй способ инкапсуляции: применение свойств класса Помимо традиционных методов доступа и изменения для обращения к закрытым членам класса можно также использовать свойства (properties). // Обращение к имени сотрудника через свойство public static int Main(string[] args) { Employee p = new Employee(); // Устанавливаем значение p.EmpID = 81; // Получаем значение Console.WriteLine(“Person ID Is: {0}”, p.EmpID); return 0; } Синтаксис класса Employee с определением свойства EmpID: // Пользовательское свойство EmpID для доступа к переменной empID public class Employee { private Int empID; // Свойство для empID public Int EmpID { get {return empID;} set { // Здесь вы можете реализовать логику для проверки вводимых // значений и выполнения других действий empID = value; } } } Внутреннее представление свойств С# Многие программисты стараются использовать для имен методов доступа и изменения соответственно приставки get_ и set_(например, get_Name() и set_Name()). С# для внутреннего представления свойства использует методы с теми же самыми префиксами. Если вы откроете сборку EmpLoyees.exe при помощи утилиты ILDastn.exe, вы увидите, что каждому свойству соответствуют два отдельных метода. Поэтому подобное определение класса вызовет ошибку компилятора: // Помните, что свойство С# автоматически отображается в пару методов get/set public class Employee { // Определение свойства public string SSN { get { return ssn;} // Отображается в get_SSN() set { ssn = value;} // Отображается в set_SSN() } // Ошибка! Эти методы уже определены через свойство SSN! public string get_SSN() { return ssn; } public string set_SSN (string val) { ssn = val; } } Свойства только для чтения, только для записи public class Employee { // Будем считать, что исходное значение этой переменной присваивается // с помощью конструктора класса private string ssn; // А вот так выглядит свойство только для чтения public string SSN ( get { return ssn; } } Статические свойства // Со статическими данными должны работать статические свойства public class Employee { private static string CompName; // Статическая переменная public static string Company // Статическое свойство { get { return CompName; } set { CompName = value; } } } Обращение к статическим свойствам производится так же, как и к статическим методам; // Задаем и получаем информацию об имени компании public static int Main(string[] args) { Employee. Company = "Intertech, Inc"; Console. WriteLine( "These folks work at {0}", Employee. Company); } Статические конструкторы // Статические конструкторы используются для инициализации статических переменных public class Employee { private static string CompName; static Employee() { CompName = "Intertech, Inc"; } } Если нам потребуется использовать свойство Employee.Company, присваивать ему исходное значение не придется — статический конструктор сделает это за нас автоматически: // Значение свойства ("Intertech. Inc") будет автоматически установлено // через статический конструктор public static int Main(string[] args) { Console. WriteLine(“These folks work at {0}”, Employee.Company); } Псевдоинкапсуляция: создание полей «только для чтения» public class Employee { // Поле только для чтения (его значение устанавливается конструктором): public readonly string SSNFIeld; } Статические поля «только для чтения» // В классе Tire определен набор полей только для чтения public class Tire { public static readonly Tire GoodStone = new Tire(90); public static readonly Tire FireYear = new Tire(100); public static readonly Tire ReadyLine = new Tire(43); public static readonly Tire Blimpy = new Tire(83); private int manufacturelD; public int MakeID { get { return manufacturelD;} } public Tire (int ID) { manufactureID = ID; } }