Kezdőoldal » Számítástechnika » Programozás » [C#] Ebben az esetben miért...

[C#] Ebben az esetben miért viselkedik másképp ha egy virtuális metódust felülírok az öröklött osztályban mintha a new kulcsszóval új meghatározást adnék neki?

Figyelt kérdés

Csináltam egy egyszerű példát a problémámra

[link]

A 37. és 38. sor miért nem ugyanazt("baseMethod") az eredményt adja vissza? Ha a szülő osztályomra castolom a gyerek osztályt miért a gyerek osztály metódusát hívja meg?


2020. jan. 30. 17:47
 1/6 anonim ***** válasza:
63%

Ennek nincs köze hozzá. Az a baja, hogy a myBaseClass függvénye nem virtuális, így mindenképp az hívódik meg.

De nem értem, miért van virtual, override, és new össze-vissza a kódban?

2020. jan. 30. 18:24
Hasznos számodra ez a válasz?
 2/6 A kérdező kommentje:

Nem össze-vissza van, leírtam hogy mit szeretnék, egy származtatott osztály példányát használva meghívni a szülő osztály metódusát, erre csináltam két lehetséges megoldást - egy virtuális metódust és egy publikus metódust amit a new kulcsszóval a származtatott osztályban felülírok.

A problémám meg pont az, hogy a származtatott myBaseMethod metódust hívja meg, nem pedig az alap osztály myBaseMethod metódusát, és nem értem hogy miért, arra számítottam hogy castolás után gyakorlatilag megegyezik azzal mintha a származtatott osztályon belül azt írnám hogy base.myBaseMethod().

Könnyen lehet hogy valamit rosszul csinálok, nem értem a logikát mögötte, hogy konkrétan mi történik ilyenkor.

2020. jan. 30. 19:19
 3/6 anonim ***** válasza:
63%

Mert VIRTUÁLIS a method. Ami azt jelenti jelen esetben, hogy tárol egy virtuális függvénytáblát, és minden objektumhoz hozzárendeli a megfelelő függvényt.

Ebben az esetben létrehozáskor eltárolja hogy a derivedclass method hol van, és utána azt hiába cast-olgatod, a virtuális táblában az a cím marad.

2020. jan. 30. 20:47
Hasznos számodra ez a válasz?
 4/6 anonim ***** válasza:
63%
Ha a kulonbozo viselkedesu gyermekeket egy ososztaly tipusu kollekcioban tarolunk el vagy parameterkent adunk at, akkor mi ertelme lenne a polimorfizmusnak, ha allandoan tipust ellenorizni es kenyszeriteni kene, hogy hozzak az elvart viselkedest? Raadasul, mi tortenne akkor, ha felulirt metodus abstract? Mi hivodna meg castolas utan?
2020. jan. 30. 20:52
Hasznos számodra ez a válasz?
 5/6 A kérdező kommentje:

#3 Tudsz esetleg linkelni ezzel kapcsolatban dokumentációt? Nem találtam erre a konkrét esetre semmit, szeretném megérteni hogy miért így működik, hogy kívülről miért nem érhető el a szülő osztálya amikor a származtatott osztályon belül ennek semmi akadálya.

#4 egészen konkrétan semmi hasznosat nem írtál.

2020. jan. 30. 21:19
 6/6 anonim ***** válasza:
63%

Polimorfizmus a szó, amit te keresel. Ha a hivatalos doksi érdekel, itt van:

[link]


A lényeg az, hogy van két osztályod, A és B, ahol B az A osztály leszármazott osztálya.


class A {}

class B : A {}


Ebben az esetben, ha a B osztályt példányosítod, csinálhatod így:

B obj = new B();


Van ez a fogalom, hogy statikus típus és dinamikus típus. A statikus típus azt jelenti, hogy fordítási időben milyen típusú kifejezés az obj változód, ami a példányt tárolja. A dinamikus típus pedig azt jelenti, hogy futási időben valójában milyen típusú objektum áll mögötte.

B obj; - ez a változódeklaráció eldönti, hogy az "obj" változód statikus típusa "B" lesz. Vagyis minden olyan tagot, amivel a B osztály rendelkezik, látni fogod.

new B() - ez a példányosító kifejezés pedig azt jelenti, hogy az "obj" változód mögött egy "B" objektum fog szerepelni - vagyis a dinamikus típusa "B" lesz.


A dolog akkor lesz érdekes, amikor rájössz arra, hogy az öröklődés miatt valójában ezt is megteheted:

A obj = new B();

Ezt azért teheted meg, mert a B osztály az A osztály leszármazottja - vagyis az öröklődés miatt tud minden olyan dolgot, amit az A is tud.

Ebben az esetben viszont az obj változód statikus típusa A lesz, de a dinamikus típusa B. És ez felvet két érdekes helyzetet.


Az egyik helyzet az, hogy van az A-ban egy virtual vagy override kulcsszóval megjelölt metódus, amit a B-ben override-olok:

class A {

public virtual void DoSomething() => Console.WriteLine(nameof(A));

}


class B : A {

public override void DoSomething() => Console.WriteLine(nameof(B));

}


A obj = new B();

obj.DoSomething();


Ebben az esetben a kimenet B lesz, mivel override esetében mindig a dinamikus típust kell figyelembe venni. Ezért fut le a B.DoSomething().


New kulcsszó esetén pedig az a szabály, hogy mindig a statikus típust kell figyelned, mivel nem felüldefiniál egy deklarációt, hanem csak elrejti azt.

class A {

public virtual void DoSomething() => Console.WriteLine(nameof(A)); //a virtualnak nincs hatása ebben az esetben

}


class B : A {

public new void DoSomething() => Console.WriteLine(nameof(B));

}


A obj = new B();

obj.DoSomething();


A kimenet A lesz.


Ugyanez a szabály vonatkozik arra az esetre is, amikor osztályon belül vagy:

class A {

public void DoSomething() => Console.WriteLine(Get());

public virtual string Get() => nameof(A);

}


class B : A {

public override string Get() => nameof(B);

}


A obj = new B();

obj.DoSomething(); //A kimenet "B"


New kulcsszó esetén pedig:

class A {

public void DoSomething() => Console.WriteLine(Get()); //a this objektum statikus típusa A

public virtual string Get() => nameof(A);

}


class B : A {

public new string Get() => nameof(B);

}


A obj = new B();

obj.DoSomething(); //A kimenet "A"

2020. jan. 30. 23:06
Hasznos számodra ez a válasz?

Kapcsolódó kérdések:




Minden jog fenntartva © 2025, www.gyakorikerdesek.hu
GYIK | Szabályzat | Jogi nyilatkozat | Adatvédelem | Cookie beállítások | WebMinute Kft. | Facebook | Kapcsolat: info(kukac)gyakorikerdesek.hu

A weboldalon megjelenő anyagok nem minősülnek szerkesztői tartalomnak, előzetes ellenőrzésen nem esnek át, az üzemeltető véleményét nem tükrözik.
Ha kifogással szeretne élni valamely tartalommal kapcsolatban, kérjük jelezze e-mailes elérhetőségünkön!