лекции (2008) (by Kravets) (укороченное) (1160827), страница 20
Текст из файла (страница 20)
Ñ òî÷êè çðåíèÿ ÿ îáëàñòè äåéñòâèÿ èìååò ìåñòî 2 ïðèíöèïà- ïåðåãðóçêà- ñêðûòèåÏî÷òè âî âñåõ ñëó÷àÿõ ðå÷ü èäåò èìåííî è ñêðûòèè. Òî åñòü ìû äîëæíû ðàçëè÷àòü èìåíà ôóíêöèé(äîïóñêàþò ïåðåãðóçêó) è èìåíà îñòàëüíûõ îáúåêòîâ.Y y;y.f();Òàêîå îáðàùåíèå - îáðàùåíèå ê int f. Òàê êàê void f() ñêðûòî. Òî åñòü òàêîå îáðàùåíèå ïðèâåäåò ê îøèáêå.Ðàññìîòðèì äðóãîé âàðèàíòclass X{void f();};class Y:public X{void f(int);}; äàííîì ñëó÷àå ðå÷ü èäåò òàê æå î ñêðûòèè, òî åñòü f() áóäåò ïåðåêðûòà f(int).
Òî åñòü êëàññ y îáëàäàåòòîëüêî ôóíêöèåé y.f(int).Ïåðåãðóçêà âîçìîæíà òîëüêî â îäíîé îáëàñòè äåéñòâèÿ. Äëÿ èìåí ôóíêöèé ïîÿâëÿåòñÿ è òðåòèé âàðèàíò- ïåðåîïðåäåëåíèå. Ýòî òîëüêî äëÿ ôóíêöèé, êîòîðûå îáëàäàþò äèíàìè÷åñêèì ñâÿçûâàíèåì.class X{virtual void f();};class Y:public X{void f();};Ôóíêöèþ èç êëàññà - ïðåäêà ìîæíî âûçâàòü ïóòåì ÿâíîãî óêàçàíèÿ èìåíè êëàññà.
y.X::f().Áîëåå õèòðàÿ ñèòóàöèÿ â ÿçûêå Java.Ðàññìîòðèì òåïåðü ìîäóëüíûå ßÏ - Àäà - 95 è Îáåðîí.<= Oberon =>MODULE M;TYPE BASE* =RECORDI:INTEGER;J*:REAL;END;END M;MODULE M1;IMPORT M;78TYPE DERIVED *= RECORD (M.BASE)K: INTEGER;END;PROCUDURE P(VAR X:DERIVED);BEGINX.K := 0;X.J := 1;X.I := 1; Îøèáêà;END:Òî åñòü, åñòü ëèáî ïóáëè÷íûå ÷ëåíû äàííûõ (*), ëèáî ïàêåòíûå ÷ëåíû äàííûõ, êîòîðûå âèäíû òîëüêî âïðåäåëàõ ïàêåòà.Ðàññìîòðèì ÿçûê Àäà.package M isType Base is tagged private;...priatetype Base is tagged record...end record;end M;package M1 isuse M;type Derived is new Basewith recordK:integer;end record;procudere B(VAR X:inout Derived) is ...Äàëåå,â Àäà ïîÿâëÿåòñÿ ïîíÿòèå äî÷åðíèõ ïàêåòîâ.package M.M1 istype Derived is new Base withrecordK:Integer;end record;procedure P(X: inout Derived);Âñå èìåíà, êîòîðûå îïèñàíû â M äîñòóïíû â M1(äàæå ïðèâàòíûå).Ìíîæåñòâåííîå íàñëåäîâàíèåÏðîáëåìû1.
Êîíôëèêò èìåí2. Ðåàëèçàöèÿ3. Ïðèñâàèâàíèå îáúåêòîâ ðàçíûõ êëàññîâ.4.Base * pb = new Base;Derived * pd = new Derived;pb = pd;pb -> f();Çäåñü âñå íîðìàëüíî.class X:public Y, public Z{};X * px = new X;Y * py = new Y;Z * pz = new Z;79px = pz; Errorpy = px;pz = px;pz -> f (); ñëó÷àå âèðòóàëüíûõ ìåòîäîâ âîïðîñ åùå ñèëüíåå óñëîæíÿåòñÿ, òàê êàê êîìïèëÿòîð íà ýòàïå êîìïèëÿöèèíå çíàåò êàêîé èìåííî ìåòîä âûçûâàòü.80Ëåêöèÿ 2911.12.2008Èòàê áûëî îòìå÷åíî òðè ïðîáëåìû ñâÿçàííûå ñ ìíîæåñòâåííûì íàñëåäîâàíèåì1. Êîíôëèêò èìåí.Ñ++ äîïóñêàåò ïîëíîå ìíîæåñòâåííîå íàñëåäîâàíèå.Ñ++ Îäèí èç íåìíîãèõ ÿçûêîâ, äîïóñêàþùèõ ïîëíîå ìíîæåñòâåííîå íàñëåäîâàíèå.
Ïðè ýòîì îãðàíè÷åííîå ìíîæåñòâåííîå íàñëåäîâàíèå (èíòåðôåéñû) åñòüïî÷òè âî âñåõ ñîâðåìåííûõ ßÏ. Ïðè íàñëåäîâàíèè èíòåðôåéñîâ êîíôëèêòîâàòü ìîãóò òîëüêî èìåíà ìåòîäîâ.2. Ñëîæíîñòè ðåàëèçàöèè.Òðåáîâàíèå êîððåêöèè óêàçàòåëåé â ñëó÷àå ëèíåéíîãî ðàçìåùåíèÿ ïàìÿòè (ïðèñóòñòâóåò ïî÷òè âî âñåõÿçûêàõ ïðîìûøëåííîãî ïðîãðàììèðîâàíèÿ).3.Èäåîëîãè÷åñêèå ñîîáðàæåíèÿ (íå ðàññìàòðèâàåì)Ïðèìåð èåðàðõèèX− > W < −YL− > X− > W < −Y < −LL− > W < −L Òàêîå íåäîïóñòèìîÏîèñê èìåí ïðîèñõîäèò ñíà÷àëà â ñâîåì ïðîñòðàíñòâå èìåí, à ïîòîì ïàðàëëåëüíî â âûñøèõ ïîðÿäêàõ(ìåõàíèçì, ñõîæèé ñ ìåõàíèçìîì ïîèñêà â ïðîñòðàíñòâàõ èìåí).Äëÿ ïîëó÷åíèÿ äîñòóïà ê ÷ëåíàì äàííûõ êëàññîâ - ïðåäêîâ ìîæåò ïîòðåáîâàòüñÿ ÿâíàÿ ñïåöèôèêàöèÿ. òàêèõ ÿçûêàõ, êàê C#, Java, Delphi, â êîòîðûõ âñå îáúåêòû íàñëåäóþò êëàññ Object, èìåþòñÿ îáîáùåííûå (àáñòðàêòíûå) êîíòåéíåðû, â êîòîðûõ ìîãóò õðàíèòüñÿ îáúåêòû ëþáîãî òèïà.Åñëè òðåáóåòñÿ õðàíèòü îäèí è òîò æå îáúåêò â êà÷åñòâå äâóõ ñóùíîñòíîé, òî ýòî ìîæíî ðåàëèçîâàòü ñïîìîùüþ ìíîæåñòâåííîãî íàñëåäîâàíèÿ.
Òàêèå èåðàðõè÷åñêèå ñòðóêòóðû èçó÷àåòñÿ â îñîáîì ðàçäåëå ìàòåìàòèêè - òåîðèè ðåøåòîê èëè òåîðèè êàòåãîðèé.Áðèëëèàíòîâîå (ðîìáîâèäíîå) íàñëåäîâàíèåX/\AW\Y/Ïðèìåðîì òàêîãî íàñëåäîâàíèÿ ìîæåò ñëóæèòü ïðîåêòèðîâàíèå ìîäóëÿ <iostream>. Óïðîùåííàÿ èåðàðõèÿ âûãëÿäèò òàê.ios(int fd)/\/\istreamostream\/\/iostreamclass A{};class X:public virtual A{};class Y:public virtual B{};class W:public X, public Y{};Åñëè îïóñòèòü õîòÿ áû îäíî ñëîâî virtual, òî "ðîìáîâèäíîãî"íàñëåäîâàíèÿ íå áóäåò. Íåäîñòàòêîì òàêîéñõåìû ñëóæèò òî, ÷òî ðåøåíèå î òèïå íàñëåäîâàíèÿ äîëæíî ïðèíèìàòüñÿ íà ýòàïå åäèíè÷íîãî íàñëåäîâàíèÿ.Ýòî íå ÿâëÿåòñÿ íåäîñòàòêîì Ñ++, íî ñâîéñòâîì íàñëåäîâàíèÿ, òàê êàê âñÿ èåðàðõèè äîëæíà ðàçðàáàòûâàòüñÿ íà ýòàïå ïðîåêòèðîâàíèÿ.81 Ñ++ íåò íèêàêèõ îãðàíè÷åíèé ñ òî÷êè çðåíèÿ íàñëåäîâàíèÿ, òî åñòü íåò íèêàêèõ ÿçûêîâûõ ìåòîäîâçàïðåòèòü íàñëåäîâàíèÿ äàííîãî êëàññà.
Êîíå÷íî, ìîæíî ñäåëàòü êîíñòðóêòîð èëè äåñòðóêòîð çàêðûòûìè,íî ýòî óæå íå èçâîðîòû. Java ìîæíî çàïðåòèòü íàñëåäîâàíèå, ñ ïîìîùüþ êëþ÷åâîãî ñëîâà nal. Åñëè ýòî ñëîâî ñòîèò ïåðåäèìåíåì ìåòîäà, òî ýòîò ìåòîä íå ìîæåò ïåðåîïðåäåëÿòüñÿ â ïðîèçâîäíûõ êëàññîâ. Åñëè æå îíî ñòîèò ïåðåäîïðåäåëåíèåì êëàññà, òî êëàññ íåëüçÿ íàñëåäîâàòü.  Ñ# òàêóþ æå ðîëü èãðàåò ñëîâî sealed.Ïî÷òè âñå áèáëèîòåêà .NET ÿâëÿåòñÿ çàïå÷àòàííîé, òî åñòü èç íåëüçÿ íàñëåäîâàòü, à òå êëàññû, èç êîòîðûõìîæíî íàñëåäîâàòü îáû÷íî ÿâëÿþòñÿ àáñòðàêòíûìè.Çàïå÷àòûâàíèå ìîæåò ïîâûñèòü ýôôåêòèâíîñòü ïðîãðàììû.Äèíàìè÷åñêîå ñâÿçûâàíèå ìåòîäîâ.Áåç äèíàìè÷åñêîãî ñâÿçûâàíèÿ ìåòîäîâ ïîíÿòèå íàñëåäîâàíèÿ ïðàêòè÷åñêè òåðÿåò ñâîé ñìûñë.
Íàñòîÿùååíàñëåäîâàíèå ïðîÿâëÿåòñÿ òîëüêî ïðè èñïîëüçîâàíèè äèíàìè÷åñêîé òèïèçàöèè.  ÿçûêàõ èíäóñòðèàëüíîãîïðîãðàììèðîâàíèÿ (ñî ñòðîãîé òèïèçàöèåé) çàìåíà îáúåêòà ñóïåð-êëàññà íà îáúåêò ïðîèçâîäíîãî êëàññà íè÷åãî íå ìåíÿåò ñ òî÷êè çðåíèÿ íàäåæíîñòè.base=derivedvoid foo (base b);f(base)f(derived)Äðóãîå äåëî, êîãäà âìåñòî îáúåêòà ïåðåäàåòñÿ ññûëêà íà îáúåêò.  ÿçûêàõ ãäå åñòü íàñëåäîâàíèå, åñòüïîíÿòèå ñòàòè÷åñêîãî òèïà, òî åñòü òèïà, ïðèñâîåííîãî îáúåêòó ïðè ñîçäàíèè.var X = new System.Window.Forms.FormÏðè ýòîì òèï îáúåêòà X ñòàòè÷åñêè îïðåäåëèì. Îáúåêòíûõ ßÏ äëÿ íåêîòîðûõ îáúåêòîâ ÒÏ ïîÿâëÿåòñÿ äèíàìè÷åñêèé òèï - òèï îáúåêòà äàííûõ, íàêîòîðûé ññûëàåòñÿ óêàçàòåëü èëè ññûëêà.Base * pd;Ñòàòè÷åñêîé òèï - Base, à äèíàìè÷åñêèì òèïîì ìîæåò áûòü ëþáîé èç ïîòîìêîâ Base, òàê êàê pb ìîæåòóêàçûâàòü íà ëþáîãî îáúåêòà-ïîòîìêà Base.Ñòàòè÷åñêèé òèï îáúåêòà äàííûõ èçìåíèòü íåëüçÿ.
Êàæäûé îáúåêò îáëàäàåò êóñêîì ïàìÿòè, äëÿ êîòîðîãîáûë âûçâàí êîíñòðóêòîð. C#, Java è Delphi, îáúåêò ðàçìåùàåòñÿ â äèíàìè÷åñêîé ïàìÿòè, è êàê òîëüêî îí áûë òàì ðàçìåùåí åãîòèï çàôèêñèðîâàí.Íå-ñòàòè÷åñêèé ìåòîä êëàññà - ìåòîä, âûçûâàåìûé ÷åðåç ññûëêó íà îáúåêò. Ìåòîä íàçûâàåòñÿ ñòàòè÷åñêèïðèâÿçàííûì, åñëè åãî âûçîâ îïðåäåëÿåòñÿ èç ñòàòè÷åñêîãî òèïà ññûëêè, è äèíàìè÷åñêè åñëè åãî âûçîâîïðåäåëÿåòñÿ äèíàìè÷åñêèì òèïîì ññûëêè.Òî åñòü îïðåäåëÿåòñÿ äèíàìè÷åñêèé òèï ññûëêè, è äëÿ ýòîãî òèïà âûçûâàåòñÿ ìåòîä. Ñ++ ýòî ðåàëèçóåòñÿ íà îñíîâå âèðòóàëüíûõ ôóíêöèé.
Íà òàêèå ôóíêöèè íàëîæåíû íåêîòîðûå òðåáîâàíèÿ.Îïðåäåëåíèå, åñëè òèï 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. Òî åñòü âèðòóàëüíîñòü - ñâîéñòâî ìåòîäà.82Åñëè ìåòîä îáúÿâëåí ñ êëþ÷åâûì ñëîâîì virtual, òî îí ñòàíîâèòñÿ äèíàìè÷åñêè ñâÿçàííûì.
Äèíàìè÷åñêîå ñâÿçûâàíèå - ýòî ñâîéñòâî âûçîâà, íî â ÿçûêàõ îíî ïðèâÿçàíî ê ìåòîäó.A→B→C→D→B* pb;pb -> f();Ïóñòü f - ñòàòè÷åñêèé ìåòîä.Ñíà÷àëà ïîèñê èäåò â êëàññå B, åñëè îí åãî íå íàõîäèò, òî îí èäåò â îáúåìëþùóþ îáëàñòü âèäèìîñòè,ïîêà íå íàéäåò ìåòîä èëè íå âûäàñò îøèáêó.void B::g(){g()}Ýòî íåÿâíûå âûçîâ ÷åðåç ññûëêó this. Ñíà÷àëà f îòûñêèâàåòñÿ â êëàññå B, ïîòîì â êëàññå A, ïîòîì âïðîñòðàíñòâàõ èìåí, âïëîòü äî ñàìîãî âíåøíåãî ïðîñòðàíñòâà èìåí.Ïîèñê íóæíîãî ìåòîäà îñëîæíÿåòñÿ åùå è ïåðåãðóçêîé ôóíêöèè.Äàëåå, ïóñòü f - âèðòóàëüíûé ìåòîä.Ýòî îçíà÷àåò, ÷òî îòûñêèâàåòñÿ äèíàìè÷åñêèé òèï, òî åñòü òðåáóåòñÿ çíàòü íà ÷òî óêàçûâàåò 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.