ZpětObsahDalší

Objective C: příklad 6
Skládání objektů a dynamické rozpoznání zpráv II


Šestý příklad se trochu podobá pátému příkladu; tentokrát si však ukážeme mechanismus, který jednoznačně možnosti vícenásobné dědičnosti přesahuje: připravíme totiž objekt, který bude reprezentovat objekt kterékoli z předem dané skupiny tříd podle potřeby (ale ne všechny najednou).

// Objective C -- příklad 6
//
// ukázka skládání objektů a dynamického rozpoznávání zpráv
// pro služby přesahující možnosti vícenásobné dědičnosti
// -- objekt s dynamicky měnitelnou třídou
// (tento příklad není úplným programem)

// importujeme interface všech tříd, po kterých chceme dědit
#import "Class_1.h"
...
#import "Class_N.h"

@interface DynamicClass: NSObject @end

@implementation DynamicClass
-(void)forwardInvocation:(NSInvocation*)inv
{
  SEL msg=[inv selector];

  // vyhledáme třídu, jejíž objekty danou zprávu umějí,
  // objekt vytvoříme a použijeme:
  if ([Class_1 instancesRespondToSelector:msg])
    [
inv invokeWithTarget:[Class_1 class1]];
  ...
  if ([Class_N instancesRespondToSelector:msg])
    [inv invokeWithTarget:[Class_N classN]];
  // žádná z tříd jež máme k dispozici zprávu nemůže zpracovat ...
  // mohli bychom třeba ohlásit chybu, nebo zprávu ignorovat:
}
@end
// end of file

1. Interface

Žádné proměnné, žádné vlastní metody -- o mnoho jednodušší už to být nemůže...

Vzhledem k tomu, že nemáme žádné properties, samozřejmě není ani zapotřebí reimplementovat metody init a dealloc.

2. Dynamické rozpoznání zpráv

Pro dynamické rozpoznání zpráv samozřejmě opět použijeme zprávu forwardInvocation:. Její implementace je tentokrát nepatrně složitější: projdeme všechny třídy; každé z nich se optáme pomocí standardní metody instancesRespondToSelector: zda její objekty jsou schopny zpracovat zadanou zprávu. Jakmile narazíme na třídu u které je tomu tak, vytvoříme její objekt a zprávu mu přesměrujeme.

Za povšimnutí stojí i to, že adresu nově vytvořeného objektu nikam neukládáme: jak to potom bude s jeho zánikem, nemáme zaděláno na memory leak? Nemáme! Garbage collector Foundation Kitu se o to postará: protože jsme při vytvoření objektu nezaslali zprávu retain, odstraní jej garbage collector automaticky jakmile jej už nikdo jiný nebude potřebovat.

Seznam tříd je v tomto případě pro zjednodušení příkladu statický; vzhledem k tomu, že třída je v Objective C objekt jako každý jiný, bychom mohli snadno implementovat dynamický seznam tříd, který by se mohl měnit v průběhu života objektu... zkuste něco podobného v C++!


ZpětObsahDalší

Copyright (c) Chip, O. Čada 2000