русс | укр

Мови програмуванняВідео уроки php mysqlПаскальСіАсемблерJavaMatlabPhpHtmlJavaScriptCSSC#DelphiТурбо Пролог

Компьютерные сетиСистемное программное обеспечениеИнформационные технологииПрограммирование


Linux Unix Алгоритмічні мови Архітектура мікроконтролерів Введення в розробку розподілених інформаційних систем Дискретна математика Інформаційне обслуговування користувачів Інформація та моделювання в управлінні виробництвом Комп'ютерна графіка Лекції


Перетворення вказівних типів (розширення та звуження)


Дата додавання: 2014-05-29; переглядів: 1171.


Переходимо до вказівнихтипів. Перетворення об'єктних типів найкраще ілюструється за допомогою дерева наслідування. Розглянемо невеликий приклад наслідування:

 

// Оголошуємо клас Parent

class Parent {

int x;

}

// Оголошуємо клас Child і успадковуємо

// Його від класу Parent

class Child extends Parent {

int y;

}

// Оголошуємо іншого спадкоємця

// Класу Parent - клас Child2

class Child2 extends Parent {

int z;

}

 

В класі оголошено поле з унікальним ім'ям. Будемо розглядати це поле як приклад набору унікальних властивостей, притаманних деякого об'єктному типу.

Три оголошених класи можуть породжувати три види об'єктів. Об'єкти класу Parent володіють тільки одним полем x, а значити, тільки вказівники типу Parent можуть посилатися на такі об'єкти. Об'єкти класу Child володіють полем y і полем x, отриманим у спадок від класу Parent. Стало бути, на такі об'єкти можуть вказувати вказівник типу Child або Parent. Другий випадок вже ілюструвався таким прикладом:

 

Parent p = new Child ();

 

Зверніть увагу, що за допомогою такого вказівника p можна звертатися лише до поля x створеного об'єкту. Поле y недоступні, тому що компілятор, перевіряючи коректність висловлювання p.y, не можна передбачити, що посилання p буде вказувати на об'єкт типу Child під година виконання програми. Він аналізує лише тип самої змінної, а вона оголошена як Parent, алі в цьому класі немає поля y, що й викличе помилку компіляції.

Аналогічно, об'єкти класу Child2 володіють полем z і полем x, отриманим у спадок від класу Parent. Значити, на такі об'єкти можуть вказувати посилання типу Child2 або Parent.

Таким чином, посилання типу Parent можуть вказувати на об'єкт будь-якого з трьох розглянутих типів, а посилання типу Child і Child2 - тільки на об'єкти точно такого ж типу. Тепер можна перейти до перетворення вказівних типів на основі такого дерева наслідування.

Розширення означає перехід від більш конкретного типу до менш конкретного, тобто перехід від дітей до батьків. У нашому прикладі перетворення від будь-якого спадкоємця (Child, Child2) до батьків (Parent) є розширення, перехід до більш загального типу. Подібно до випадку з примітивними типами, цей перехід здійснюється самою JVM при необхідності й непомітно для розробника, тобто не вимагає ніяких додаткових зусиль, оскільки він завжди проходити успішно: завжди можна звертатися до об'єкта, породженому від спадкоємця, за типом його батька.

 

Parent p1 = new Child ();

Parent p2 = new Child2 ();

 

В обох рядках змінним типу Parent присвоюється значення іншого типу, а значити, відбувається перетворення. Оскільки це розширення, воно виконується автоматично й завжди успішно.

Зверніть увагу, що при подібному перетворенні з самим об'єктом нічого не відбувається. Незважаючи на ті, що, наприклад, поле y класу Child тепер недоступні, це не означає, що воно зникло. Така істотна зміна структури об'єкта неможлива. Вона була породжена від класу Child і зберігає всі його властивості. Змінився лише тип посилання, через яку йде звернення до об'єкта. Цю ситуацію можна умовно порівняти з розгляданням якогось предмета через підзорну трубу. Якщо перейти від сурми з великим збільшенням до більш слабкої, те видимих деталей стані менше, алі сам предмет, звичайно, ніяк від цього не зміниться.

Наступні перетворення є розширюючі:

- від класу A до класу B, якщо A успадковується від B (важливим окремим випадком є перетворення від будь-якого посилального типу до Object);

- від null-типу до будь-якого об'єктному типу.

Другий випадок ілюструється таким прикладом:

 

Parent p = null;

 

Порожнє посилання null не має будь-якого конкретного вказівного типу, тому іноді говорять про спеціальний null-тип. Однак на практиці важливо, що таке значення можна прозоро перетворити до будь-якого об'єктному типу.

З вивченням інших вказівних типів (інтерфейсів і масивів) цей список буде розширюватися.

Зворотний перехід, тобто рух по дереву успадкування долілиць, до спадкоємців, є звуженням. Наприклад, для розглянутого випадку, перехід від вказівного типу Parent, який може посилатися на об'єкти трьох класів, до посилання типу Child, яку може посилатися на об'єкти лише одного з трьох класів, мабуть, є звуженням. Такий перехід може виявитися неможливим. Якщо посилання типу Parent посилається на об'єкт типу Parent або Child2, то перехід до Child неможливий, адже в обох випадках об'єкт не має поле y, яку оголошено в класі Child. Тому при звуженні розробнику необхідно явним чином вказувати на ті, що необхідно спробувати провести таке перетворення. JVM під година виконання перевірить коректність переходу. Якщо він можливий, перетворення буде проведено. Якщо ж ні - виникне помилка.

 

Parent p = new Child ();

Child c = (Child) p; // Перетворення буде успішним.

Parent p2 = new Child2 ();

Child c2 = (Child) p2; // Під година виконання виникне помилка!

 

Щоб перевірити, чи можливий бажаний перехід, можна скористатися оператором instanceof:

 

Parent p = new Child ();

if (p instanceof Child) {

Child c = (Child) p;

}

Parent p2 = new Child2 ();

if (p2 instanceof Child) {

Child c = (Child) p2;

}

Parent p3 = new Parent ();

if (p3 instanceof Child) {

Child c = (Child) p3;

}

 

У даному прикладі помилок не виникне. Перше перетворення можливе, і воно буде здійснено. В іншому й третьому випадках умови операторів if не спрацюють і спроб некоректного переходу не буде.

На даний момент можна назвати лише одне звужуюче перетворення: від класу A до класу B, якщо B успадковується від A (важливим окремим випадком є звуження типу Object до будь-якого іншого посилального типу). З вивченням інших документів, які типів (інтерфейсів і масивів) цей список буде розширюватися.


<== попередня лекція | наступна лекція ==>
Види приведення даних | Перетворення до рядку


Онлайн система числення Калькулятор онлайн звичайний Науковий калькулятор онлайн