Капсулация – пример
За да онагледим какво представлява капсулацията, която предоставят свойствата на един клас, както и какво представляват самите свойства, ще разгледаме един пример.
Нека имаме клас, който представя точка от двумерното пространство със свойства координатите (x, y). Ето как би изглеждал той, ако декларираме всяка една от координатите, като поле:
Point.cs
|
using System;
class Point
{
private double x;
private double y;
public Point(int x, int y)
{
this.x = x;
this.y = y;
}
public double X
{
get { return x; }
set { x = value; }
}
public double Y
{
get { return y; }
set { y = value; }
}
}
|
Полетата на обектите от нашия клас (т.е. координатите на точките) са декларирани като private и не могат да бъдат достъпвани чрез точкова нотация. Ако създадем обект от клас Point, можем да модифицираме и четем свойствата (координатите) на точката, единствено чрез свойствата за достъп до тях:
PointTest.cs
|
using System;
class PointTest
{
static void Main()
{
Point myPoint = new Point(2, 3);
double myPointXCoordinate = myPoint.X; // Access a property
double myPointYCoordinate = myPoint.Y; // Access a property
Console.WriteLine("The X coordinate is: " +
myPointXCoordinate);
Console.WriteLine("The Y coordinate is: " +
myPointYCoordinate);
}
}
|
Резултатът от изпълнението на този Main() метод ще бъде следният:
The X coordinate is: 2
The Y coordinate is: 3
|
Ако обаче решим, да променим вътрешното представяне на свойствата на точката, например вместо две полета, ги декларираме като едномерен масив с два елемента, можем да го направим, без това да повлияе по някакъв начин на останалите класове от нашия проект:
Point.cs
|
using System;
class Point
{
private double[] coordinates;
public Point(int xCoord, int yCoord)
{
this.coordinates = new double[2];
// Initializing the x coordinate
coordinates[0] = xCoord;
// Initializing the y coordinate
coordinates[1] = yCoord;
}
public double XCoord
{
get { return coordinates[0]; }
set { coordinates[0] = value; }
}
public double YCoord
{
get { return coordinates[1]; }
set { coordinates[1] = value; }
}
}
|
Резултатът от изпълнението на Main() метода няма да се промени и резултатът ще бъде същият, без да променяме дори символ в кода на класа PointTest.
Демонстрираното е добър пример за добра капсулация на данните на един обект предоставена от механизма на свойствата. Чрез тях скриваме вътрешното представяне на информацията, като декларираме свойства / методи за достъп до него и ако в последствие настъпи промяна в представянето, това няма да се отрази на другите класове, които използват нашия клас, тъй като те ползват само свойствата му и не знаят как е представена информацията "зад кулисите".
Разбира се, разгледаният пример демонстрира само една от ползите да се опаковат (обвиват) полетата на класа в свойства. Свойствата позволяват още контрол над данните в класа и могат да проверяват дали присвояваните стойности свойства са коректни по някакви критерии. Например ако имаме свойство максимална скорост на клас Car, може чрез свойства да наложим изискването стойността й да е в диапазона между 1 и 300 км/ч.
Още за физическото представяне на свойствата в класа
Както видяхме по-горе, свойствата могат да имат различно представяне в един клас на физическо ниво. В нашия пример, информацията за свойствата на класа Point първоначално беше съхранена в две полета, а след това в едно поле-масив.
Ако обаче решим, вместо да пазим информацията за свойствата на точката в полета, можем да я запазим във файл или в база данни и всеки път, когато се наложи да достъпваме съответното свойство, можем да четем / пишем от файла или базата вместо както в предходните примери да използваме полета на класа. Тъй като свойствата се достъпват чрез специални методи (наречени методи за достъп и модификация или accessor methods), които ще разгледаме след малко, за класовете, които ще използват нашия клас, това как се съхранява информацията няма да има значение (заради добрата капсулация!).
В най-честия случай обаче, информацията за свойствата на класа се пази в поле на класа, което има възможно най-стриктното ниво на видимост private.
|
Няма значение по какъв начин физически ще бъде пазена информацията за свойствата в един C# клас, но обикновено това става чрез поле на класа с максимално ограничено ниво на достъп (private).
|
Сподели с приятели: |