Koks skirtumas tarp abstrakčios funkcijos ir virtualios funkcijos?

Kada rekomenduojama naudoti virtualų ar abstraktų? Kas yra teisingas požiūris?

1153
24 дек. Moran yra nustatytas gruodžio 24 d 2008-12-24 17:11 '08, 17:11, 2008-12-24 17:11
@ 20 atsakymų

Abstrakta funkcija negali turėti funkcionalumo. . Jūs iš esmės sakote, kad bet kuri vaiko klasė PATEIKIA savo pačios šio metodo versiją, tačiau pernelyg bendra, kad netgi bandytumėte įdiegti tėvų klasėje.

Virtuali funkcija iš esmės kalba apie išvaizdą, čia yra funkcijos, kurios gali būti pakankamai geros vaiko klasei. Todėl, jei jis yra pakankamai geras, naudokite šį metodą, jei ne, tada iš naujo apibrėžkite mane ir pateikite savo funkcijas.

2103
24 дек. Atsakymą pateikė BFree 24 Dec. 2008-12-24 17:14 '08 at 17:14 pm 2008-12-24 17:14

Abstrakta funkcija neįgyvendinama ir gali būti paskelbta tik abstrakčioje klasėje. Dėl šios priežasties gauta klasė pateikia įgyvendinimą. Virtuali funkcija suteikia numatytąjį įgyvendinimą ir gali egzistuoti abstrakčioje klasėje arba ne abstrakčioje klasėje. Taigi, pavyzdžiui:

 public abstract class myBase { //If you derive from this class you must implement this method. notice we have no method body here either public abstract void YouMustImplement(); //If you derive from this class you can change the behavior but are not required to public virtual void YouCanOverride() { } } public class MyBase { //This will not compile because you cannot have an abstract method in a non-abstract class public abstract void YouMustImplement(); } 
226
24 дек. Atsakymą pateikė JoshBerke . 2008-12-24 17:19 '08, 17:19, 2008-12-24 17:19
  • Tik abstract klasės gali turėti abstract narių.
  • Ne abstract klasė, kuri paveldi iš abstract klasės, turi override jos abstract narius.
  • abstract netiesiogiai virtual .
  • abstract narys negali suteikti jokio įgyvendinimo (kai kuriose kalbose abstract vadinamas pure virtual ).
65
16 апр. Mehrdad Afshari atsakymas, pateiktas balandžio 16 d 2009-04-16 12:03 '09, 12:03 2009-04-16 12:03

Jūs visada turite iš naujo apibrėžti abstrakčią funkciją.

Taigi:

  • Anotacijos funkcijos - kai įpėdinis turi pateikti savo įgyvendinimą
  • Virtuali - kai prieš įpėdinį nusprendžia
47
24 дек. Rinato Abdullino atsakymas gruodžio 24 d 2008-12-24 17:13 '08, 17:13, 2008-12-24 17:13

Anotacija:

  • Jis gali būti paskelbtas tik abstrakčioje klasėje.
  • Jame yra tik metodo deklaracija, kuri nėra įgyvendinimas abstrakčioje klasėje.
  • Jis turi būti iš naujo apibrėžtas išvestoje klasėje.

Virtuali funkcija:

  • Jis gali būti paskelbtas abstrakčioje ir abstrakčioje klasėje.
  • Jame yra metodo įgyvendinimas.
  • Tai gali būti atšaukta.
28
28 мая '14 в 10:52 2014-05-28 10:52 atsakymas pateikiamas Lexnim gegužės 28, 14 d. 10:52 2014-05-28 10:52

Anotacija: Kai klasėje yra abstraktus metodas, ši klasė turi būti paskelbta abstrakčia. Abstraktus metodas nėra įgyvendinamas, todėl klasės, kurios kyla iš šios abstrakčios klasės, turi užtikrinti šio abstrakčiojo metodo įgyvendinimą.

Virtualus metodas: Klasė gali turėti virtualų metodą. Virtualus metodas įgyvendinamas. Kai paveldėsite klasę, turinčią virtualų metodą, galite panaikinti virtualųjį metodą ir suteikti papildomą logiką arba pakeisti logiką savo įgyvendinimu.

Kada naudoti tai, ką: Kai kuriais atvejais žinote, kad tam tikri tipai turi turėti konkretų metodą, bet nežinote, kokį įgyvendinimą šis metodas turėtų turėti.
Tokiais atvejais galite sukurti sąsają, kurioje yra šis parašas. Tačiau, jei turite tokį atvejį, bet žinote, kad šios sąsajos kūrėjai taip pat turės kitą bendrą metodą (kurį jau galite pateikti įgyvendinant), galite sukurti abstrakčią klasę. Tuomet ši abstrakta klasė turi abstrakčią metodą (kuris turi būti iš naujo apibrėžtas) ir kitą metodą, kuriame yra „bendra“ logika.

Virtualus metodas turėtų būti naudojamas, jei turite klasę, kuri gali būti naudojama tiesiogiai, tačiau norite, kad paveldėtojai keistų tam tikrą elgesį, nors tai nėra būtina.

26
16 апр. Frederik Gheysels atsakymas balandžio 16 d 2009-04-16 12:03 '09, 12:03 2009-04-16 12:03

Abstraktus metodas yra metodas, kuris turi būti įgyvendintas tam, kad būtų sukurta konkreti klasė. Deklaracija yra abstrakčioje klasėje (ir bet kuri klasė su abstrakčiu metodu turi būti abstrakta klasė), ir ji turi būti įgyvendinta tam tikroje klasėje.

Virtualus metodas yra metodas, kuris gali būti iš naujo apibrėžtas išvestoje klasėje naudojant perregistravimą, pakeičiantį superklasės elgesį. Jei nepaisysite, gausite pradinį elgesį. Jei tai padarysite, visada gausite naują elgesį. Tai prieštarauja ne virtualiems metodams, kurių negalima pakeisti, bet gali paslėpti pradinį metodą. Tai daroma su new modifikatoriumi.

Žr. Šį pavyzdį:

 public class BaseClass { public void SayHello() { Console.WriteLine("Hello"); } public virtual void SayGoodbye() { Console.WriteLine("Goodbye"); } public void HelloGoodbye() { this.SayHello(); this.SayGoodbye(); } } public class DerivedClass : BaseClass { public new void SayHello() { Console.WriteLine("Hi There"); } public override void SayGoodbye() { Console.WriteLine("See you later"); } } 

Kai sukuriu „ DerivedClass “ egzempliorių ir skambinu SayHello arba SayGoodbye , aš gavau „Hello there“ ir „ SayGoodbye you later“. Jei paskambinsiu „ HelloGoodbye , gausiu „Sveiki“ ir „ HelloGoodbye jus vėliau“. Taip yra dėl to, kad „ SayGoodbye yra virtuali ir gali būti pakeista išvestinėmis klasėmis. SayHello paslėptas, todėl, kai jį vadinu iš savo pagrindinės klasės, gaunu savo pradinį metodą.

Anotaciniai metodai yra netiesiogiai virtualūs. Jie apibrėžia elgesį, kuris turėtų būti, labiau kaip sąsaja.

21
16 апр. Kamiel Wanrooij atsakymas, balandžio 16 d 2009-04-16 12:13 '09, 12:13, 2009-04-16 12:13

paaiškinimas: su analogijomis. Tikiuosi, kad tai padės jums.

Kontekstas

Dirbu 21-ame aukšte. Ir aš paranoiška apie ugnį. Kartais, kažkur pasaulyje, ugnis degina dangoraižį. Tačiau, laimei, mes turime instrukcijas, kaip dirbti čia, ką daryti gaisro atveju:

„Fireescape“ ()

  • Negalima rinkti daiktų
  • Pasivaikščiokite iki gaisro gelbėjimo.
  • Gedimas

Tai virtualus metodas, vadinamas „ FireEscape“ ()

Virtualus metodas

Šis planas yra gana geras 99% aplinkybių. Tai yra pagrindinis planas, kuris veikia. Tačiau yra 1% tikimybė, kad ugnies išėjimas yra užblokuotas arba sugadintas, tokiu atveju jūs visiškai prisuktas ir tapsite skrudintuvu, jei nesiimsite jokių ryžtingų veiksmų. Naudodami virtualius metodus galite tai padaryti: galite iš naujo apibrėžti „FireEscape“ () pagrindo planą su savo plano versija:

  • Paleiskite į >
  • Uždaryti >
  • Žemiau parašiutas saugus

Kitaip tariant, virtualūs metodai suteikia pagrindinį planą, kurį, jei reikia, galima pervertinti. Jei programuotojas nustato, kad tai tinkama, pogrupiai gali ignoruoti pagrindinio klasės virtualųjį metodą.

Anotacijos metodai

Ne visos organizacijos yra gerai išgręžtos. Kai kurios organizacijos nevykdo ugnies gesinimo pratimų. Jie neturi bendros pabėgimo politikos. Kiekvienas žmogus už save. Valdymą domina tik tokia esama politika.

Kitaip tariant, kiekvienas asmuo yra priverstas sukurti savo metodą FireEscape (). Vienas vaikinas išeis iš ugnies. Kitas vaikinas bus parašiutu. Kitas vaikinas naudos raketų varomąją technologiją, kad galėtų skristi nuo pastato. Kitas vaikinas išnyks. Vadovybė nesirūpina, kaip vengti, jei turite pagrindinį „FireEscape“ () planą, jei jie negali būti garantuoti. OHS ateis į organizaciją kaip tonų plytų. Tai yra tai, ką reiškia abstraktus metodas.

Koks skirtumas tarp šių dviejų?

Anotacijos metodas: poklasiai įgyvendina savo „FireEscape“ metodą. Su virtualiuoju metodu jūs turite pagrindinį planą, kuris laukia jūsų, bet jūs galite jį įgyvendinti, jei jis nėra pakankamai geras.

Dabar tai nebuvo taip sunku?

20
16 июня '16 в 4:01 2016-06-16 04:01 atsakymas pateikiamas BKSpurgeon birželio 16 d. 16 val. 4:01 2016-06-16 04:01

Anotaciniai metodai visada yra virtualūs. Jie negali būti įgyvendinami.

Tai yra pagrindinis skirtumas.

Iš esmės, jei naudojate numatytąjį įgyvendinimą, naudosite virtualųjį metodą ir norite, kad palikuonys keistų savo elgesį.

Naudodami abstrakčią metodą, jūs priversti palikuonius pateikti įgyvendinimą.

9
16 апр. atsakymas pateikiamas Rashack 16 balandžio. 2009-04-16 12:00 '09 12:00 val. 2009-04-16 12:00

Padariau lengviau atlikti keletą šių klasių patobulinimų (iš kitų atsakymų):

 using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace TestOO { class Program { static void Main(string[] args) { BaseClass _base = new BaseClass(); Console.WriteLine("Calling virtual method directly"); _base.SayHello(); Console.WriteLine("Calling single method directly"); _base.SayGoodbye(); DerivedClass _derived = new DerivedClass(); Console.WriteLine("Calling new method from derived class"); _derived.SayHello(); Console.WriteLine("Calling overrided method from derived class"); _derived.SayGoodbye(); DerivedClass2 _derived2 = new DerivedClass2(); Console.WriteLine("Calling new method from derived2 class"); _derived2.SayHello(); Console.WriteLine("Calling overrided method from derived2 class"); _derived2.SayGoodbye(); Console.ReadLine(); } } public class BaseClass { public void SayHello() { Console.WriteLine("Hello\n"); } public virtual void SayGoodbye() { Console.WriteLine("Goodbye\n"); } public void HelloGoodbye() { this.SayHello(); this.SayGoodbye(); } } public abstract class AbstractClass { public void SayHello() { Console.WriteLine("Hello\n"); } //public virtual void SayGoodbye() //{ // Console.WriteLine("Goodbye\n"); //} public abstract void SayGoodbye(); } public class DerivedClass : BaseClass { public new void SayHello() { Console.WriteLine("Hi There"); } public override void SayGoodbye() { Console.WriteLine("See you later"); } } public class DerivedClass2 : AbstractClass { public new void SayHello() { Console.WriteLine("Hi There"); } // We should use the override keyword with abstract types //public new void SayGoodbye() //{ // Console.WriteLine("See you later2"); //} public override void SayGoodbye() { Console.WriteLine("See you later"); } } } 
9
07 дек. Atsakymas pateikiamas „ MeqDotNet“ 07 gruodis. 2011-12-07 12:14 '11, 12:14, 2011-12-07 12:14

Kai kuriose vietose matiau abstrakčią metodą, kaip parodyta žemiau. **

„Abstraktus metodas turi būti įgyvendintas vaikų klasėje

** Aš tai jaučiau.

Nebūtina, kad abstraktus metodas būtų įgyvendintas vaikų klasėje , jei vaiko klasė taip pat yra abstrakta .

1) Abstraktus metodas negali būti privatus metodas. 2) Abstraktus metodas bus įgyvendinamas toje pačioje abstrakčioje klasėje.

Sakyčiau, kad jei įdiegsime abstrakčią klasę, turėsite panaikinti abstrakčius metodus iš bazinės abstrakčios klasės. Nes .. Abstrakto metodo įgyvendinimas su raktinių žodžių nepaisymu . Kaip virtualus metodas.

Nereikia, kad virtualus metodas būtų įgyvendintas paveldėtoje klasėje.

  ----------CODE-------------- public abstract class BaseClass { public int MyProperty { get; set; } protected abstract void MyAbstractMethod(); public virtual void MyVirtualMethod() { var x = 3 + 4; } } public abstract class myClassA : BaseClass { public int MyProperty { get; set; } //not necessary to implement an abstract method if the child class is also abstract. protected override void MyAbstractMethod() { throw new NotImplementedException(); } } public class myClassB : BaseClass { public int MyProperty { get; set; } //You must have to implement the abstract method since this class is not an abstract class. protected override void MyAbstractMethod() { throw new NotImplementedException(); } } 
3
05 авг. Atsakymą pateikė „ Kodoth“ 05 rug . 2015-08-05 23:45 '15, 23:45 pm 2015-08-05 23:45

Iš esmės jūs naudojate virtualų metodą, jei norite, kad įpėdiniai išplėstų funkcionalumą, jei nori.

Jūs naudojate abstrakčius metodus, kai norite, kad paveldėtojai įdiegtų funkcionalumą (ir šiuo atveju jie neturi kito pasirinkimo)

3
16 апр. Atsakymas pateikiamas Brann balandžio 16 d. 2009-04-16 12:02 '09, 12:02 2009-04-16 12:02

Anotacija (metodas):

● Anotacija - tai metodas, deklaruotas naudojant abstraktų raktinį žodį.

● Jis neturi kūno.

● Jis turi būti įgyvendintas pagal gautą klasę.

● Jei metodas yra abstraktus, klasė turi būti ištraukta.

virtualioji funkcija (metodas):

● Virtualus metodas yra būdas, deklaruotas naudojant virtualųjį raktinį žodį, ir gali būti panaikintas išvestiniu klasės metodu, naudojant perrašymo raktinį žodį.

● Tai išvestiniam klasės orui, jį iš naujo apibrėžti.

2
31 мая '16 в 16:12 2016-05-31 16:12 atsakymą pateikė Kedarnath MS gegužės 16 d. 16:12 2016-05-31 16:12

Dauguma pirmiau pateiktų pavyzdžių naudoja kodą - ir jie yra labai geri. Man nereikia pridėti to, ką jie sako, bet taip yra paprastas paaiškinimas, kuriame naudojamos analogijos, o ne kodai / techniniai terminai.

Paprastas paaiškinimas - paaiškinimas naudojant analogus

Anotacija

Pagalvokite George Bush. Jis sako savo kariams: „Eik kova Irake“. Ir tai yra. Viskas, ką jis nurodė, yra, kad jūs turite kovoti. Jis tiksliai nenurodo, kaip tai atsitiks. Bet aš turiu galvoje, jūs negalite tiesiog išeiti ir „kovoti“: ką tai reiškia? Ar aš kovoju su B-52 ar mano derringeriu? Šios konkrečios detalės paliekamos kitiems. Tai abstraktus metodas.

Virtualus metodas

David Petraeus yra aukštas armijoje. Jis apibrėžė, kokią kovą reiškia:

  • Rasti priešą
  • Neutralizuokite.
  • Po šio alaus

Problema ta, kad tai yra labai bendras metodas. Tai geras metodas, kuris veikia, bet kartais nepakankamai konkretus. Geras dalykas Petraeui yra tai, kad jo įsakymai turi veiksmų laisvę ir gebėjimą - jis leido kitiems pakeisti savo „mūšio“ apibrėžimą pagal jų konkrečius reikalavimus.

Privatus darbas „Bloggs“ skaito Petraeuso užsakymą ir gauna leidimą įgyvendinti savo pačios mūšio versiją pagal jo specialius reikalavimus:

  • Rasti priešą.
  • Šaudyk galvą.
  • Eikite į pagrindinį puslapį
  • Alus

Nuri al Maliki taip pat gauna tuos pačius užsakymus iš „Petraeus“. Jis taip pat turi kovoti. Bet jis yra politikas, o ne pėstininkas. Akivaizdu, kad jis negali šaudyti savo politinių priešų galvos. Kadangi Petraeus jam suteikė virtualų metodą, Maliki gali įgyvendinti savo kovos metodo versiją pagal savo konkrečias aplinkybes:

  • Rasti priešą.
  • Paprašykite jo suimti keletą kaltinamų BS.
  • Eikite į pagrindinį puslapį
  • Alus

Kitaip tariant, virtualus metodas suteikia komandų komandas - bet tai yra bendrieji nurodymai, kurie gali būti labiau konkretūs armijos hierarchijos žmonėms pagal jų konkrečias aplinkybes.

Skirtumas tarp šių dviejų

  • Džordžas Bušas neįrodė įgyvendinimo detalių. Tai turi atlikti kažkas kitas. Tai abstraktus metodas.

  • Petraeus, kita vertus, pateikia išsamią informaciją apie įgyvendinimą, bet davė savo pavaldiniams leidimą iš naujo apibrėžti savo užsakymus su savo versija, jei jie gali pateikti kažką geresnio.

Tikiuosi, kad tai padės.

2
06 мая '16 в 3:48 2016-05-06 03:48 atsakymas pateikiamas BKSpurgeon 06 gegužės 16 d. 3:48 2016-05-06 03:48

Abstrakta funkcija negali turėti kūno ir ją reikia iš naujo apibrėžti pagal vaikų klases.

Virtuali funkcija turės kūną ir gali būti ignoruojama vaiko klasių.

2
12 янв. atsakymas duotas Yeasin Abedin Siam sausio 12 d 2016-01-12 20:17 '16 at 20:17 2016-01-12 20:17

Susiejimas yra pavadinimo susiejimo su kodo procesu procesas.

Vėlesnis įpareigojimas reiškia, kad mes naudojame pavadinimą, bet atidedame ekraną. Kitaip tariant, mes pirmiausia sukuriame / paminėjome pavadinimą ir leidžiame tam tikram vėlesniam procesui valdyti šio pavadinimo ekraną.

Dabar apsvarstykite:

  • Palyginti su žmonėmis, automobiliai yra tikrai geri ieškant ir rūšiuojant.
  • Palyginti su automobiliais, žmonės yra tikrai geri kurdami ir tobulindami.

Taigi, trumpas atsakymas yra toks: virtual yra pavėluotas nurodymas prijungti prie mašinos (runtime), o abstract - paskutinis privalomas nurodymas asmeniui (programuotojas)

Kitaip tariant, virtual priemonės:

„Gerbiamasis laikas , susieti atitinkamą kodą su šiuo pavadinimu atlikdami tai, ką darote geriausiai: paieška“

abstract reiškia:

„Gerbiamas programuotojas Pridėkite atitinkamą kodą prie šio pavadinimo atlikdami tai, ką darote geriausiai: kurkite „

Dėl išsamumo perkrova reiškia:

„Gerbiamas kompiliatorius , prijunkite atitinkamą kodą prie šio pavadinimo, atlikite tai, kas geriausiai tinka jums: paieška (ir rūšiavimas).“

2
13 авг. Rodrick Chapman atsakymas, pateiktas rugpjūčio 13 d 2017-08-13 23:06 '17 - 11:06 2017-08-13 23:06

Iš bendro objekto orientuoto rodinio:

Kalbant apie abstraktų metodą . Kai jūs įtraukiate abstrakčią metodą tėvų klasei, pasakykite vaiko klasėms: Ei, atkreipkite dėmesį, kad turite tokį metodo parašą. Ir jei norite ją naudoti, turite įgyvendinti savo!

Kalbant apie virtualią funkciją : kai įdedate virtualųjį metodą tėvų klasėje, jūs sakote išvestoms klasėms: Ei, čia yra funkcionalumas, kuris daro kažką jums. Jei tai naudinga, tiesiog naudokite. Jei ne, pakeiskite jį ir įveskite savo kodą, netgi galite naudoti savo įgyvendinimą savo kode!

tai yra tam tikra filosofija apie šių dviejų sąvokų skirtumą apskritai OO

1
01 марта '17 в 13:35 2017-03-01 13:35 Atsakymą pateikė Mohammad Nikravesh kovo 1 d. 17 d. 13:35 2017-03-01 13:35

Niekas nesukelia virtualios klasės C #.

Funkcijoms

1.Abstrakcijos funkcija turi tik parašą, diskų klasė turi būti iš naujo apibrėžta funkcionalumu. 2. Virtualioje funkcijoje bus dalis funkcionalumo, diskų klasė gali arba negali jį pakeisti pagal reikalavimą.

Jūs galite nuspręsti su savo reikalavimu.

1
07 июня '16 в 17:41 2016-06-07 17:41 Atsakymą pateikė Nithila Shanmugananthan birželio 07 d. 16, 17:41 2016-06-07 17:41

Atsakymas buvo pateiktas kelis kartus, tačiau klausimas, kada naudoti kiekvieną iš jų, yra sprendimas projektavimo metu. Manau, kad yra gera praktika bandyti sujungti bendras metodų apibrėžtis į skirtingas sąsajas ir ištraukti jas į klases su atitinkamu abstrakcijos lygiu. Bendro abstrakčių ir virtualių metodų apibrėžimų rinkinio panaikinimas klasėje daro klasę nestabilią, kai geriausia apibrėžti ne abstrakčią klasę, kuri įgyvendina suspaustų sąsajų rinkinį. Kaip visada, tai priklauso nuo to, kas geriausiai tinka jūsų konkrečiai programai.

1
19 авг. atsakymas pateiktas ComeIn 19 aug. 2013-08-19 13:28 '13, 13:28, 2013-08-19 13:28

Kaip suprantu:

Anotacijos metodai:

Tik abstrakta klasė gali turėti abstrakčių metodų. Be to, išvestinė klasė turi įgyvendinti metodą, o įgyvendinimas klasėje nėra įgyvendinamas.

Virtualūs metodai:

Klasė gali juos paskelbti ir užtikrinti jų įgyvendinimą. Be to, išvestinė klasė turi įdiegti metodą, kuriuo jis būtų panaikintas.

-2
27 июня '11 в 18:37 2011-06-27 18:37 atsakymą įteikė Kaiseris birželio 27 d. 11 d. 18:37 2011-06-27 18:37