Короткий зміст перекладу книги "C# вундеркіндів"
Коротко у першій частині
Діалог молодих людей. Звучить пропозиція негайно програмувати та застереження, що для цього слід довго і нудно навчатися. Програмування без належних знань уподібнюється їзді на велосипеді наосліп. Проте програмувати на C# слід з насолодою.
Далі йде опис пакету для розробки програм на C# на основі Microsoft Visual C # Express Edition. Створення консольного додатку та написання найпростішої програми.
Також пояснюється компіляція програми, запуск на виконання, доповнення коментарями. Завершується перша частина пропозицією налагодити спілкування з комп'ютером.
Коротко у другій частині
Образно пояснюється складність написання та розуміння комп'ютерних програм різним походженням людини та комп'ютера: "У нас різні батьки". Пропонується таке вирішення проблеми:
знайти єдиний «погляд на світ»;
виробити спільну мову, яку здатні розуміти як люди, так і комп'ютери.
Далі йде історія про налагодження спілкування з прибульцем. Якась зголодніла "Свєта" на безлюдному острові зустріла прибульця та назвала його "Алджі". Щоб прибулець допоміг з харчами Света навчила його людської (припустимо української) мови показуючи на картинки та предмети. Алджі швидко запам'ятав назви. Проте він не хотів зрозуміти прохання Свєти дістати їй з дерева банан. Свєта надзвичайно довго страждає від такого непорозуміння. Згодом "вищі сили" підказують Свєті, що Алджі це й не Алджі зовсім а якийсь Зніфф12. Нарешті Свєта винаходить як розтлумачити прибульцю свої забаганки. Вона повідомляє "Алджі-Зніффа12-го" про те, що:
1. усі "об'єкти" об'єднані в "класи". (Света класифікує рослин в клас "рослини", тварини в клас "тварин" і т.д.);
2. кожен об'єкт має свої властивості. (Приміром слон "може рухатися", він "важкий" і він "вредний");
3. безперевно відбуваються "події" (Свєта зголодніла, поспіли кокоси і т.д.);
4. подію можна викликати. (Якщо викликати подію "знепокоєння слона" то це допоможе викликати подію "добування кокосів" через подію "слон вдарить пальму").
На таке пояснення Алджі видає, що сам належить до класу об'єктів, що звуться "Ікс-зніфферами". Всі об'єкти цього класу мають такі властивості:
- Name (наприклад ім'я прибульця, що спілкується зі Сієтою - Зніфф12);
- EarShape (ФормаВуха) (значення цієї властивості завжди «трубка»);
- LikeToWatchTV (ЛюблюДивитисяТелевізор) (у більшості випадків має значення істини, а в інших випадках - хиби (брехні).
Ще Алджі говорить про те, що зараз вони на зйомках телешоу "Залишитися у живих" але історія завершується як приклад встановлення порозуміння між представниками різних цивілізацій. Порозуміння це було знайдено практично в термінах та поняттях об'єктно-орієнтованого програмування (ООП).
Замість інопланетянина можна порозумітися з комп'ютером аналогічним чином хоча підхід з використанням «класів, об'єктів, властивостей, подій і методів» теж не є бездоганним. Існують та створюються інші способи для "пояснення" комп'ютеру навколишнього світу але мова C # вимагає дотримуватися саме об'єктно-орієнтованого підходу. Щоб комп'ютер став помічником необхідно: вивчити мову C#, навчитися описувати речі з орієнтацією на об'єкти, встановити середовище програмування C# та інші супутні програми.
Опис орієнтації на об'єкти з точки зору програміста.
Для угруповання подібних об'єктів навколишнього світу можна розділити їх на різні класи речей, такі як «коти» або «будинки» або «дерева».
Для комп'ютера необхідно створити деякий опис того чи іншого об'єкта вказавши його властивості.Їх можна порівняти з прикметниками в українській мові. Наприклад, кота "Пушок" можна описати такими властивостями як зріст, вага та іншими.
Події - це зміни, що відбуваються з об'єктом. У реальному світі події відбуваються безперервно. Наприклад, коли я гладжу Пушка, ця подія відбувається з ним. Подібним чином, вітер, що розвіває гілки дуба - це подія, що відбувається з деревом. Події, як правило, являють собою дії, що впливають на певний об'єкт, але сам об'єкт вплинути на них не може. У комп'ютерному світі подіями можуть бути «натискання кнопки» або «переміщення миші».
Дії виконуються об'єктом. Наприклад, кіт Пушок лиже свою шерсть - це дія. Приклад дії у комп'ютерному світі «малювання зображення кота при натисканні на кнопку».
Комп'ютер по-справжньому нерозумний, він не має уявлення про те як намалювати кота. Необхідно дати зрозумілий комп'ютеру опис - метод малювання кота. Метод подібний до рецепта. Це набір покрокових інструкцій, які визначають порядок малювання кота.
Ще приклад класів це класи у школі. Дітей певного віку або з певними здібностями об'єднали в групу і назвали її класом. Вони будуть навчатися приблизно однаково і здавати одні і ті ж іспити. Але це не означає, що всі учні класу однакові, а лише говорить про те, що у них є певні спільні риси.
Трохи пізніше ми додаємо другий вираз, яке скаже комп'ютеру: «Гей, пам'ятаєш об'єкт Barsik? Тепер мені потрібно виконати з ним дію. Звільни простір в голові для роздумів про цю тварину. Комп'ютер представляє новий об'єкт «Animal» в своїй голові і розуміє, що ви говорите про той же об'єкті (Barsik), згаданий раніше. Вивчивши клас «Animal», комп'ютеру стало дещо відомо про Барсика, і він тримає цю інформацію напоготові у своїй голові в надії на те, що отримає від вас додаткові дані або кілька запитань щодо Барсика.
Animal Barsik; // оголошення об'єкта
Barsik = new Animal (); // вказівка створити реальний об'єкт з яким можна виконувати дії
Урок додавання елементів до класу
Список властивостей тварин:
Вид тварини (Kind of animal)
Зріст (Height)
Довжина (Length)
Кількість лап (Number of legs)
Забарвлення (Color)
Наявність хвоста (Has a tail)
Ссавець (Is a mammal)
Можна присвоїти значення кожної з них
Kind of animal = «Cat»
Height = 50 cm
Length = 110 cm
Number of legs = 4
Color = «Black»
Has tail = true
Is mammal = true
У C # властивості називаються полями.
Існують різні типи полів.
Значення полів height, width і number of legs є числами. Ці значення придатні для виконання математичних операцій.
Значення полів kind of animal і color складатися з букв, скріплених разом. Це рядкові поля. Вони також можуть містити числа але з числами в рядку не можна виконувати математичні операції.
Поле has tail буде приймати значення ІСТИНА або БРЕХНЯ (true / false) ще ці ж значення називають ТАК чи НІ («yes / no»).
Кожен «тип» обробляється комп'ютером по-різному, тому при визначенні полів ми повинні вказувати їх тип.
Тип «String» (рядок)
string kindOfAnimal; // повідомить комп'ютер, що властивість kindOfAnimal потрібно розглядати як рядок літер.
Числові типи
Числове значення поля в мові C# можна позначити одним з декількох числових типів. Найбільш поширений - integer. Це ціле число, яке може бути негативним, позитивним чи нулем.
int numberOfLegs; // властивість numberOfLegs цілочисельного типу integer
Тип «Boolean» (логічне значення)
Годиться якщо деяке поле буде завжди приймає значення «true» або «false» і нічого крім цих значень. Це найпростіший з усіх типів.
bool hasTail; // властивість hasTail логічного типу
У C # опис класу для комп'ютера може мати наступний вигляд:
class Animal
{
}
Ми збираємося обговорювати клас об'єктів, ми назвемо цей клас Animal (тварина), все опис цього класу буде розташовано між фігурними дужками {...}.
Ім'я класу «Animal» доречне у програмі, що виводить на екран зображення тварин або зберігає цікаві факти про них. Ще приклади імен класів «MyPhotoProgram» (МояФотоПрограма) або «MyGradeCalculator» (МійРізновидКалькулятора). Класи не обов'язково працюють з об'єктами, що існують в реальному світі - ім'я класу дається для опису того, з чим він має справу.
Слово «class» має бути написано малими літерами, але ім'я класу може бути будь-яким і містити літери як прописні, так і малі. Використання проміжків (пробілів між словами) не допускається. Для спрощення читання й розуміння код слід писати на окремих рядках, але для комп'ютера це немає принципової різниці.
Наприклад є певна істота в класі тварин яку ви називаєте Барсиком. Це можна виразити таким чином:
Animal Barsik;
Комп'ютер це розуміє так: «Ця людина хоче поговорити про об'єкт у класі «Animal» і назвати його «Barsik». Однак код потрібно доповнити ще одним виразом:
Barsik = new Animal ();
Перший вираз попереджає комп'ютер, що незабаром ми попросимо його працювати з певним індивідуумом з класу «Animal». Тепер у комп'ютера з'являється можливість перевірити свої знання про цей клас. Він переглядає всю програму і шукає опис класу з ім'ям «Animal». Якщо він не знаходить такого об'єкта, то може попередити вас: «Ей, я не зможу цього зробити!». Якщо ж вдається знайти потрібний опис, він просто продовжить виконання програми, взявши до уваги, що ви пізніше попросите його виконати деяку дію з об'єктом класу «Animal» на ім'я Barsik.
Додавання полів у клас
Ми готові додати поля у визначення класу.
class Animal
{
string kindOfAnimal;
string name;
int numberOfLegs;
int height;
int length;
string color;
bool hasTail;
bool isMammal;
bool spellingCorrect;
}
(Щоб код легко читався створюються відступи полів пропусками та клавішею TAB)
Використання полів з певними об'єктами
Отже, тепер ми пояснили комп'ютеру, що ВСІ об'єкти класу «Animal» мають ці поля. Тепер давайте попросимо комп'ютер створити екземпляр, який являє певний об'єкт класу «Animal» (як ми робили це в попередньому розділі) і повідомимо комп'ютеру деяку інформацію про цей певний об'єкт, присвоївши значення кожному полю.
Animal Barsik;
Barsik = new Animal ();
Barsik.kindOfAnimal = "Cat";
Barsik.name = "Кіт Барсик";
Barsik.numberOfLegs = 4;
Barsik.height = 50;
Barsik.length = 110;
Barsik.color = "Black";
Barsik.hasTail = true;
Barsik.isMammal = true;
Зверніть увагу, що значення рядкових полів завжди береться в лапки (""), але тільки не значення інших типів полів. В кінці кожного виразу ставиться крапка з комою (;).
На даному етапі варто згадати, що вибране нами ім'я об'єкта «Barsik» не несе ніякого емоційного значення для комп'ютера. Він би також легко працював з об'єктом, якби ми замінили всі імена «Barsik» на «X» чи будь-яке інше ім'я на вибір:
Animal X;
X = new Animal ();
X.kindOfAnimal = "Cat";
X.height = 50;
X.length = 110;
X.color = "Black";
X.hasTail = true;
X.isMammal = true;
Хоча поля можуть розташовуватися на краю сторінки, вважається доброю звичкою дотримуватися відступів за допомогою табуляції від правого краю, які можна створити за допомогою клавіші TAB на клавіатурі. Це спрощує читання коду.
Поля завжди мають певний тип. Існує багато різних допустимих типів, ось опис деяких найбільш поширених з них:
Будівельний блок: Поля
Зазвичай в класі є одне або кілька полів, які дозволяють описувати певні риси такого класу
class SchoolKid
{
string firstName;
string lastname;
int age;
bool isWideAwake;
}
Зверніть увагу на різні рівні захищеності дітей в сім'ї, як показано на малюнку вище. Малютка Світлана закрита (private) в кімнаті - її не випускають з будинку і вона має найбільш високий рівень захисту. З нею можуть спілкуватися люди, що володіють найбільшою довірою. Борис може знаходитися як на передньому, так і задньому дворі, але він як і раніше в певною мірою захищений (protected). Толя, старша дитина, є відкритим (public) для інших і будь-хто може спілкуватися з ним.
Отже, на початок оголошення поля ми можемо додати наступне слово:
class Animal
{
public string kindOfAnimal;
public string name;
public int numberOfLegs;
public int height;
public int length;
public string color;
bool hasTail;
protected bool isMammal;
private bool spellingCorrect;
}
Ви може поцікавитися, а що якщо ми не станемо включати ці слова. У цьому випадку комп'ютер мовчки сприймає код, як якщо б на початку оголошення було написано слово «private», оскільки «private» задається за замовчуванням. Тому поле hasTail автоматично стає закритим (private).
Що означають ці слова?
Private означає, що «об'єкти тільки цього класу можуть звертатися до даного поля»
Public означає, що «об'єкти будь-якого класу можуть звертатися до цього поля»
Protected означає, що «тільки об'єкти тісно пов'язаних класів можуть звертатися до поля»
Наступні приклади двох класів демонструють описаний принцип полів public і private. Ми не станемо далі обговорювати поля типу protected. Додаткові відомості про них можна отримати в довідці Visual C # Express.
Як і раніше, ми спочатку визначаємо кілька закритих і відкритих полів у класі «Animal» і потім намагаємося звернутися до них з класу «Zoo».
class Animal
{
public string kindOfAnimal;
public string name;
public int numberOfLegs;
public int height;
public int length;
public string color;
bool hasTail;
protected bool isMammal;
private bool spellingCorrect;
}
class Zoo
{
Animal a = new Animal ();
/ / Наступний рядок буде виконана успішно, оскільки класу «Zoo» дозволено
/ / звертатися до відкритих полів у класі «Animal»
a.kindOfAnimal = "Kangaroo";
/ / Обидві наступні рядки НЕ будуть виконані, оскільки класу «Zoo»
/ / Не дозволено звертатися до закритих або захищеним полям
a.isMammal = false; / / Спроба звернення до захищеного методу
a.spellingCorrect = true; / / Спроба звернення до закритого методу
}
Програми були б досить малокорисними, якби дозволяли тільки описувати об'єкти. Безумовно, ми хочемо, щоб вони крім іншого виконували деякі дії.
Виводили слова на екран
Вирішували завдання
Копіювали дані з веб-сайту
Регулювали яскравість фотографії
... І могли виконувати ще тисячі операцій
А тепер згадайте уроки, на яких вас вчили додаванню чисел. Скоріш за все, спочатку вас учили тому ЯК додавати числа, можливо, покроково описуючи порядок дій. Іншими словами, в першу чергу вас вчили МЕТОДУ вирішення подібного типу завдання. Метод являє собою набір покрокових інструкцій, що пояснюють порядок виконання дій.
При визначенні поля в програмі необхідно вказати його тип та ім'я:
string lastname;
Позначення типу повинно бути відоме комп'ютеру. Зазначені вище основні типи (як int) пишуться малими літерами, проте деякі типи можуть містити великі літери.
Іменем поля може бути будь-яке слово, наприклад «ZavzdiNapogotovi» з поєднанням великих і малих літер. Використання пропусків (пробілів) не допускається.
При роботі з певним об'єктом, полям зазвичай присвоюються значення, які допомагають описувати об'єкт. Якщо, наприклад, у нас є об'єкт з ім'ям schoolKid, то його полям можна було б присвоїти наступні значення:
schoolKid.firstName = "Jiminy";
schoolKid.age = 13;
Назва об'єкту та ім'я поля розділяються крапкою (.).
Отже, schoolKid.firstName = "Jiminy" означає «значення "Jiminy" підставити в поле firstName об'єкта schoolKid».
Закриті, захищені і відкриті поля
При першому вивченні мови C # цей розділ не буде настільки важливим, але надалі вам можуть зустрічатися слова «private», «protected» і «public» і ви захочете дізнатися їх значення. Давайте обговоримо це питання.
class Animal
{
string kindOfAnimal;
string name;
int numberOfLegs;
int height;
int length;
string color;
bool hasTail;
bool isMammal;
bool spellingCorrect;
}
class MyTestClass
{
}
Об'єкти можна брати з одного класу, такого як MyTestClass вище, і говорити про об'єкти в іншому класі, такому як Animal.
При оголошенні полів так, як це показано вище, ми можемо вирішити, чи повинні інші класи мати доступ до них чи ні. Іноді дуже важливо робити поля закритими (private), наприклад тому що інший клас може поміщати неправильні значення в поля і порушувати роботу програми. Використання полів «private», «protected» і «public» визначає наскільки безпечним буде наш клас.
Тепер, коли вам відомий метод вирішення завдань певного типу, ви зможете вирішити будь-які поставлені перед вами завдання, дотримуючись його.
Подібним чином, щоб комп'ютер виконував потрібні нам дії, ми повинні написати код, що роз'яснює порядок їх виконання, іншими словами, ми повинні описати метод, який буде використовуватися для виконання необхідних дій. Потім цей метод можна буде застосовувати кожен раз при вирішенні завдання подібного типу.
У мові C # метод представлений уривком коду з описом порядку виконання певних дій. Коли згодом ми викликаємо його, комп'ютер читає код і виконує в точності те, що ми написали.
Простий метод для комп'ютера може мати наступний вигляд:
void SayHello ()
{
}
Але метод не має сенсу, якщо він нічого не робить, тому давайте доповнимо код між фігурними дужками.
void SayHello ()
{
Console.WriteLine ("Hello");
}
(Щоб додати коду акуратний вигляд, необхідно створити відступи в методі за допомогою клавіші TAB)
Якщо зараз викликати цей метод, то на екран буде виведено слово «Hello». Це не надто складне завдання, тому і метод досить простий.
Що означає VOID?
Дивне слово «void» в наведеному вище прикладі може дещо спантеличити і ви можете поцікавитися навіщо взагалі ми його використали. Давайте коротко розглянемо його. Просто подумайте про свій улюблений фільм про космічні подорожі: уявіть безмежний, порожній простір у Всесвіті. Void означає «нічого».
Використання слова «void» перед ім'ям методу означає, що коли завершується його виконання, повертається пусте значення, тобто нічого не повертається. Це не означає, що метод не виконує жодних дій, а скоріше те, що по завершенні відведеної операції він ніяких значень не повертає. У наведеному вище прикладі методу «SayHello» нам це чудово підходить, оскільки після написання слова «Hello» повертати нічого не потрібно. От і все, що потрібно було зробити.
Ви зможете краще зрозуміти сенс цього слова, коли ми будемо розглядати випадки, де метод повинен буде повертати деякий результат. Ми розглянемо цей приклад трохи пізніше.
Будівельний блок: Оголошення і виклик методу
Найчастіше в класі є один або декілька методів. Вони виконують певні дії. Методами вони називаються тому, що саме в них описується метод виконання дій: покрокові інструкції, що пояснюють порядок опреацій.
class Person { // Поля public string firstName; public string lastName; // Метод public void ShowFullName() { Console.WriteLine("Name is " + this.firstName + " " + this.lastName); } … }
Person Jiminy; Jiminy = new Person(); Jiminy.firstName = "Jiminy"; Jiminy.lastName = "Cricket"; Jiminy.ShowFullName();
Параметри метода
У попередньому розділі ми коротко ознайомилися з методами, але про них можна розповісти набагато більше. У цій главі ми розглянемо більш докладні характеристики методів. У першу чергу, вам буде досить основ, але на певному етапі буде потрібно розуміння того, як відправляти значення в метод і отримувати значення з нього.
Уявімо, що вам потрібно, щоб комп'ютер вивів на екран наступний текст:
Hello Jo
Hello Sam
Hello You
Ось один спосіб, як це зробити: можна було б написати окремий метод для кожного випадку:
void WriteHelloJo ()
{
Console.WriteLine ("Hello Jo");
}
void WriteHelloSam ()
{
Console.WriteLine ("Hello Sam");
}
void WriteHelloYou ()
{
Console.WriteLine ("Hello You");
}
і потім викликати їх наступним чином:
WriteHelloJo ();
WriteHelloSam ();
WriteHelloYou ();
Але це здається зайвою витратою сил, оскільки три методи дуже схожі один на одного. А що якщо використовувати один метод WriteHello і при кожному його виклик просто повідомляти потрібну частину, яка відрізняється від попередньої.
У цьому випадку можна написати наступний метод:
void WriteHello (string someName)
{
Console.WriteLine ("Hello" + someName);
}
і потім викликати метод таким чином:
WriteHello ("Jo");
WriteHello ("Sam");
WriteHello ("You");
Як видно, цей код дозволяє скоротити як займаний простір, так і зусилля. Потрібно завжди намагатися робити код як можна більш коротким. За великим рахунком, чим коротше програма, тим розумніша програміст.
При написанні методу подібним «розумним» чином,
void WriteHello (string someName)
{
Console.WriteLine ("Hello" + someName);
}
ми фактично кажемо: «Кожного разу при виклику цього методу я буду підставляти рядок символів з певним ім'ям. Будь-який підставлений рядок повинен виводитися після слова «Hello».
Код в дужках (string someName) називається параметром. Параметр дозволяє підставляти значення в метод при його виклику.
Коли вас навчали додаванню чисел, вчитель не розповідав про кожну можливості, він просто навчив вас методу і потім поставив вам різні завдання: «Додайте 2 і 5. Тепер додайте 7 і 3 ».
Це схоже на те, як якби вчитель виклав вам метод додавання чисел і підставляв щоразу різні параметри. Неважливо, які це були б параметри, ви б змогли знайти відповідь, бо знали б метод.
Для комп'ютера не має значення, яке ім'я ви присвоїли параметру, важливо щоб воно було єдиним при використанні в усьому методі.
Наприклад, наступний код буде виконано правильно:
void WriteHello (string x)
{
Console.WriteLine ("Hello" + x);
}
А цей - ні:
void WriteHello( string someName )
{
Console.WriteLine( “Hello ” + someBodysName );
}
Можете знайти помилку? Параметри «SomeName» і «someBodysName» відрізняються - це заплутає нашого «електронного» друга і він «розгнівається».
Крім того, можна на повних правах використовувати більше одного параметру в методі. Для цього їх потрібно просто розділити комами:
void WriteHello( string firstName, string lastName )
{
Console.WriteLine( “Hello ” + firstName + “ ” + lastName );
}
Але потім при виклику методу важливо підставити правильне кількість значень
WriteHello( “Jiminy”, “Cricket” );
WriteHello ("Чорт забирай", "Боротьба");
У даному випадку на екран буде виведено текст «Hello Jiminy Cricket». («Hello чорт забирай Крикет».)
Відправлення невірних типів параметрів
Уявіть, що коли ви вперше вивчали додавання чисел, ваш учитель несподіваного задав вам таке завдання: «Складіть число 5 і квітка».
Що б ви стали робити? Напевно відповіли б, що квітка це не число і додавання неможливе. Правильно.
Подібним чином комп'ютеру не сподобається, якщо ви вкажете значення невірного типу. Така помилка зустрічається часто серед програмістів. Тому якщо щось йде не так, поверніться і переконайтеся, що вказані вами значення мають тип, відповідний визначеному в методі.
А потім, кожен раз при виклику методу ми повинні переконатися, що підставляємо правильний тип значень в ці параметри. У наведеному нижче прикладі ми підставляємо два цілих числа, оскільки параметри методу «LuckyNumber» були визначені як цілі числа.
Будівельний блок: Параметри
Щоб підставити значення в метод, необхідно визначити в ньому параметри:
class Person { // Поля string firstName; string lastName; // Метод public void LuckyNumber( int numberOfTeeth, int age ) { Console.WriteLine( “Счастливое число “ + numberOfTeeth * age ); } … }
Person jiminy; jiminy= new Person(); jiminy.LuckyNumber(24, 14);
Наведені досі методи виводили якийсь текст на екран і потім просто поверталися назад до рядка, що викликав їх, як би кажучи: «Я свою справу зробив. Повернувся у вихідну точку». Однак, іноді може виникати необхідність повернення деякого значення в рядок, з якого цей метод був викликаний.
Наведемо приклад. Ми напишемо метод, який буде виконувати пошук кількості кінцівок зазначеної тварини і потім відправляти отримане число туди, звідки він був викликаний.
Далі визначається порядок створення методу. Слід пам'ятати, що метод це частина, в якій ми вчимо комп'ютер ЯК виконувати певну дію, записуючи послідовність операцій. Спочатку я напишу те, чого хочу добитися від комп'ютера українською мовою, а потім на C #:
Якщо тварина, про яку ми говоримо - слон, то number of legs = 4.
В іншому випадку, якщо тварина, про яку ми говоримо - індик, то number of legs = 2.
В іншому випадку, якщо тварина, про яку ми говоримо - устриця, то number of legs = 1.
В іншому випадку, якщо ми говоримо про будь-яких інших тварин, то number of legs = 0.
int NumberOfLegs (string animalName)
{
if (animalName == "слон") / / Якщо назва тварини - слон
{
/ / Повертане значення 4
return 4;
}
else if (animalName == "індичка") / / В іншому випадку, якщо тварина - індичка
{
/ / Повертане значення 2
return 2;
}
else if (animalName == "устриця") / / В іншому випадку, якщо тварина - устриця
{
/ / Повертане значення 1
return 1;
}
Else / / В іншому випадку (при всіх інших умовах)
{
/ / Повертане значення 0
return 0;
}
}
і потім ми могли б викликати метод: Викличемо його двічі:
1. int i; / / Створення змінної «i» цілочисельного типу для зберігання значення числа кінцівок
2. i = NumberOfLegs ("індичка"); / / Тепер i = 2 з методу NumberOfLegs вище
3. Console.WriteLine ("У індички" + i + "кінцівок");
4. i = NumberOfLegs ("мавпа"); / / Тепер i = 0 з методу NumberOfLegs вище
5. Console.WriteLine ("У мавпи" + i + "кінцівок");
У рядку 3 на екран виводиться текст «У індички 2 кінцівок», а по рядку 5 - «У мавпи 0 кінцівок». Отже, метод повертає значення, яке можна включити безпосередньо в рядок коду, звідки був викликаний метод.
Чому ми визначили метод саме так?
int NumberOfLegs (string animalName)
{
...
}
а не ось так:
void NumberOfLegs (string animalName)
{
...
}
або таким чином:
string NumberOfLegs (string animalName)
{
...
}
А зробили так ми саме тому, що нам необхідно, щоб метод повертав ціле число в даному випадку, а не «порожнє» значення (void), не рядок літер, а саме ціле число. А для роботи з цілими числами використовується тип даних «Integer» або «int» в скороченому варіанті.
При написанні методу ми завжди вказуємо тип даних, що повертаються цим методом. Якщо немає необхідності повертати значення, ми використовуємо «void» для повернення порожнього значення.
void JustWriteSomething (string someThing)
{
Console.WriteLine (someThing);
}
І нарешті, можливо ви здогадалися, що слово «return» фактично повертає значення. Коли комп'ютер зустрічає слово «return» відбувається вихід з методу і повернення запитуваного значення.
Повертаються значення потім автоматично стають доступними в будь-якому місці, де ми викликаємо метод.
Наприклад, повернене значення ми могли б використовувати наступним способом:
Спочатку ми могли б зберегти відповідь у змінній і потім використовувати значення змінної в окремому виразі.
Або ми могли б викликати метод безпосередньо у виразі WriteLine наступним чином:
Як і поля (див. попередню главу), методи можна викликати з інших класів. Таку можливість можна дозволити або заборонити.
За замовчуванням, всі методи будуть розглядатися як private (закриті), це означає, що їх можна використовувати тільки усередині свого класу. Щоб дозволити їх використання з інших класів, можна додати слово «public» в початок оголошення.
public void JustWriteSomething (string someThing)
{
Console.WriteLine (someThing);
}
У реальному світі доступ людей без спеціального дозволу до деяких зонах заборонено. Наприклад, в ресторанах тільки кухарі та офіціанти можуть проходити на кухню, яка є закритою зоною. У той же час столова кімната відкрита для вільного доступу відвідувачів і в ній можуть знаходитися будь-які особи. Подібним чином деякий код закритий для інших класів.
В одному з розділів цієї книги ми вже розглядали приклад з закритими і відкритими полями. Давайте доповнимо наш приклад і включимо закриті (Private) і відкриті (Public) методи в клас «Animal» і потім намагаємося звернутися до них з класу «Zoo».
class Animal
{
public string kindOfAnimal;
public string name;
public int numberOfLegs;
public int height;
public int length;
public string color;
bool hasTail;
protected bool isMammal;
private bool spellingCorrect;
public string GetFoodInfo ()
/ / Відкритий метод, який отримує інформацію про те, чим харчується тварина
{
/ / Уявімо, що тут розташований код, який виконує пошук по базі даних
...
}
private void SpellingCorrect ()
/ / Закритий метод для перевірки правильності написання виду тварини
{
/ / Уявімо, що тут розташований код для перевірки правопису
...
}
protected bool IsValidAnimalType ()
/ / Захищений метод, який приймає рішення про існування зазначеного виду тварини
{
/ / Уявімо, що тут розташований код для перевірки існуючих видів тварин
...
}
...
}
class Zoo
{
Animal a = new Animal ();
a.name = "Kangaroo";
string food;
bool animalExists;
/ / Наступний код буде виконано успішно, оскільки класу «Zoo» дозволено
/ / Звертатися до відкритих методів у класі «Animal»
food = a.GetFoodInfo (); / / Виклик відкритого методу
/ / Обидві наступні рядки НЕ будуть виконані, оскільки класу «Zoo»
/ / Не дозволено звертатися до закритих або захищених методів
a.spellingCorrect (); / / спроба виклику закритого методу
animalExists = a.IsValidAnimalType (); / / спроба виклику захищеного методу
}
Дуже часто вам будуть зустрічатися класи з досить специфічним типом методу який називають «конструктором». Ім'я методу-конструктора відповідає імені класу і тип повернення в нього не включається.
Даний метод називається конструктором, оскільки він допомагає «конструювати» або будувати об'єкт при першому його створенні. Створення цього методу в класах вважається хорошою практикою.
class Person
{
/ / Поля
string firstName;
string lastName;
/ / Метод-конструктор для класу Person
public Person ()
{
firstName = "Johnny";
lastName = "Rocket";
}
}
Метод-конструктор обробляється по-особливому: він виконується автоматично при кожному створенні екземпляра класу.
Нагадування:
Під «екземпляром класу» ми розуміємо певний об'єкт класу. Наприклад, в одному з попередніх розділів по об'єктах ми виділили «Горила Джеремі» як певний об'єкт або екземпляр класу «Animal».
Отже, якщо ми виконаємо наступний код ...
Person p = new Person ();
Console.WriteLine (p.lastName);
то результатом буде слово «Rocket» на екрані. Створивши об'єкт «Person» ми автоматично і непомітно виконали метод конструктора «Person», який в цьому випадку задає значення «Rocket» для lastName.
Наведемо аналогічний приклад з реального життя. У деяких країнах при народженні дитини його реєструють згідно закону перш ніж він покине лікарню, щоб він міг відразу прийняти участь у житті суспільства.
Цю дію можна порівняти з методом-конструктором, що виконується для класу. Перш ніж новий екземпляр класу зможе щось зробити, виконується метод-конструктор. У нього можна включити будь-які дії, які повинні виконуватися автоматично, перш ніж об'єкт буде вважатися «готовим до життя».
Конструктори з параметрами
У метод-конструктор можна включити параметри. Наведемо приклад класу з двома різними методами-конструкторами:
class Person
{
/ / Поля
string firstName;
string lastName;
/ / Перший метод-конструктор
public Person ()
{
firstName = "Johnny";
lastName = "Rocket";
}
/ / Другий метод-конструктор
public Person (string f, string l)
{
this.firstName = f;
this.lastName = l;
}
}
І тепер у нас є два різні способи конструювання об'єкту:
Наприклад, цей:
Person p = new Person ();
І в поле p.lastName буде автоматично підставлено значення «Rocket».
Або ж цей:
Person p = new Person ("Jiminy", "Cricket");
І в поле p.lastName буде підставлено значення «Cricket».
Пам'ятайте, що слово «this» відноситься до «того об'єкту, який ми створюємо». Тобто, фактично говориться «підставляти в поля імені і прізвища цього нового об'єкта будь-які значення, передані методу-конструктору».
У реальному світі події відбуваються безперервно. Деякі події не залежать від нас. Наприклад, схід та захід сонця (хотів би я подивитися, як ви намагаєтеся примусити сонце вставати і сідати). Інші події можуть викликатися нами, скажімо, ми можемо змусити гучномовець видавати звуки.
комп'ютерному світі в основному зустрічаються такі події:
Натискання кнопки на екрані монітора
Закінчення часу таймера
Переміщення миші
Натискання клавіші на клавіатурі
Очевидно, що натисканням кнопки ми хочемо змусити комп'ютер виконати певну дію, якщо ні, то навіщо взагалі вона нам потрібна. Але комп'ютер чекає, що ви скажете йому, що натискання цієї кнопки має значення для вас, а також вкажіть дію, яку потрібно виконати при цьому.
Давайте розглянемо приклад з натисканням кнопки, оскільки це, можливо, найбільш поширене подія, і детально розберемо порядок роботи. Припустимо, у вашій програмі є об'єкт кнопки з ім'ям mrButton і словами «Click me» на неї. Навіть знаєте що, спробуйте робити все самі по ходу обговорення. Для початку:
Щоб запустити Visual C # Express в меню «Пуск» вкажіть «Усі програми» і потім «Microsoft Visual C # 2005 Express Edition».
Створіть новий проект програми Windows: У меню File («Файл») виберіть Create project («Створити проект») і виберіть тип проекту Windows Application («Додаток Windows»).
У Visual C # Express відкриється декілька файлів з «кодом-скелетом» програми.
У вікні браузера рішень справа (де перераховані всі файли) видаліть файл з ім'ям Form1.cs.
Двічі клацніть ім'я файлу Program.cs і видаліть весь автоматично вставлений «скелет» коду.
Щоб створити програму з примірником кнопки наберіть наступний код у вікні Program.cs в точності так, як показано нижче (написання слів курсивом або жирним шрифтом можна опустити)
using System;
using System.Windows.Forms;
class MyButtonClass: Form
{
private Button mrButton;
/ / Метод-конструктор
public MyButtonClass ()
{
mrButton = new Button ();
mrButton.Text = "Click me";
this.Controls.Add (mrButton);
}
/ / Основний метод
static void Main ()
{
Application.Run (new MyButtonClass ());
}
}
Виконайте програму за допомогою клавіші F5 на клавіатурі (або клацніть зелену кнопку «Виконати»). Якщо виникнуть повідомлення про помилки, ретельно перевірте код на предмет помилок. Якщо програма буде виконана успішно, то ви повинні побачити форму з кнопкою «Click me». Поки при натисканні на кнопку ніяких дій відбуватися не буде. Зовсім не те, що ви чекали, я знаю, але ми прийдемо і до цього.
Подія натискання кнопки
Вказівка дії у разі події
Тепер, коли нам відомо, що потрібно зробити при натисненні на кнопку, ми повинні вказати метод, за яким буде виконуватися дія. Типи методів, які повідомляють комп'ютера про дії у разі подій називаються методами обробника подій, оскільки вони «обробляють» подію. У наведеному нижче прикладі виділений жирним код просто змінює напис на кнопці, тому він зовсім короткий.
using System;
using System.Windows.Forms;
class MyButtonClass: Form
{
private Button mrButton;
/ / Метод-конструктор
public MyButtonClass ()
{
mrButton = new Button ();
mrButton.Text = "Click me";
this.Controls.Add (mrButton);
}
/ / Основний метод
static void Main ()
{
Application.Run (new MyButtonClass ());
}
/ / Метод обробника подій
void MyButtonClickEventHandler (object sender, EventArgs e)
{
mrButton.Text = "You clicked me!";
}
}
Програма, як і раніше виконується?
Зупиніть її (натисніть кнопку X у верхньому правому куті вікна, в якому відкрита форма)
Додайте виділений жирним код у вашу програму і натисніть клавішу F5 для виконання зміненої програми.
Спробуйте тепер натиснути кнопку «Click me» Бррр! І тепер нічого?
Якщо ви прочитали главу про методи, то дізнаєтеся основну структуру наведеного вище методу. Слово «void» означає, що по завершенні методу нічого не повертається. Словом «MyButtonClickEventHandler» ми назвали цей метод.
Тоді все стає трохи дивним. Можливо ви зрозумієте, що в дужках присутній два параметри, але вони не підходять: (object sender, EventArgs e). Мені не хотілося б повідомляти вам такі неприємні новини, але з методами обробників подій не можна використовувати власні типи параметрів. При виклику такого методу система сама автоматично підставляє певні параметри і нічого з цим вдіяти ми не зможемо.
Тому доведеться просто змиритися і завжди використовувати очікувані типи параметрів з обробником подій. У випадку з подією натискання на кнопку і багатьма іншими, підставляються параметри мають тип «object» і «EventArgs». У наведеному вище прикладі ми вибрали імена параметрів «sender» і «e», але ми могли б вибрати будь-які імена - для комп'ютера важливі імена типів цих параметрів. Наприклад, наступний код буде працювати в точності так само, як і код в прикладі вище. Якщо хочете, можете самі перевірити це, змінивши імена параметрів у вашій програмі на «x» і «y».
void MyButtonClickEventHandler (object x, EventArgs y)
{
mrButton.Text = "You clicked me!";
}
У першому параметрі зазвичай міститься деяка інформація про об'єкт, що ініціював подію. Другий параметр відноситься до даних про саму подію.
Також слід знати наступне - незважаючи на те, що системою завжди підставляються деякі значення в ці два параметри, часто не буде необхідності в їх використанні - вони відправляються в метод обробника подій «на всякий випадок».
Підключення методу обробника подій до події
Ви дивуєтеся чому нічого не відбувається при натисканні на кнопку? Справа в тому, що вказаний метод викликається тільки тоді, коли ми зв'яжемо з ним подію натискання на кнопку. У програмі потрібно вказати, що при натисканні на кнопку необхідно перейти до певного обробника подій.
Це абсолютно очевидно, коли в програмі використовуються різні кнопки і кілька обробників подій. Звідки комп'ютера буде відомо, який метод виконувати при натисканні на кожну кнопку?
Код для зв'язування події об'єкта з методом обробника події виглядає теж трохи дивно. І ми знову виділимо його жирним.
using System;
using System.Windows.Forms;
class MyButtonClass: Form
{
private Button mrButton;
/ / Метод-конструктор
public MyButtonClass ()
{
mrButton = new Button ();
mrButton.Text = "Click me";
mrButton.Click + = new System.EventHandler (MyButtonClickEventHandler);
this.Controls.Add (mrButton);
}
/ / Основний метод
static void Main ()
{
Application.Run (new MyButtonClass ());
}
/ / Метод обробника подій
void MyButtonClickEventHandler (object sender, EventArgs e)
{
mrButton.Text = "You clicked me!";
}
}
З комп'ютерної на нашу мову це можна перекласти наступним чином:
До події натискання на кнопку додати новий метод обробника подій, який називається MyButtonClickEventHandler.
Отже, при натисненні на кнопку, наведена вище рядок коду направляє програму до методу обробника подій. При його виконанні напис на кнопці змінюється на «You clicked me!»
Щоб спробувати цей код, зупиніть свою програму, додайте в неї виділений жирним код (у відповідне місце) і натисніть клавішу F5 для виконання програми. Натисніть на кнопку і її напис зміниться. Робочу програму - приклад події натискання на кнопку можна знайти в папці прикладів до цієї книги (Програма 5).
У цьому розділі ми опишемо основну структуру методу обробника подій миші. Ймовірно, в цьому випадку ви захочете використовувати інформацію, що підставляється в параметр MouseEventArgs, щоб з'ясувати, наприклад, яка з кнопок миші натискається.
public void TheMouseIsDown (object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
this.Text = "Натиснута ліва кнопка миші";
}
}
А далі показано як подію можна пов'язати з методом. У цьому прикладі йдеться: «Якщо при виконанні цієї програми натискається кнопка миші, перейти до методу TheMouseIsDown», якому відомо як обробляти події миші:
this.MouseDown + = new MouseEventHandler (TheMouseIsDown);
Можна зробити навіть ще трохи краще. Коли ініціюється наступний обробник, код, написаний в ньому, робить вікно ширше або вже залежно від натискаємо кнопки.
public void TheMouseWasClicked(object sender, MouseEventArgs e)
{
/ / При натисненні лівої кнопки
if (e.Button == MouseButtons.Left)
{
/ / Розширення поточного вікна
this.Width = this.Width + 100;
}
else if (e.Button == MouseButtons.Right)
{
/ / Звуження поточного вікна
this.Width = this.Width - 100;
}
}
Наступний обробник подій дозволяє виявити переміщення миші і малювати коло в тому місці, де знаходиться курсор:
public void TheMouseMoved (object sender, MouseEventArgs e)
{
/ / Підготовка області малювання
System.Drawing.Graphics g = this.CreateGraphics ();
/ / Використання червоної ручки
System.Drawing.Pen redPen = new System.Drawing.Pen (Color.Red, 3);
/ / Малюємо коло (еліпс, точки якого рівновіддалені від центру)
/ / Лівий верхній кут квадрата має координати X і Y поточного положення миші
g.DrawEllipse (redPen, e.X, e.Y, 40, 40);
/ / Очищення
g.Dispose ();
}
На наступному знімку екрана показано як це виглядає при переміщенні миші:
Простори імен та Поштова служба
У світі існують сотні, якщо не тисячі вулиць імені Леніна. Яким чином лист, відправлений на адресу по вулиці Леніна знаходить свого одержувача? Природно, адреса складається не тільки з вулиці. Ми, як правило, щонайменше, додаємо назву міста і назва країни.
Очевидно, якщо ми напишемо:
Вулиця ім. Леніна, 17
Вулиця ім. Леніна, 82
то не буде різниці між цими вулицями і листоноша буде жахливо розчарований.
Замість цього можна було б написати так:
Вулиця ім. Леніна, 17. м. Москва
Вулиця ім. Леніна, 82. м. Алмати.
Так-то краще, але що якщо буде два міста з назвою Москва! Тоді краще всього додати ще й назву країни.
Вулиця ім. Леніна, 17. м. Москва. Російська Федерація.
Вулиця ім. Леніна, 82. м. Алмати. Республіка Казахстан.
Адреса з таким же успіхом можна написати і навпаки:
Російська Федерація. м. Москва. Вулиця ім. Леніна, 17.
Республіка Казахстан. м. Алмати. Вулиця ім. Леніна, 82
Тепер лист повинен дійти до адресата без проблем. Наприклад, у другому прикладі, лист доставлять до Республіки Казахстан. Потім з аеропорту його відправлять у місто Алмати. А потім листоноша піде на вулицю ім. Леніна і знайде будинок під номером 82.
Формат [Республіка Казахстан.Алмати.вул. ім. Леніна] можна вважати «простором імен» для повідомлень.
Простори імен та програмний код
Так яке відношення все це має до програмування?
Припустимо, що розробниками корпорації Microsoft написаний клас «Point», який використовується для малювання фігури в певній точці, але ви також створили клас під назвою «Point», наприклад для завантаження фотографії людини, що вказує на що-небудь.
Очевидно, що ці два класи виконують абсолютно різні дії, але обидва їх можна назвати «Point». Звідки програма буде знати з яким класом працювати?
Безумовно, має сенс якось використовувати різні імена. У середовищі. NET для цього можна використовувати різні простори імен. Наприклад, так:
Microsoft.Drawing.Point
Susy.PictureStuff.Point
Імена класів збережені («Point»), але «простір імен» перед ім'ям класу дозволяє чітко бачити, де який клас. І тепер, якщо мені потрібно використовувати клас Point для Susy, я міг би створити об'єкт Point за допомогою наступного методу-конструктора:
Susy.PictureStuff.Point SusyPoint = new Susy.PictureStuff.Point ();
А для роботи з класом Point від Microsoft я б використав наступний код:
Microsoft.Drawing.Point MicrosoftPoint = new Microsoft.Drawing.Point ();
Незважаючи на те, що обидва мої об'єкти мають один тип класу «Point», вони виконують різні дії.
Присвоєння простору імен власному класу
Розміщення власного класу в простір імен вкрай просто. Замість того, щоб писати клас наступним чином:
class Animal
{
...
}
включіть його в наступний код:
namespace Susy
{
class Animal
{
...
}
}
або зробіть так, якщо хочете:
namespace Susy.FunStuff
{
class Animal
{
...
}
}
Можна створити будь-який простір імен, який, як вам здається, має сенс. Просто розділяйте свої слова крапкою (.).
В останньому наведеному прикладі, клас Animal тепер входить у простір імен Susy.FunStuff.
Ви також побачите, що всі бібліотеки коду від Microsoft, а також інших організацій, поміщаються в простори імен. Тому щоб використовувати код з таких бібліотек, необхідно розуміти, як працювати з просторами імен.
Примірник або об'єкт наведеного вище класу можна розглядати за допомогою методу-конструктора класу наступним чином:
Або, якщо б нам потрібно було використовувати багато об'єктів з одного простору імен, і при цьому не хотілося б кожного разу писати «Charles.SchoolUtilities», то ми могли б вжити ключове слово «using» на початку програми, щоб повідомити комп'ютера, що в надалі будемо застосовувати цей простір імен. Наприклад:
/ / Говоримо комп'ютера, що будемо використовувати класи з цього простору імен
using Charles.SchoolUtilities;
/ / Створення об'єкта Animal з простору імен Charles.SchoolUtilities
Animal cat = new Animal ();
Будівельний блок: Простору імен
Для логічного об'єднання подібних класів і їх розрізнення рекомендується завжди поміщати клас на значемий простір імен.
namespace Charles.SchoolUtilities { class Animal { } }
Charles.SchoolUtilities.Animalcat = new Charles.SchoolUtilities.Animal();
Оскільки метою книги є тільки знайомство з програмуванням, ми не станемо розглядати занадто складні речі, тому не розповімо багато чого про спадкування.
Однак, оскільки іноді вам буде зустрічатися оголошення класів наступного вигляду
class MyFancyClass: Form
{
...
}
замість цього
class MyFancyClass
{
...
}
ми повинні дати пояснення з частини коду, що починається з двокрапки (:).
Спадкування серед людей
Людина, як правило, успадковує певні якості від своїх батьків. У вас може бути колір волосся мами, а ніс - тата.
Хоча це не означає, що ви повністю схожі на свою матір чи батька, але певні якості «закладені» в вас при народженні. Ви також будете володіти різними унікальними якостями і здібностями крім тих, які отримали від батьків.
Спадкування коду
При написанні програмного коду було б також корисним мати можливість наслідування всього набору здібностей існуючого класу, будь то власний клас або чийсь ще.
Наведемо приклад. Ми визначили два класи - «Animal» і «Bird», і клас «Bird» успадковує ознаки класу «Animal».
class Animal
{
public string kindOfAnimal;
public string name;
public int numberOfLegs;
public int height;
public int length;
public string color;
bool hasTail;
protected bool isMammal;
private bool spellingCorrect;
...
}
class Bird: Animal / / Клас «Bird» успадковує від класу «Animal»
{
public string featherColor;
...
}
У реальному світі птах - це вид тварини, але деякі ознаки птахів не відповідають ознакам всіх тварин. Тоді має сенс класу Bird переймати всі ознаки класу Animal і мати ряд додаткових ознак. У цьому випадку ми визначили одне спеціальне поле тільки для птахів - featherColor.
Отже, коли ми пишемо
class Bird: Animal
{
...
}
ми фактично кажемо: «Я визначаю новий клас" Bird ", але він повинен автоматично успадковувати всі властивості класу «Animal». Часто кажуть, що клас «Bird» є похідним від класу «Animal».
При створенні екземпляра «Bird» ми можемо тут же звертатися до полів як класу «Animal», так і «Bird» (якщо вони не є закритими):
Bird b = new Bird ();
b.kindOfAnimal = "Tawny Eagle";
b.isMammal = false;
b.featherColor = "Tawny";
Щоб було зрозуміло, ми виключили методи в класах «Animal» і «Bird» у прикладі вище, але для них діє те ж правило. Похідний клас може викликати будь-які методи в батьківському класі, якщо вони не оголошені закритими.
Інший приклад - Спадкування деяких можливостей роботи з вікнами в вашій програмі.
Припустимо, вам потрібно написати програму, що виконується в звичайному вікні. Вам необхідні можливості зміни розміру, розгортання, звертаючи, перетягування вікна і деякі інші. Має сенс, щоб ваш клас «успадковував» можливості класу, який вже працює з подібним типом інтерфейсу. Звичайним вибором стає клас System.Windows.Forms.Form.
Отже, коли ми пишемо
class MyFancyClass: Form
{
...
}
ми фактично кажемо: «Я пишу власний клас, але він повинен автоматично успадковувати всі можливості класу« Form ».
Розглянуті в цьому розділі питання розбираються на практиці у Розділі III по System.Windows.Forms.
Коли слід використовувати спадкування
Для використання класу зовсім не обов'язково успадковувати від нього поля! Спадкування найкраще працює в тих випадках, коли те, чого ви намагаєтеся домогтися, можна отримати від існуючого класу, і хочеться розширити або налаштувати його.
Будівельний блок: Спадкування
Клас можна змусити успадковувати ознаки і здатності іншого класу.
У наступному прикладі клас «Guitarist» успадковує три поля з класу «Musician» і має два власні поля.
Двокрапка (:) говорить комп'ютера, що потрібно змусити новий клас (Guitarist) успадковувати поля класу, написаного праворуч від двокрапки.
public class Musician { public string name; public int age; public bool canSing; } public class Guitarist : Musician { public string guitarType; public string guitarBrand; } Guitarist g = new Guitarist(); g.name = "Jimbo van Helsdingen"; g.ageInYears = 28; g.canSing = false; g.guitarType = ”Acoustic”; g.guitarBrand = ”Gibson”;