- •Лекція 1 Вступ. Огляд парадигм та платформ для Web-розробки. Платформа asp.Net. Інструменти та інтегроване середовище розробки Visual Web Developer 2010.
- •1.1 Вступ. Поняття Інтернет. Базові концепції Всесвітньої павутини www. Еволюція Web
- •1.1.1 Поняття Інтернет
- •1.1.2 Базові концепції Всесвітньої павутини www
- •1.1.3 Еволюція Web
- •1.2 Огляд парадигм та платформ для Web-розробки
- •1.2.2 Найбільш поширені мови та технології розробки
- •1.3 Платформа asp.Net
- •1.3.1 Розвиток asp.Net
- •1.3.2 Ключові переваги asp.Net mvc
- •1.4 Інструменти та інтегроване середовище розробки Visual Web Developer 2010
- •1.4.3 Додаткові компоненти
- •1.4.4 Отримання допоміжної інформації від розробників
- •1 Анатомія html-документа
- •2 Текст
- •3 Гіперпосилання
- •4 Форматовані списки
- •5 Таблиці
- •6 Каскадні таблиці стилів
- •Лекція 3 Синтаксичні конструкції мови c#.
- •3.1Зв’язок між c# I .Net. Особливості платформи .Net
- •3.1.1 Загальномовне виконуюче середовище
- •3.1.2 Класи .Net Framework
- •3.1.3 Простори імен .Net
- •3.2Синтаксичні особливості c#
- •3.2.2 Визначені типи даних
- •3.2.3 Керування потоком виконання
- •3.2.4 Перерахування
- •3.2.5 Простори імен
- •3.2.6 Метод Main (). Консольний ввід-вивід. Коментарі.
- •3.3Об’єкти і типи
- •3.3.1 Класи
- •3.3.2 Структури
- •3.4Наслідування
- •3.4.1 Типи наслідування
- •3.4.2 Модифікатори доступу
- •3.4.3 Інтерфейси
- •3.5Узагальнення
- •3.6Операції
- •1 Колекції
- •2 Делегати
- •Лекція №5 Елементи керування на сторінках asp.Net
- •1. Структура web-додатку на основі asp.Net
- •2. Керування станом в asp.Net
- •3. Серверні елементи керування на сторінках asp.Net
- •3.1 Серверні веб-елементи управління
- •4. Сценарії обробки запитів
- •5. Життєвий цикл сторінки asp.Net
3.3.2 Структури
Іноді з міркувань продуктивності є сенс віддати перевагу структурі. Як згадувалося раніше, єдине, що слід змінити в коді, щоб зробити тип структурою замість класу - просто замінити ключове слово class на struct:
struct Dimensions
{
public double Length;
public double Width;
}
Визначення функцій для структур виглядає точно так само, як визначення функцій для класів.
struct Dimensions
{
public double Length;
public double Width;
Dimensions(double length, double width)
{
Length=length;
Width=width;
}
public int Diagonal
{
get
{
return Math.Sqrt(Length*Length + Width*Width);
}
}
}
Структури - це типи значень, а не типи посилань. Це означає, що вони або зберігаються в стеку, або є вбудованими (останнє - якщо вони є частиною іншого об'єкта, що зберігається в купі), і мають ті ж обмеження часу життя, що і прості типи даних.
Структури не підтримують наслідування.
Є деяка відмінність у роботі конструкторів структур. Зокрема, компілятор завжди генерує конструктор по замовчуванню без параметрів, який перевизначити неможливо.
Для структур можна вказувати те, як поля розміщуються в пам'яті.
Оскільки структури насправді призначені для групування даних, в більшості випадків всі їх поля оголошуються загальнодоступними. Структури слідують тим же правилам, що і всі інші типи даних: перед використанням всі поля повинні бути ініціалізовані. Структура розглядається як повністю ініціалізована, коли для її створення була викликана операція new або ж коли всім її полях індивідуально були привласнені значення. І, звичайно ж, структура, якщо вона виступає як поле класу, ініціалізується автоматичним обнуленням при ініціалізації об'єкта, що її включає.
Структури не призначені для наслідування. Тобто успадковувати від структури не можна. Єдиний виняток полягає в тому, що структури, як і всі інші типи в С #, зрештою успадковуються від класу System.Object. Тому структури мають доступ до методів класу System.Object і навіть можуть перевизначати їх.
Оголошувати конструктори структур можна точно так само, як це робиться для класів, за винятком того, що не дозволено визначати конструктори без параметрів. Таким чином, конструктор за замовчуванням, який ініціалізує всі поля нульовими значеннями, завжди присутній неявно, навіть якщо застосовуються інші конструктори з параметрами.
3.4Наслідування
3.4.1 Типи наслідування
В об'єктно-орієнтованому програмуванні (ООП) існують два різних типу наслідування: наслідування реалізації танаслідування інтерфейсу.
Наслідування реалізації (implementation inheritance) означає, що тип походить від базового типу, отримуючи від ньоговсі поля-члени та функції-члени. При наслідування реалізації похідний тип адаптує реалізацію кожної функціїбазового типу, якщо тільки в його визначенні не вказано, що реалізацію функції повинна бути перевизначено. Такийтип наслідування більш корисний, коли потрібно додати функціональність до існуючого типу або ж коли кількапов'язаних типів поділяють істотний обсяг загальної функціональності.
Наслідування інтерфейсу (interface inheritance) означає, що тип наслідує тільки сигнатуру функцій, але не успадковує ніякої реалізації. Цей тип наслідування найбільш корисний, коли потрібно специфікувати, що тип забезпечує доступ до певних засобів.
У С # підтримується як наслідування реалізації, так і наслідування інтерфейсу. Обидва типи наслідування повністю вбудовані в мову з самого початку, дозволяючи приймати рішення про те, який з них використовувати, на основі архітектури додатку.
В С # множинне наслідування не підтримується, тобто клас наслідується не більш, ніж від одного базового класу. Однак можна сказати точніше: завдяки наявності System.Object як загального базового типу, кожен клас С # (за винятком Object) має строго один базовий клас
С # дозволяє наслідувати безліч інтерфейсів. Це означає, що клас С # може наслідуватися від іншого класу і будь-якої кількості інтерфейсів.
Одним з обмежень, що накладаються на структури, є те, що вони не підтримують наслідування, незважаючи на той факт, що кожна структура автоматично наслідується від System.ValueType. Іншими словами, структури не підтримують наслідування реалізації, але підтримують наслідування інтерфейсу. Таким чином, підсумувати ситуацію з користувацькими типами можна наступним чином:
Структури завжди наслідуються від System. ValueType. Вони можуть також наслідувати будь-яку кількість інтерфейсів.
Класи завжди наслідуються від одного класу за вашим вибором. Вони також можуть наслідувати будь-яку кількість інтерфейсів.
Наслідування реалізації
Для оголошення, що клас наслідується від іншого класу, застосовується наступний синтаксис:
class НаслідуванийКлас: БазовийКлас
{
//Дані-члени та функції-члени
}
Якщо клас також наслідує інтерфейси, то список базового класу і інтерфейсів розділяється комами:
public class MyDerivedClass: MyBaseClass, Ilnterfacel, IInterface2
{
//і т.д.
}
Для оголошення наслідування інтерфейсів для структур, синтаксис буде такий же, тільки замість слова classвказується struct.
Якщо при визначенні класу базовий клас не зазначений, то компілятор С# припускає, що базовим класом є System.Object.
Віртуальні методи
Щоб дозволити перевизначати функцію в класах-наслідниках, її потрібно оголосити як virtual:
class MyBaseClass
{
public virtual string VirtualMethod ()
{
return "Це - віртуальний метод, визначений у MyBaseClass";
}
}
Також допускається оголошення властивості як virtual. Для віртуальної або перевизначеної властивості використовується такий же синтаксис, що і для невіртуальної властивості, за винятком ключового слова virtual, яке додається до визначення.
C# вимагає явного оголошення, коли функція класу-наслідника перевизначає іншу функцію, за допомогою ключового слова override:
class MyDerivedClass: MyBaseClass
{
public override string VirtualMethod ()
{
return "Цей перевизначений метод оголошений в MyDerivedClass";
}
}
Ні поля-члени, ні статичні функції не можуть бути оголошені віртуальними. Ця концепція просто не має сенсу ні для яких членів класу, за винятком функцій-членів рівня екземпляра.
Якщо методи з однаковою сигнатурою оголошені і в базовому, і в успадкованому класі, але при цьому не вказані, відповідно, як virtual і override, то говорять, що версія методу в класі-насліднику приховує версію методу базового класу. У більшості випадків потрібно перевизначати методи, а не приховувати їх. Приховуючи методи, є ризик викликати "невірний" метод для екземпляра даного класу.
У С # передбачений спеціальний синтаксис виклику базових версій методу з похідного класу: base.<ІмяМетоду>(). Синтаксис base.<ІмяМетоду>() можна використовувати для виклику будь-якого методу базового класу, не обов'язково викликати його тільки для перевизначеної версії того ж методу.
Абстрактні класи та функції
Мова С # дозволяє оголошувати абстрактними і класи, і функції. Створювати екземпляри абстрактних класів не можна, оскільки абстрактні функції не мають реалізації і повинні бути перевизначені в будь-якому неабстрактному класі-насліднику. Очевидно, що абстрактні функції автоматично є віртуальними (хоча не можна застосовувати ключове слово virtual, так як це призведе до синтаксичної помилку). Якщо будь-який клас містить будь-яку абстрактну функцію, цей клас сам є абстрактним і повинен бути оголошений таким:
abstract class Building
{
public abstract decimal CalculateHeatingCost (); / / абстрактний метод
}
Запечатані класи і методи
С # дозволяє оголошувати класи і методи як sealed (запечатані). У разі класу це означає, що наслідувати від нього не можна. У випадку методу це означає неможливість його перевизначення.
sealed class FinalClass
{
//і т.д.
}
class DerivedClass: FinalClass//Невірно. Помилка компіляції.
{
//і т.д.
}
Найбільш ймовірна ситуація, коли може знадобитися помітити клас або метод як sealed - це коли клас або метод забезпечує внутрішні дії бібліотеки, класу або інших розроблюваних класів, і є впевненість, що будь-яка спроба перевизначити деяку його функціональність призведе до нестабільності коду. Для того щоб можна було застосувати ключове слово sealed до методу або властивості, вони повинні бути спочатку перевизначені по відношенню до базового класу.
Конструктори похідних класів
При створенні екземпляру похідного класу працює більше одного конструктора. Конструктора класу, екземпляр якого створюється, недостатньо для повної ініціалізації - також повинні бути викликані конструктори всіх його базових класів. Припускаючи наскрізне використання конструкторів за замовчуванням, компілятор спочатку вибирає конструктор того класу, екземпляр якого він намагається створити. Перше, що робить конструктор екземпляру похідного класу - намагається викликати конструктор свого безпосереднього базового класу. Потім конструктор безпосереднього базового класу намагається викликати конструктор свого базового класу, і так аж до класу System.Object. Клас System.Object не має базового класу, тому його конструктор просто виконується і повертає керування конструктору, що його викликав. Цей конструктор виконується і, перш ніж повернути управління конструктору свого похідного класу, що його викликав, ініціалізує свої значення. У свою чергу, конструктор похідного класу виконується, ініціалізувавши свої значення, і так до самого низу по їєрархії.
До цього моменту екземпляр успішно сконструйований і ініціалізований. В цьому процесі кожен конструктор ініціалізує поля власного класу. Завжди є конструктор базового класу, який викликається першим. Це означає, що немає проблем для конструктора базового класу викликати будь-які методи, властивості і звернутися до будь-яким іншим членам базового класу, до яких йому відкритий доступ, оскільки базовий клас вже сконструйований і його поля ініціалізовані. Крім того, це означає, що якщо класу-наслідника "не подобається" те, як ініціалізований базовий клас, він може змінити початкові значення даних, до яких у нього є доступ. Ключові слова base і this - єдині ключові слова, які допускаються в цьому рядку для виклику іншого конструктора.
