Public Book(string name, string author, int year)
{
this.name = name;
this.author = author;
this.year = year;
}
Public void Info()
{
Console.WriteLine("Книга '{0}' (автор {1}) была издана в {2} году", name, author, year);
}
}
Class Program
{
static void Main(string[] args)
{
Book b1 = new Book("Война и мир", "Л. Н. Толстой", 1869);
b1.GetInformation();
Book b2 = new Book();
b2.GetInformation();
Console.ReadLine();
}
}
В данном случае мы использовали два конструктора. Один пустой. Второй конструктор наполняет поля класса начальными значениями, которые передаются через его параметры.
Поскольку имена параметров и имена полей (name, author, year) в данном случае совпадают, то мы используем ключевое слово this. Это ключевое слово представляет ссылку на текущий экземпляр класса. Поэтому в выражении this.name = name; первая часть this.name означает, что name - это поле текущего класса, а не название параметра name. Если бы у нас параметры и поля назывались по-разному, то использовать слово this было бы необязательно.
Наследование и полиморфизм. Переопределение методов.
Пусть у нас есть следующий класс Person, описывающий отдельного человека:
class Person { private string _firstName; private string _lastName; public string FirstName { get { return _firstName; } set { _firstName = value; } } public string LastName { get { return _lastName; } set { _lastName = value; } } public void Display() { Console.WriteLine(FirstName + " " + LastName); } } |
Но вдруг нам потребовался класс, описывающий сотрудника предприятия - класс Employee. Поскольку этот класс будет реализовывать тот же функционал, что и класс Person, так как сотрудник - это также и человек, то было бы рационально сделать класс Employee производным (или наследником, или подклассом) от класса Person, который, в свою очередь, называется базовым классом или родителем (или суперклассом):
class Employee : Person { } |
После двоеточия мы указываем базовый класс для данного класса. Для класса Employee базовым является Person, и поэтому класс Employee наследует все те же свойства, методы, поля, которые есть в классе Person. Единственное, что не передается при наследовании, это конструкторы базового класса.
static void Main(string[] args)
{
Person p = new Person { FirstName = "Bill", LastName = "Gates" };
p.Display();
p = new Employee { FirstName = "Denis", LastName = "Ritchi" };
p.Display();
Console.Read();
}
Все классы по умолчанию могут наследоваться. Однако здесь есть ряд ограничений:
· Не поддерживается множественное наследование, класс может наследоваться только от одного класса. Хотя проблема множественного наследования реализуется с помощью концепции интерфейсов, о которых мы поговорим позже.
· При создании производного класса надо учитывать тип доступа к базовому классу - тип доступа к производному классу должен быть таким же, как и у базового класса, или более строгим. То есть, если базовый класс у нас имеет тип доступа internal, то производный класс может иметь тип доступа internal или private, но не public.
Полиморфизм является третьим ключевым аспектом объектно-ориентированного программирования и предполагает способность к изменению функционала, унаследованного от базового класса.
Можно просто определить в классе-наследнике метод с тем же именем, добавив в его определение ключевое слово new:
Class Employee : Person
{
public string Company;
Public new void Display()
{
Console.WriteLine(FirstName + " " + LastName + " работает в компании "+ Company);
}
}
static void Main(string[] args)
{
Person p1 = new Person("Bill", "Gates");
P1.Display(); // вызов метода Display из класса Person
Employee p2 = new Employee("Sam", "Toms", "CreditBank");
P2.Display(); // вызов метода Display из класса Employee
}
Статические члены класса
Ранее, чтобы использовать какой-нибудь класс, устанавливать и получать его поля, использовать его методы, мы создавали его объект. Однако если данный класс имеет статические методы, то, чтобы получить к ним доступ, необязательно создавать объект этого класса.
Class Algorithm
{
Public static int Factorial(int x)
{
if (x == 1)
{
return 1;
}
Else
{
return x * Factorial(x - 1);
}
}
}
Ключевое слово static при определении переменной и методов указывает, что данные члены будут доступны для всего класса, то есть будут статическими. Теперь используем их в программе:
int num1 = Algorithm.Factorial(5); |
Нередко статические поля применяются для хранения счетчиков. Например, пусть у нас есть класс State, и мы хотим иметь счетчик, который позволял бы узнать, сколько объектов State создано:
Class State
{
private static int counter = 0;
Public State()
{
counter++;
}