Më poshtë e thjeshton dhe trajton një zbatim të mundshëm si fakt, por duhet të mjaftojë për të pasur një model mendor funksional.
Kur telefononi kodin "di për" një klasë, ai di gjërat e mëposhtme:
Fushat mund të aksesohen në një zhvendosje të veçantë nga vendndodhja e objektit. Kështu, për shembull, nëse një objekt është në adresën 120 dhe ka dy fusha me numra të plotë, atëherë ai mund të jetë në gjendje t'i qaset njërës në adresën 124. Nëse një objekt tjetër i të njëjtit lloj ishte në adresën 140, fusha ekuivalente do të ishte në 144.
Metodat jo virtuale (dhe vetitë mund të konsiderohen sheqer sintaksor në një ose dy metoda) janë funksione në një adresë të caktuar që marrin një referencë për objektin që po thërrisni (this
nga brenda metodës) dhe parametrat e tjerë të atij funksioni.
Metodat virtuale janë si më sipër, por adresa e tyre mund të gjendet duke parë një zhvendosje të veçantë brenda një tabele të lidhur me klasën, adresa e së cilës do të jetë gjithashtu një zhvendosje e veçantë nga adresa e klasës.
Në këtë, Kid
ka një tabelë metodash që është një superbashkësi e asaj të Parent
(mund të shtojë më shumë metoda), dhe e cila ka të njëjtën adresë funksioni për ato metoda që nuk i ka kaluar (duke thirrur Equals
në të përdor të njëjtën funksionon si thirrja e Equals
në një Parent
), por një adresë e ndryshme për ata që i kalon (Print()
në këtë rast).
Prandaj, nëse keni një Kid
, atëherë nëse e keni atë nëpërmjet referencës Parent
ose Kid
, thirrja e Print()
do të shikojë në të njëjtën tabelë, do të kërkojë vendndodhjen e metodës Print()
dhe do ta thërrasë atë.
Në rastin e Child
, përdoret new
në metodën Print
. Kjo i tregon përpiluesit se ne duam në mënyrë specifike një tabelë të ndryshme. Prandaj, nëse thërrasim Print()
nëpërmjet referencës Child
, ai kërkon tabelën specifike të Child
dhe thërret metodën që gjen. Nëse sidoqoftë e quajmë atë nëpërmjet referencës Kid
ose Parent
, atëherë as nuk e dimë se ekziston një tabelë specifike e Child
që mund të përdorim dhe ne kërkojmë funksionin në tabelën që dimë se Kid
dhe Parent
kanë përkatësisht, dhe thërrasim funksioni i gjetur (ai i përcaktuar në Kid
).
Si rregull, new
duhet të shmanget. Përdorimi i tij është në dy vende:
Njëra është përputhshmëria e prapambetur. Nëse për shembull Child
kishte një pronë Name
, dhe më vonë kodi për Parent
u ndryshua në mënyrë që edhe ai të kishte një pronë Name
, ne kemi një konflikt. Meqenëse Name
i Child
nuk është një ndryshim, ai trajtohet sikur të kishte new
, por na jep një paralajmërim, pasi kjo është e vetmja mënyrë që kodi që përdor mënyrën e vjetër të gjërave dhe kodin që di për Name
të ri në Parent
mund të bashkëekzistojë. . Nëse kthehemi ndonjëherë për të ripërpiluar Child
, ndoshta duhet të rifaktorojmë në mënyrë që ai të mos ketë Name
-në e vet (nëse ai më Parent
bën atë që duam ne), të rifaktorojmë kështu që është një zëvendësim, rifaktor i diçkaje krejtësisht të ndryshme, ose të shtojmë new
për të treguar se kështu duam që gjërat të jenë pavarësisht se është më pak se ideale.
Tjetra është kur new
lejon një formë më specifike të së njëjtës sjellje që lejon metoda e klasës bazë, por është logjikisht e pajtueshme (kështu që përdoruesit të mos habiten). Kjo e fundit duhet të hyjë në kutinë e teknikave gjysmë të avancuara dhe të mos bëhet lehtë. Gjithashtu duhet komentuar si e tillë, sepse në shumicën e rasteve të shohësh new
do të thotë të merresh me diçka që në rastin më të mirë është një kompromis dhe ndoshta duhet përmirësuar.
(Përveç: a jam unë i vetmi person që mendova për gazetat tabloide kur pashë Kid
s që kishte Child
ren?)
14.08.2012
Child
, nuk do të merrniThis is Child
. A nuk e kuptoni se operatorinew
nuk është ekuivalent me metodat mbizotëruese? 14.08.2012