Bobcho
Write second dog name:
Walcho
Bobcho said: Wow-wow!
Walcho said: Wow-wow!
Balkan said: Wow-wow!
В примерната програма, с помощта на Console.ReadLine(), получаваме имената на обектите от тип куче, които потребителят трябва да въведе от конзолата.
Присвояваме първия въведен низ на променливата firstDogName. След това използваме тази променлива при създаването на първия обект от тип Dog – firstDog, като я подаваме като параметър на конструктора.
Създаваме втория обект от тип Dog, без да подаваме низ за името на кучето на конструктора му. След това, чрез Console.ReadLine(), въвеждаме името на второто куче и получената стойност директно подаваме на свойството Name. Извикването му става чрез точкова нотация, приложена към променливата, която пази референция към втория създаден обект от тип Dog – secondDog.Name.
Когато създаваме третия обект от тип Dog, не подаваме име на кучето на конструктора, нито след това модифицираме подразбиращата се стойност "Balkan".
След това създаваме масив от тип Dog, като го инициализираме с трите обекта, които току-що създадохме.
Накрая, използваме цикъл, за да обходим масива от обекти от тип Dog. На всеки елемент от масива, отново използвайки точкова нотация, извикваме метода Bark() за съответния обект чрез dog.Bark().
Природа на обектите
Нека припомним, че когато в .NET създадем един обект, той се състои от две части – същинска част от обекта, която съдържа неговите данни и се намира в частта от оперативната памет, наречена динамична памет (heap) и референция към този обект, която се намира в друга част от оперативната памет, където се държат локалните променливи и параметрите на методите, наречена стек (stack).
Например, нека имаме клас Dog, на който характеристиките му са име (name), порода (kind) и възраст (age). Създаваме променлива dog от този клас. Тази променлива се явява референция (указател) към обекта в динамичната памет (heap).
Референцията е променливата, чрез която достъпваме обекта. На схемата по-долу примерната референция, която има връзка към реалния обект в хийпа, е с името dog. В нея, за разлика от променливите от примитивен тип, не се съдържа самата стойност (т.е. данните на самия обект), а адреса, на който те се намират в хийпа:
Когато декларираме една променлива от тип някакъв клас, но не искаме тя да е инициализирана с връзка към конкретен обект, тогава трябва да й присвоим стойност null. Ключовата дума null в езика C# означава, че една променлива не сочи към нито един обект (липса на стойност):
Съхранение на собствени класове
В C# единственото ограничение относно съхранението на наши собствени класове е те да са във файлове с разширение .cs. В един такъв файл може да има няколко класа, структури и други типове. Въпреки че компилаторът не го изисква, е препоръчително всеки клас да се съхранява в отделен файл, който съответства на името му, т.е. класът Dog трябва да е записан във файл с име Dog.cs.
Вътрешна организация на класовете
Както знаем от темата "Създаване и използване на обекти", пространствата от имена (namespaces) в C# представляват именувани групи класове, които са логически свързани, без да има специално изискване как да бъдат разположени във файловата система.
Ако искаме да включим в кода си пространствата от имена нужни за работата на класовете, декларирани в даден файл или няколко файла, това трябва да стане чрез т.нар. using директиви. Те не са задължителни, но ако ги има, трябва да ги поставим на първите редове от файла, преди декларациите на класове или други типове. В следващите параграфи ще разберем за какво по-точно служат те.
След включването на използваните пространства от имена, следва декларирането на пространството от имена на класовете във файла. Както вече знаем, не сме задължени да дефинираме класовете си в пространство от имена, но е добра практика да го правим, тъй като разпределянето в пространства от имена помага за по-добрата организация на кода и разграничаването на класовете с еднакви имена.
Пространствата от имена съдържат декларации на класове, структури, интерфейси и други типове данни, както и други пространства от имена. Пример за вложени пространства от имена е пространството от имена System, което съдържа пространството от имена Data. Името на вложеното пространство е System.Data.
Пълното име на класа в .NET Framework е името на класа, предшествано от името на пространството от имена, в което той е деклариран: .. Чрез using директивите можем да използваме типовете от дадено пространство от имена, без да уточняваме пълното му име. Например:
using System;
…
DateTime date;
|
вместо
Ето типичната последователност на декларациите, която трябва да следваме, когато създаваме собствени .cs файлове:
// Using directives - optional
using ;
using ;
// Namespace definition - optional
namespace
{
// Class declaration
class
{
// ... Class body ...
}
// Class declaration
class
{
// ... Class body ...
}
// ...
// Class declaration
class
{
// ... Class body ...
}
}
|
Декларирането на пространство от имена и съответно включването на пространства от имена са вече обяснени в главата "Създаване и използване на обекти" и затова няма да ги дискутираме отново.
Преди да продължим, да обърнем внимание на първия ред от горната схема. Вместо включвания на пространства от имена той съдържа коментар. Това не е проблем, тъй като по време на компилация, коментарите се "изчистват" от кода и на първи ред от файла остава включване на пространство от имена.
Кодиране на файловете. Четене на кирилица и Unicode
Когато създаваме .cs файл, в който да дефинираме класовете си, е добре да помислим за кодирането при съхраняването му във файловата система.
Вътрешно в .NET Framework компилираният код се представя в Unicode кодиране и затова няма проблеми, ако във файла използваме символи, които са от азбуки, различни от латинската, например на кирилица:
using System;
public class EncodingTest
{
// Тестов коментар
static int години = 4;
static void Main()
{
Console.WriteLine("години: " + години);
}
}
|
Този код ще се компилира и изпълни без проблем, но за да запазим символите четими в редактора на Visual Studio, трябва да осигурим подходящото кодиране на файла.
За да направим това или ако искаме да използваме различно кодиране от Unicode, трябва да асоциираме съответното кодиране с файла. При отваряне на файлове това става по следния начин:
1. От File менюто избираме Open и след това File.
2. В прозореца Open File натискаме стрелката, съседна на бутона Open и избираме Open With.
3. От списъка на прозореца Open With избираме Editor с encoding support, например CSharp Editor with Encoding.
4. Натискаме [OK].
5. В прозореца Encoding избираме съответното кодиране от падащото меню Encoding.
6. Натискаме [OK].
За запаметяване на файлове във файловата система в определено кодиране стъпките са следните:
1. От менюто File избираме Save As.
2. В прозореца Save File As натискаме стрелката, съседна на бутона Save и избираме Save with Encoding.
3. В Advanced Save Options избираме желаното кодиране от списъка Encoding (за предпочитане е универсалното кодиране UTF-8).
4. От Line Endings избираме желания вид за край на реда.
Въпреки че имаме възможността да използваме символи от други азбуки, в .cs файловете, e препоръчително да пишем всички идентификатори и коментари на английски език, за да може кодът ни да е разбираем за повече хора по света.
Представете си само, ако ви се наложи да дописвате код, писан от виетнамец, където имената на променливите и коментарите са на виетнамски език. Не искате да ви се случва, нали? Тогава се замислете как ще се почувства един виетнамец, ако види променливи и коментари на български език.
Модификатори и нива на достъп (видимост)
Нека си припомним, от главата "Методи", че модификатор наричаме ключова дума с помощта, на която даваме допълнителна информация на компилатора за кода, за който се отнася модификаторът.
В C# има четири модификатора за достъп. Те са public, private, protected и internal. Модификатори за достъп могат да се използват само пред следните елементи на класа: декларация, полета, свойства и методи на класа.
Модификатори и нива на достъп
Както обяснихме, в C# има четири модификатора за достъп – public, private, protected и internal. С тях ние ограничаваме или позволяваме достъпа (видимостта) до елементите на класа, пред които те са поставени. Нивата на достъп в .NET биват public, protected, internal, protected internal и private. В тази глава ще се занимаем подробно само с public, private и internal. Повече за protected и protected internal ще научим в главата "Принципи на обектно-ориентираното програмиране".
Ниво на достъп public
Използвайки модификатора public, ние указваме на компилатора, че елементът, пред който е поставен, може да бъде достъпен от всеки друг клас, независимо дали е от текущия проект, от текущото пространство от имена или извън тях. Нивото на достъп public определя липса на ограничения върху видимостта, най-малко рестриктивното от всички нива на достъп в C#.
Ниво на достъп private
Нивото на достъп private, което налага най-голяма рестрикция на видимостта на класа и елементите му. Модификаторът private служи за индикация, че елементът, за който се отнася, не може да бъде достъпван от никой друг клас (освен от класа, в който е дефиниран), дори този клас да се намира в същото пространство от имена. Това ниво на достъп се използва по подразбиране, т.е. се прилага, когато липсва модификатор за достъп пред съответния елемент на класа.
Ниво на достъп internal
Модификаторът internal се използва, за да се ограничи достъпът до елемента само от файлове от същото асембли, т.е. същия проект във Visual Studio. Когато във Visual Studio направим няколко проекта, класовете от тях ще се компилират в различни асемблита.
Асембли (assembly)
Сподели с приятели: |