Avatar billede mj89dk Nybegynder
26. oktober 2007 - 23:10 Der er 11 kommentarer og
2 løsninger

Virtuelle metoder og andet

Hej :)

Jeg er i gang med at læse Teach Yourself The C# Language in 21 Days og er stødt på nogle ting som jeg ikke helt forstår.

Jeg har en klasse der hedder Person med bl.a. den virtuelle (virtuel) metode displayFullName().

Dernæst har jeg en Employee-klasse der nedarver fra Person, og med override laver en ny displayFullName().

Han skriver så følgende:

Person me = new Employee(“Bradley”, “Jones”, 1983);

Det er fint nok, og når jeg kalder funktionen er det Employees der bliver brugt. Men hvordan kan det være at han i første omgang ikke bare skriver:

Employee me = new Employee(“Bradley”, “Jones”, 1983);

Umiddelbart ville jeg ikke mene der var nogen forskel.



Derudover har jeg et andet spørgsmål (samme udgangspunkt mht metoder som før):



Person me = new Employee("Bradley", "Jones", 1983);

me.displayFullName(); // bruger Employees funktion, ikke base-klassens

Console.WriteLine("me er en {0}", me.GetType()); // returnerer Employee

// TestF er defineret i Employee

(me as Employee).TestF(); // virker


me.TestF(); // virker ikke


Hvordan kan det være at hvis me er en Employee, hvorfor kan jeg så ikke tilgå dens funktioner direkte?


Håber I forstår mig :)

Hilsen Mark

PS. Jeg har også spurgt på udvikleren, men ville gerne høre fra flere mennesker som evt. arbejder med C# dagligt
Avatar billede mr-kill Nybegynder
26. oktober 2007 - 23:43 #1
Skal sige fra starten at jeg ikke har "lært" C# i skole eller noget, men gjorde det på samme måde som dig, så hvis hvis nogen fortæller dig at jeg tager fejl så skal du nok tro på dem. Jeg arbejder dog med C# ofte, så ved en smule om det ;)

I spørgsmål nummer 2:

(me as Employee).TestF(); // virker
me.TestF(); // virker ikke

Når du skriver: Person me = new Employee("Bradley", "Jones", 1983);

Så er "me" af typen Person, den bruger bare Person's child constructor. Det vil sige at "me" bliver betragtet som Person og kan derfor kun bruge ting fra klasser som Person selv arver fra (går du fra det kun er klassen object - som alle klasser arver fra). Den kan derfor ikke bruge Employee's funktioner uden at du først laver typen om (Det er det du gør med (me as Employee)). En klasse kan "kun" læse op i hiakiet, ikke ned:
object
|
--Person
  |
  --Employee

Grunden til dette:
me.displayFullName(); // bruger Employees funktion, ikke base-klassens

Da du i Employee overrider den metode, så er det den overridede metode der bruges.

Jeg ved ikke om det besvarer spørgsmål 1 også?
Avatar billede mj89dk Nybegynder
26. oktober 2007 - 23:55 #2
Så giver du jo meget mere mening :)

Og så går jeg ud fra at GetType() også bliver overridden?

Men jeg forstår stadig ikke fordelen ved at bruge Person i spørgsmål 1.

Hilsen
Mark
Avatar billede mj89dk Nybegynder
26. oktober 2007 - 23:58 #3
Så er "me" af typen Person, den bruger bare Person's child constructor.

Her mener du vel Emp.'s constructor, ikke?
Avatar billede mr-kill Nybegynder
27. oktober 2007 - 00:04 #4
jo Emp er child af Person.

GetType() fortæller hvilken constructor der blev brugt til at lave objectet. (med mindre du skifter type bagefter)

"Men jeg forstår stadig ikke fordelen ved at bruge Person i spørgsmål 1.":
Det kommer an på hvad der ellers er i klassen. Ud fra det du har skrevet ville jeg bruge Employee me = ...
Kan faktisk ikke lige komme nogen steder hvor det kan være en fordel at bruge Person me = ... og så bruge en constructor fra en klasse der arver fra Person. Hvis det er fordi man gerne vil bruge noget fra Person og ikke Employee så kan man jo bare bruge (me as Person). Mon ikke han bare skriver det for at vise at man KAN gøre det?
Avatar billede mj89dk Nybegynder
27. oktober 2007 - 00:10 #5
Ah, ja, okay, så forstår jeg :)

Du har nok ret mht Person vs Emp. Ellers betyder det nok ikke det store. Vil du lægge svar nu, eller skal jeg vente til i morgen og se om der evt kommer flere svar?
Avatar billede mr-kill Nybegynder
27. oktober 2007 - 00:16 #6
Det bestemmer du helt selv. Jeg prøver bare at hjælpe, så godt jeg kan. Du må gerne vente og se om der er nogen der mener noget andet i morgen. Men vil gerne ha' point ellers :)

Giv evt. karma hvis du lyster, det mangler jeg :P
Avatar billede mr-kill Nybegynder
27. oktober 2007 - 00:22 #7
Mange tak for karma :)

Jeg lægger et svar nu og så kan du bare vente til i morgen med at gøre noget, så kan du jo lige høre om det er noget sludder jeg fortæller dig ;)
Avatar billede arne_v Ekspert
27. oktober 2007 - 05:32 #8
#2 er forklaret, men en side bemærkning - jeg ville skrive:

(me as Employee).TestF();

som:

((Employee)me).TestF();
Avatar billede arne_v Ekspert
27. oktober 2007 - 05:36 #9
Med hensyn til spørgsmål #1, så:

Person me = new Employee("Bradley", "Jones", 1983);

giver god mening i masser af sammenhænge.

Og grunden er sådan se spørgsmål #2 !!!!

Hvis koden nedenunder skal kunne processe alle slags Person, så kan man ved at gøre
me til typen Person sikre at man ikke uden videre kan kalde metoder som er
specifikke for Employee.

Læs evt. også http://en.wikipedia.org/wiki/Polymorphism_in_object-oriented_programming
Avatar billede mj89dk Nybegynder
27. oktober 2007 - 10:25 #10
Okay, så har jeg fået besvaret det jeg ville :) smider du også et svar, arne_v?
Avatar billede mr-kill Nybegynder
27. oktober 2007 - 12:44 #11
Ahh ja du har som altid helt ret arne_v. Hvis der er flere klasser der arver fra Person og så f.eks. vil samle en masse forskellige Person childs i f.eks. et array.

Med hensyn til:
(me as Employee).TestF();
vs.
((Employee)me).TestF();

Er der så nogen forskel? Ud over du måske synes nummer 2 er lettest at skrive (Jeg synes det ikke)
Avatar billede arne_v Ekspert
27. oktober 2007 - 17:08 #12
Person[] eller List<Person> eller Dictionary<string,Person> etc..

Forskellen er hvis me ikke er en Employee.

Den første giver en NullReferenceException - den anden giver en InvalidCastException.
Avatar billede arne_v Ekspert
27. oktober 2007 - 17:09 #13
og et svar
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester