ТЕМА 16: Класове и обекти
Класове и обекти
Класът е фундамент, на който е построен целия език С#. В класа се определят данните и кода, който обработва тези данни. Обектите са екземпляри на класа. Непосредствената инициализация на променливите в обекта се извършва в конструктор. В класа могат да бъдат определени няколко конструктора.
Класът е логическа абстракция докато не бъде създаден обект и не се появи физическа реализация на този обекат в паметта на компютъра. Методите и променливите, съставящи класа, се наричат членове на класа. Данните се съдържат в променливите на обекта, които са определени в класа, а кода се съдържа в методите. Общ вид на дефиницията на класа, съдържащ само променливи на екземпляра и методи:
class име_на_класа
{
достъп тип променлива1;
достъп тип променлива2;
...
достъп тип променливаN;
достъп тип метод1(параметри)
{
//тяло;
}
достъп тип метод2(параметри)
{
//тяло;
}
...
достъп тип методN(параметри)
{
//тяло;
}
}
Обърнете внимание, че дефинирането на всяка променлива или метод започва с задавне на достъп. Достъпът може да бъде private или public. Модификаторът private указва, че съответния член на класа е достъпен само за членовете на този клас. Модификатортът public указва, че съответния член на класа е достъпен и за кода, определен извън границите на дадения клас. Ако достъпът не е зададен се приема по подразбиране private. Методър Main() е необходим само в класа, от който трябва да започне изпълнението на програмата.
using System;
class Vehicle
{
public int passengers;
public int fuelcap;
public int mpg;
}
Синтаксиса за дефиниране на променлива на екземпляра е аналогичен на този, на дефиниране на вътрешни (локални) променливи, само че дефиницията започва със задаване на спецификатора за достъп. С дефинирането на класа се описва нов тип данни:
class VehicleDemo
{
public static void Main()
{
Vehicle minivan = new Vehicle();
Vehicle sportscar = new Vehicle();
//Тук се създават 2 обекта с помощта на операцията new:
int range1, range2;
/*При създаване на екземпляр на класа се създава обект => всеки екземпляр съдържа свои собствени копия на променливите си. За достъп до тях се ползва операцията ‘.’. Тази операция свързва името на обекта с името на члена на класа. Операцията ‘.’ може да се използва за достъп както до променливите на екземпляра, така и до методите.*/
minivan.passengers = 7;
minivan.fuelcap = 16;
minivan.mpg = 21;
sportscar.passengers = 2;
sportscar.fuelcap = 14;
sportscar.mpg = 12;
/*Пресмятане на максималното растояние, което може да измине всеки от автомобилите ако има пълен резервоар.*/
range1 = minivan.fuelcap * minivan.mpg;
range2 = sportscar.fuelcap * sportscar.mpg;
Console.WriteLine("Микробусът може да превози " + minivan.passengers + " пътници на растояние " + range1 + " мили");
Console.WriteLine("Спортният автомобил може да превози " + sportscar.passengers + " пътници на растояния " + range2 + " мили");
}
}
В този пример, класовете Vehicle и VehicleDemo са различни самостоятелни класове. Единствената връзка между тях е, че в единия клас се създава екземпляр на другия клас. Макар че те са самостоятелни, кодът във VehicleDemo може да има достъп до членовете на Vehicle, тъй като те са public. В редa “Vehicle minivan = new Vehicle();” се извършват две действия:
- дефинира се променлива с име minivan от тип Vehicle, тази променлива не е непосредствено обект а съдържа адрес на обект;
- при изпълнението на new се създава обект чиито адрес се присвоява на minivan.
След изпълнението на кода от реда minivan ще бъде псевдоним на указател към обект от тип Vehicle. Операцията new динамично разпределя памет за обекта и връща адреса на тази област от паметта, който по-късно се съхранява в променлива т.е. за всички стойности в C# се заделя памет динамично. Двете стъпки за по нагледно могат да се запишат отделно:
Vehicle minivan;
minivan = new Vehicle();
Непосредствено след дефинирането на minivan, тя съдържа стойност null, което означава, че тя няма връзка с определен обект. Когато й се присвои адрес на даден обект, тогава тя има връзка с този обект. Тъй като достъпът до елементите на класа става чрез указател (reference), то класът е от reference-тип (указателен тип). Променлива от обикновен тип непосредствено съхранява стойността си, а променлива от указателен тип съхранява адрес на обект.
Фрагмент от програма:
Vehicle car1 = new Vehicle();
Vehicle car2 = car1;
Двете променливи сочат към един и същи обект т.е. достъпът до обекта може да се реализира чрез която и да е от тях. Когато стойността на променлива от указателен тип се присвоява на друга променлива от указателен тип, двете променливи сочат към един адрес и копиране на променлива (обект) не се прави.
Vehicle car3 = new Vehicle();
car2 = car3;
Сега car2 и car3 ще сочат към един и същи обект. Обектът към който сочи car1 не се променя.