С# для AS3 розробників. Частина 3: get, set, sealed, using, const, readonly

image

Переклад статті From AS3 to C#, Part 3: AS3 Class Parity

Сьогодні ми закінчимо розбиратися з класами в C# (з точки зору AS3 розробника) і підготуємося до наступної статті, в якій ми зможемо познайомитися з поняттями, аналогів яких немає в AS3. У поточній статті ми розглянемо спосіб реалізації:
— геттеров/сеттерів (getter/setter)
— функцій і класів, які не можна перекрити/успадковувати (final)
— констант
— пакетів


Get/Set функції

Давайте почнемо з геттеров і сеттерів. Щоб освіжити пам'ять, ось як вони виглядали в AS3:

class Person
{
private var _name:String;
public function get name(): String
{
return _name;
}
public function set name(n:String): void
{
_name = n;
}
}


А ось, еквівалент у З#:

class Person
{
private String _name;
public String Name
{
get
{
return _name;
}
set
{
_name = value;
}
}
}


Як ми можемо побачити, C#, замість 2 оголошення функцій, геттер і сетер оголошені у вигляді єдиною змінною. Правда, ця змінна не закінчується крапкою з комою (;), а містить блок у вигляді фігурних дужок, всередині якого є 2 частини: get{} set{}. Ці частини є геттер і сетер функціями. Всередині сетера у вас буде доступ до нового ключовому слову value, воно являє собою значення, яке має бути встановлено і вам не потрібно оголошувати його, як це доводилося робити в AS3. Якщо не брати в розрахунок ця відмінність у синтаксисі, геттери і сетери працюють однаково в C# і AS3.

C# надає можливість використовувати скорочену запис для подібних функцій, дозволяючи уникнути написання зайвого коду для простих функцій:

class Person
{
public String Name { get; set; }
}


Використання цієї конструкції автоматично створить змінну _name і геттер/сетер функції, як у прикладі вище. Але що, якщо вам не потрібна функція-сетер? Просто приберіть її:

class Person
{
public String Name { get; }
}


Швидше за все, вам необхідно буде, як мінімум, надати можливість класу Person встановлювати значення цієї змінної. Для цього сетер може бути оголошений private:

class Person
{
public String Name { get; private set; }
}


І ще, трохи термінології C#: поля класу, у яких є get та/або set функції (Name), називаються «властивості». Змінні, які використовуються для зберігання цих даних (_name), називаються «допоміжні поля».

Final/sealed функції

А тепер, давайте поговоримо про final функції, які не можуть бути перевизначені (AS3):

class Person
{
final function print(): void
{
trace("i'm a Person");
}
}
class MyPerson extends Person
{
// illegal
override print function(): void
{
trace("i'm not just a Person, i'm a MyPerson too");
}
}


З# надає функціонал ідентичний, використовуючи слово sealed:

class Person
{
sealed void Print()
{
Debug.Log("i'm a Person");
}
}
class MyPerson extends Person
{
// illegal
override void Print()
{
Debug.Log("i'm not just a Person, i'm a MyPerson too");
}
}


Пакети і namespace

Пакети в AS3:

package com.jacksondunstan.examples
{
class Person
{
}
}


В C#, пакети називаються namespace, от і все:

namespace com.jacksondunstan.examples
{
class Person
{
}
}


Щоб отримати доступ до пакету всередині .as файлу, ви можете імпортувати пакет:

import com.jacksondunstan.examples;
class Printer
{
print function(person:Person): void
{
trace("person has name: " + person.name);
}
}


В C# ви використовуєте ключове слово using для namespace:

using com.jacksondunstan.examples;
class Printer
{
void Print(Person person)
{
Debug.Log("person has name: " + person.name);
}
}


Константи і readonly змінні

І наостанок, давайте поговоримо про константах. Ось, як в AS3 може бути створено поле, яке не можна змінити після оголошення:

class Person
{
private static const MIN_TEEN_AGE:int = 13;
private static const MAX_TEEN_AGE:int = 19;
var age:int;
function IsTeen(): Boolean
{
return age >= MIN_TEEN_AGE && age <= MAX_TEEN_AGE;
}
}


Ось, як це можна зробити в C#:

class Person
{
private const int MinTeenAge = 13;
private const int MaxTeenAge = 19;
int Age;
bool IsTeen()
{
return Age >= MinTeenAge && Age <= MaxTeenAge;
}
}


Важливий нюанс: в C# для констант можна використовувати тільки базові типи (наприклад, int) і рядки. Це необхідно тому, що подібне поле не буде існувати насправді, замість цього, скрізь, де воно використовується, будуть підставлені значення цього поля. Так само, це означає, що подібні поля автоматично стають статичними (static), і їх не потрібно оголошувати, як static окремо. Після компіляції клас Person в C# буде виглядати наступним чином:

class Person
{
int Age;
bool IsTeen()
{
return Age >= 13 && Age <= 19;
}
}


В AS3 ключове слово const використовувалося виключно для перевірки на етапі компіляції і не призводило до змін/подстановкам в коді. Якщо необхідно домогтися схожого поведінки в C# або необхідно використовувати базовий тип даних (наприклад, Person), то потрібно використовувати ключове слово readonly:

class Person
{
static readonly Person Newborn = new Person(0);
readonly int Age;
Person(int age)
{
Age = age;
}
}


У прикладі вище є 2 readonly поля:

1) Newborn — поле, яке було оголошено з ключовим словом static (readonly поля, на відміну від констант, не обов'язково є static). Дане поле буде ініціалізований в тому місці, де воно оголошено (за аналогією з константами в AS3).

2) Age — поле, яке є readonly, але не є static. Воно буде ініціалізований в конструкторі.

На завершення, порівняння описаних особливостей C# і AS3 коду:
////////
// C# //
////////

// Collection of classes being used by this file
using org.apache.coolstuff;

// Collection of classes
namespace com.jacksondunstan.examples
{
class Person
{
// Complex getters and setters
private String _name;
String Name
{
get
{
return _name;
}
set
{
_name = value;
}
}

// Simple getters and setters
int Age { get; set; }

// Read-only field
readonly int ID;

// Inlined field
const int AdultAge = 18;

// Function that can't be overridden
sealed void Print()
{
Debug.Log("Name: " + name + ", ID: " + ID);
}
}
}

/////////
// AS3 //
/////////

// Collection of classes being used by this file
import org.apache.coolstuff;

// Collection of classes
package com.jacksondunstan.examples
{
class Person
{
// Complex getters and setters
private var _name:String;
function get name(): String
{
return _name;
}
function set name(value:String): void
{
_name = value;
}




// Simple getters and setters
// {not supported. use complex instead.}

// Read-only field
const var ID:int;

// Inlined field
// {not supported. use compile-time constants via command-line instead.}

// Function that can't be overridden
final function print(): void
{
trace("Name: " + name + ", ID: " + ID);
}
}
}



У наступній статті ми, нарешті, почнемо розглядати поняття, аналогів яких немає в AS3.

Не перемикайте канал!

Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.