лекции (2008) (by Kravets) (1160829), страница 21
Текст из файла (страница 21)
Íà òàêèåôóíêöèè íàëîæåíû íåêîòîðûå òðåáîâàíèÿ.Îïðåäåëåíèå, åñëè òèï X ÿâëÿåòñÿ ïðîèçâîäíûì èëè ñîâïàäàåò ñ Y, òîòèï X êîâàðèàíòåí ñ Y.Ó äèíàìè÷åñêè ñâÿçàííûõ ìåòîäîâ äîëæåí áûòü îäèí è òîò æå ïðîôèëü ïàðàìåòðîâ, íî êîâàðèàíòíûå âîçâðàùàåìûå çíà÷åíèÿ. Òî åñòüclass Y{public Y f(){}}class X extends Y{public X f(){}//Okpublic int f(){}//Err} Java âñå ìåòîäû äèíàìè÷åñêè ñâÿçàííûå, â C++, C#, Delphi äëÿýòîãî ñóùåñòâóåò ñïåöèàëüíîå êëþ÷åâîå ñëîâî virtual. Òî åñòü âèðòóàëüíîñòü - ñâîéñòâî ìåòîäà.Åñëè ìåòîä îáúÿâëåí ñ êëþ÷åâûì ñëîâîì virtual, òî îí ñòàíîâèòñÿ äèíàìè÷åñêè ñâÿçàííûì.
Äèíàìè÷åñêîå ñâÿçûâàíèå - ýòî ñâîéñòâî âûçîâà,íî â ÿçûêàõ îíî ïðèâÿçàíî ê ìåòîäó.A→B→C→D→B* pb;pb -> f();Ïóñòü f - ñòàòè÷åñêèé ìåòîä.Ñíà÷àëà ïîèñê èäåò â êëàññå B, åñëè îí åãî íå íàõîäèò, òî îí èäåòâ îáúåìëþùóþ îáëàñòü âèäèìîñòè, ïîêà íå íàéäåò ìåòîä èëè íå âûäàñòîøèáêó.void B::g(){g()}Ýòî íåÿâíûå âûçîâ ÷åðåç ññûëêó this. Ñíà÷àëà f îòûñêèâàåòñÿ â êëàññå B, ïîòîì â êëàññå A, ïîòîì â ïðîñòðàíñòâàõ èìåí, âïëîòü äî ñàìîãîâíåøíåãî ïðîñòðàíñòâà èìåí.Ïîèñê íóæíîãî ìåòîäà îñëîæíÿåòñÿ åùå è ïåðåãðóçêîé ôóíêöèè.Äàëåå, ïóñòü f - âèðòóàëüíûé ìåòîä.135Ýòî îçíà÷àåò, ÷òî îòûñêèâàåòñÿ äèíàìè÷åñêèé òèï, òî åñòü òðåáóåòñÿçíàòü íà ÷òî óêàçûâàåò bp.
Íàïðèìåðbp = new DÒî åñòü ìû ñìîòðèì íà äèíàìè÷åñêèé òèï, à ïîòîì íà÷èíàÿ ñ íåãîèùåì ñîîòâåòñòâóþùåå ïåðåîïðåäåëåíèå ìåòîäà. Òî åñòü åñëè ìåòîä îáúÿâëåí êàê âèðòóàëüíûé, òî êàæäûé ïðîèçâîäíûé êëàññ ìîæåò ëèáî óíàñëåäîâàòü ìåòîä, ëèáî ïåðåîïðåäåëèòü åãî.Àíàëîãè÷íàÿ ñèòóàöèÿ è äëÿ ÿçûêà C#. Òî åñòü äëÿ âèðòóàëüíîãîìåòîäà îòûñêèâàåòñÿ äèíàìè÷åñêèé òèï, è äëÿ íåãî âûçûâàåòñÿ ìåòîä.A→B→C→DÍåìíîãî äðóãàÿ ñèòóàöèÿ â ÿçûêå java.pb -> f()Ñíà÷àëà êîìïèëÿòîð èäåò â îïðåäåëåíèå B è îòûñêèâàåò îïðåäåëåíèåf(), òàì îí óçíàåò ñïîñîá ñâÿçûâàíèå è òèï ïàðàìåòðîâ.
Ýòà ñèòóàöèÿîñëîæíÿåòñÿ íåÿâíûìè ïðåîáðàçîâàíèÿìè. Òàê æå âûâîäèòñÿ äîñòóï. ÂJava äðóãàÿ ìîäåëü - òàì èäåò óïðàâëåíèå âèäèìîñòüþ, òî åñòü íà çàêðûòîþ ôóíêöèþ íèêòî íå ñìîòðèò.Òî åñòü êîìïèëÿòîð äàæå íå âèäèò ïðèâàòíûå ìåòîäû ïðè âûçîâåèçâíå.Âîïðîñ - ÷òî åñòü îïðåäåëåíà ïðèâàòíàÿ âèðòóàëüíàÿ ôóíêöèÿ. Ååìîæíî ïåðåîïðåäåëÿòü, íî ÷òî ñ äîñòóïîì?class A{private:virtual void f(){..}};class B{privatevirtual void f(){..}};Ïðè÷åì â ïåðåîïðåäåëåíèè ôóíêöèÿ îáÿçàíû òàê æå áûòü private.Ïåðåîïðåäåëÿÿ ïðèâàòíóþ ôóíêöèþ, ìû äàåì áàçîâîìó êëàññó âûçûâàòüïðèâàòíóþ ôóíêöèþ íàøåãî êëàññà.Ïåðåîïðåäåëÿÿ ôóíêöèþ, ìû îòêàçûâàåìñÿ îò íàñëåäîâàíèÿ ðåàëèçàöèè. ÏðèìåðFigure136/ | \/ |\Point Circle Rectvirtual void Draw ();Íàñëåäîâàòü íå îáÿçàòåëüíî,íî äîïóñòèì, ÷òî Circle → Ellipse è åñòü ñïèñîê èç ôèãóð.
Òîãäà íàðèñîâàòü âñå ôèãóðû ìîæíî òàêwhile (L != NULL){L-> f ->Draw ();L = L -> next;}×òîá ñîçäàòü íîâûé òèï äàííûõ, íóæíî ïðîñòî îïðåäåëèòü íîâûéêëàññ, è òàì ïåðåîïðåäåëèòü ñîîòâåòñòâóþùèå ìåòîäû. Íàïðèìåðvoid PatternRect::Draw(){Full (pattern);Rect::Draw ();}Òî åñòü âûçûâàåòñÿ óíàñëåäîâàííûé, à íå ïåðåîïðåäåëåííûé ìåòîä.Òàêàÿ êîíñòðóêöèÿ - ñíÿòèå ñâîéñòâà âèðòóàëüíîñòè ìåòîäà.Rect *f = new PatternRect;f -> Rect::Draw (); âûçîâ ìåòîäà Draw äëÿ Rect;Äëÿ ïðèâàòíûõ âèðòóàëüíûõ ôóíêöèé âîçìîæíî ëèáî ïîëíîå çàìåùåíèå ëèáî ïîëíîå íàñëåäîâàíèå, íî íå èñïîëüçîâàíèå â çàìåùåíèè.137Ëåêöèÿ 3016.12.2008 Ñ++ ìåòîä ÿâëÿåòñÿ âèðòóàëüíûì, åñëè îí ïîìå÷åí êëþ÷åâûì ñëîâîì virtual.
Ïðè ýòîì çàìåùåíèå ìåòîäà ìîæåò èäòè òîëüêî ïðè íàñëåäîâàíèè. Äëÿ çàìåùåíèÿ íåîáõîäèìî, ÷òîá ñîâïàäàëè èìÿ è ñèãíàòóðàïàðàìåòðîâ (ïðîôèëü ïàðàìåòðîâ äîëæåí ñîâïàäàòü), òèï âîçâðàùàåìîãî çíà÷åíèÿ äîëæåí áûòü êîâàðèàíòåí.Òàêèì îáðàçîì, åñëè ôóíêöèÿ âîçâðàùàåò îäèí èç áàçîâûõ òèïîâÿçûêà (int, double) òî òèï âîçâðàùàåìîãî çíà÷åíèÿ äîëæåí ñîâïàäàòü. ñëó÷àå, åñëè îíà âîçâðàùàåò îáúåêò êëàññà, òî ïðè ïåðåîïðåäåëåíèèôóíêöèÿ ìîæåò âîçâðàùàòü ïðîèçâîäíûé îò íåãî òèï.class Base{public:virtual base * clone ();};class Derived: public Base{public:Derived * clone ();};Âñå çàìåñòèòåëè âèðòóàëüíîé ôóíêöèè ïî îïðåäåëåíèþ áóäóò âèðòóàëüíûìè.Ïðè ýòîì îñòàåòñÿ âîïðîñ ñ ïðàâàìè äîñòóïà.
Òî åñòü åñëè îòêðûòàÿôóíêöèÿ ïåðåîïðåäåëåíà êàê ïðèâàòíàÿ, òî îíà ìîæåò áûòü âûçâàíà èçèíòåðôåéñà áàçîâîãî êëàññà.class Base{public:virtual base * clone ();};class Derived: public Base{private:Derived * clone ();};Base * pb = new Base;pb -> clone ();138Derived * pd = new Derived;pd -> clone ();//íåëüçÿpb = pd;pb -> clone ();//OkÒåïåðü ðàññìîòðèì Java, òàì èäåò óïðàâëåíèå âèäèìîñòüþ, à íå äîñòóïîì.X:public void f() {}class Y extends X{private void f(){}} äàííîì ñëó÷àå ïðèâàòíàÿ ôóíêöèÿ âîîáùå íå âèäíà, òî åñòü åå âûçâàòü ìîæíî òîëüêî âíóòðè êëàññà Y. Èçâíå áóäåò âûçûâàòüñÿ ôóíêöèÿêëàññà X. Java âñå ôóíêöèè ïî óìîë÷àíèþ äèíàìè÷åñêèå, åäèíñòâåííûé ñïîñîá çàïðåòèòü äèíàìè÷åñêîå çàìåùåíèå - êëþ÷åâîå ñëîâî nal. Åñëè âjava íå ñîâïàäàåò èìÿ - òî ýòî ïðîñòî íîâàÿ ôóíêöèÿ, åñëè ñîâïàäàåòèìÿ, íî íå ñîâïàäàåò ïðîôèëü, òî ýòî ñêðûòèå.
Åñëè æå ñîâïàäàåò èìÿ èïðîôèëü, íî òèï âîçâðàùàåìûõ çíà÷åíèé íå êîâàðèàíòåí, òî ýòî îøèáêà.class Y extends X{public final void f(){}};Y y = new Y_Derived;y -> f();Ïðè ýòîì áóäåò âñåãäà âûçâàí èìåííî ìåòîä èç êëàññà Y, òàê êàê îíàîáúÿâëåíà êàê nal.Ðàññìîòðèì òåïåðü C# è Delphi. Êàê è â Ñ++ òàì åñòü êàê âèðòóàëüíûå, òàê è íå âèðòóàëüíûå ìåòîäû. Åñëè â C# ìåòîä îáúÿâëåí êàêâèðòóàëüíûé, òî â êëàññå íàñëåäíèêå âîçìîæíà ñëåäóþùàÿ ñèòóàöèÿ ôóíêöèÿ, ó êîòîðîé ñîâïàäàåò ïðîôèëü, èìÿ, è êîâàðèàíòåí òèï âîçâðàùàåìîãî çíà÷åíèÿ íå îáÿçàíà çàìåùàòü.Òàêèì îáðàçîì òðåáóåòñÿ åùå ìîäèôèêàòîð override.139class Y::X{};public override void f(){..}Åñëè ñëîâà override íåò, òî ñâîéñòâî äèíàìè÷åñêîãî ñâÿçûâàíèÿ òåðÿåòñÿ.
Òî åñòü.class Y:X{};publicvoid f(){..} äàííîì ïðèìåðå äëÿ ôóíêöèè f íåò äèíàìè÷åñêîãî ñâÿçûâàíèÿ. Delphitype X = classprocedure P; virtual;end;type Y = class (X)procedure P;override;end;Òî åñòü ñèòóàöèÿ àíàëîãè÷íàÿ C#. C# â ñëó÷àå îòñóòñòâèå override èëè new â îïðåäåëåíèè ôóíêöèèâûäàåòñÿ ïðåäóïðåæäåíèå.class Z: Y{public virtual void f();};Y y = new Z();y.f ();Òåïåðü áóäåò âûçâàíà ôóíêöèÿ èç Z, òàê êàê â êëàññå Z îïÿòü óêàçàííî ñëîâî virtuaÒàê æå âîçìîæíà ñèòóàöèÿ, êîãäà ôóíêöèÿ íå áûëà âèðòóàëüíîé âáàçîâûõ êëàññàõ, íî ñòàëà âèðòóàëüíîé â êëàññå ïîòîìêå.Ðàññìîòðèì ÿçûê Îáåðîí - 2.
 îäíîé èç âåðñèÿ ïîÿâèëèñü ïðîöåäóðû, äèíàìè÷åñêè ïðèâÿçàííûå ê òèïó.Ðàññìîòðèì ñíà÷àëà âàðèàíò ñ ïîëåì òèïà.140TYPE FIGURE* = RECORD....END;TYPE LINE* = RECORD (FIGURE)...END;TYPE CIRCLE* = RECORD (FIGURE)....END;PROCEDURE DRAW (VAR F: FIGURE); (VAR X: LINE);IF F IS LINE THENDRAWLINE (LINE.F);ELSEIF F IS CIRCLE THENDRAWCIRCLE (CURCLE.F);Òåïåðü ðàññìîòðèì âàðèàíò ñ äèíàìè÷åñêîé ïðèâÿçêîé òèïà.PROCEDURE (VAR F: FIGURE) DRAW();PROCEDURE (VAR C: CIRCLE) DRAW();Ýòî åäèíñòâåííûé ñëó÷àé, êîãäà â Îáåðîí - 2 ðàçðåøåíà ïåðåãðóçêàèìåí. Âîïðîñ - êàê ýòî âûçûâàòü?PROCEDURE DRAWALL (VAR F.FUGURE);...F.DRAW (); ïñåâäî ìîäóëå îïðåäåëåíèÿ áóäåò ñãåíåðèðîâàí ñëåäóþùèé êîä.TYPE FIGURE =RECORDÎáúÿâëåíèå âèäèìûõ ÷ëåíîâ.PROCEDURE DRAW();END;DRAW () - âûçîâ óíàñëåäîâàííîé ðåàëèçàöèè (ñíÿòèå âèðòóàëüíîñòè).FIGURE INTERSECT (F1, F2: figure);141Äëÿ êàæäîé ïàðû òèïîâ Òðåáóåòñÿ íàïèñàòü ñâîþ ïðîöåäóðó INTERSECT.Âîïðîñ îïÿòü æå êàê åå âûçâàòü?Îäèí èç âàðèàíòîâ - f1@f2.intersect.
Íî òå ÿçûêè, êîòîðûå ìû ñåé÷àñðàññìàòðèâàåì íå èìåþò ìóëüòèìåòîäîâ.Òåïåðü ðàññìîòðèì Àäà - 95. Òàì íåòó âèðòóàëüíûõ ìåòîäîâ â ÿâíîìâèäå.type Base is tagged record ... end record;type Derived is new Base with record <íîâûå ÷ëåíû è îáúÿâëåíèÿ> end record;procedure P( x: Base);procedure P( y: Derived);Ïîêà ðå÷ü î çàìåùåíèè èëè äèíàìè÷åñêîé ïðèâÿçêè ê òèïó íåòó. Òîåñòüb: Base;d: Derived;P(b);{P(Base)}P(d);{P(Derived)}P(Y'Base);{P(Base)} Àäà - 95 áûëè ââåäåíû CW - ïåðåìåííûå (class wide) è CW - Òèïû.CW - Òèïû (êëàññîâûå òèïû).T'class - îáúåäèíåíèå T è âñåõ îáúåêòîâ, ïðîèçâîäíûõ îò íåãî.X: Base'class - ïîëíûé àíàëîã íåîãðàíè÷åííûõ ïåðåìåííûõ. Òàêîé ïåðåìåííîé ìîæíî ïðèñâàèâàòü ëþáîé îáúåêò êëàññà Base èëè ïðîèçâîäíûõîò íåãî.P(X) - äèíàìè÷åñêèé âûçîâ.P(b);P(d);P(X);staticstaticdynamicFIGURE → LINEFIGUGE → CIRCLEprocedure DrawAll (p: Figure'class)Ëþáàÿ ïðîöåäóðà, êîòîðàÿ èìååò õîòÿ áû îäíèì ïàðàìåòðîì îáúåêòòåãèðîâàííîãî òèïà ìîæåò áûòü âûçâàíà äèíàìè÷åñêèì îáðàçîì, ïðè÷åìòåãèðîâàííûé îáúåêò äîëæåí áûòü çàìåíåí íà îáúåêò êîíêðåòíîãî òèïà.142function Intersect (X, Y: Figure) return Figure;function Intersect (A, B: Figure'class) return Figure;{Bad}Íî ìû íå ìîæåì âûçâàòü ïðîöåäóðó, ó êîòîðîé áîëåå îäíîãî ïàðàìåòðà ÿâëÿåòñÿ êëàññîâûìè òèïàìè.
Òî åñòü òîëüêî îäèí ïàðàìåòð ìîæåò áûòü êëàññîâîãî òèïà. Íî âîçìîæíî íàïèñàòü Intersect (X, L) èëèIntersect (C, X), òî åñòü óêàçûâàÿ îäèí êëàññîâûé ïàðàìåòð.class Figure {public:virtual void Draw ();};class circle: public Figure {public:void Draw ();};Òàêàÿ ðåàëèçàöèÿ âûçîâåò îøèáêó (íå îïèñàòü Figure::Draw()), ÷òîíå ïîçâîëÿåò èíèöèàëèçèðîâàòü òàáëèöó âèðòóàëüíûõ ìåòîäîâ.
ÊëàññFigure - àáñòðàêòíûé êëàññ.Âî âñåõ ÎÎßÏ åñòü ïîíÿòèå àáñòðàêòíîãî êëàññà.  Ñ++ åñòü ïîíÿòèå ÷èñëî âèðòóàëüíîé ôóíêöèè. Êëàññ, êîòîðûé èìååò õîòÿ áû îäíó÷èñòî âèðòóàëüíóþ ôóíêöèþ íàçûâàåòñÿ àáñòðàêòíûì. Íåëüçÿ ñîçäàòüîáúåêòû òàêîãî êëàññà. Ñèíòàêñè÷åñêè ýòî ðåàëèçóåòñÿ êàê virtual voidDraw() = 0;Ýòî îçíà÷àåò ÷òî ñîîòâåòñòâóþùàÿ ôóíêöèÿ ìîæåò èìåòü ðåàëèçàöèþ, à ìîæåò è íå èìåòü.Figure f;//ErrFigure * p;//Okp = new Figure;//Errp = 0; //Okp = new Line;//Ok Ñ# è Java åñòü êëþ÷åâîå ñëîâî abstract, ÷òî îçíà÷àåò ÷òî ìåòîäÿâëÿåòñÿ âèðòóàëüíûì è ïðèòîì ÷èñòî âèðòóàëüíûì. Åñëè ó êëàññà åñòüõîòü îäèí àáñòðàêòíûé ìåòîä, òî êëàññ ÿâëÿåòñÿ àáñòðàêòíûì, òî ïåðåäåãî îïðåäåëåíèåì äîëæíî ñòîÿòü êëþ÷åâîå ñëîâî abstract.143Ëåêöèÿ 3118.12;2008Ãëàâà 3. ÈíòåðôåéñûÈíòåðôåéñ - îñîáàÿ ÿçûêîâàÿ êîíñòðóêöèÿ, êîòîðàÿ ñîäåðæèò îáúÿâëåíèå íàáîðà ïóáëè÷íûõ ìåòîäîâ. Èíòåðåñ íå ñîäåðæèò ÷ëåíîâ äàííûõ,îí ìîæåò ñîäåðæàòü òîëüêî ñòàòè÷åñêèå ÷ëåíû.Èíòåðôåéñ ìîæåò íàñëåäîâàòüñÿ (ïðè íàñëåäîâàíèè ðàññìàòðèâàþòñÿ êàê àáñòðàêòíûå êëàññû). Ñ++ èíòåðôåéñû ìîäåëèðóþòñÿ ñ ïîìîùüþ àáñòðàêòíûõ êëàññîâ. C# è Java ïðèñóòñòâóþò ÿâíî (interface).Ðàññìîòðèì 2 âîïðîñà1.