15. maj 2008 - 00:35Der er
12 kommentarer og 1 løsning
Sealed metode i en abstrakt klasse
Hej Eksperter
Hvordan kan jeg oprette en sealed metode i en abstrakt klasse?
Jeg har en klasse som skal fungere som "base" for alle andre klasser i mit projekt. Selve "basen" er abstract. Basen har dog et par metoder jeg ikke vil tillade bliver overskrevet i de klasser der nedarver fra min "base". Bla. har jeg en methode til logging af programbeskeder osv. Den vil jeg ikke har blive ændret.
Hvordan angiver jeg dét? Jeg har forsøgt mig med "public sealed void" osv., men jeg får at vide det ikke er tilladt.
Mød en af Nordens fremmeste eksperter i adfærdsdesign – Morten Münster, der bl.a. har skrevet ” Jytte fra marketing er desværre gået for i dag” – på Computerworld Cloud & AI Festival.
Tak for svaret. Kan det virkeligt passe, at jeg i så tilfælde må gå på kompromis med mine nuværende design ideer? Jeg vil gerne lave et framework til andre udviklere hvor de kan lave udvidelser til min applikation (kræver blot at de nedarver fra mine baseclasses), men jeg vil gerne have noget funktionalitet som de ikke kan få lov til at rode med.
class Program { static void Main(string[] args) { B b = new B(); b.M(); b.M2(); A a = b; a.M(); a.M2(); } }
public abstract class A { public void M() { Console.WriteLine("A.M"); } public virtual void M2() { Console.WriteLine("A.M2"); } }
public class B : A { public new void M() { Console.WriteLine("B.M"); } public override void M2() { Console.WriteLine("B.M2"); } } ===============================================================
som giver:
B.M B.M2 A.M B.M2
den metode som ikke er makeret virtual, kan kun overskrives ved brug af new keywordet, og læg mårke til at selv om du i alle tilfælde har fat i en B, så når du betragter den som en A (Up caster den). Så er det A's M() der bliver kaldt og IKKE B's...
modsat med den der er makeret med virtual og kan overskrives med keywordet override, her bliver B's metode altid kaldt hvad end vi betragter objectet som A eller B.
Hej begge. Jeg kan fint følge jeres eksempler, men humlen i det jeg gerne vil hen til, er at mine "kunder" ikke må lave deres egen implementation af én eller flere metoder i min baseclass. Det kan jeg så forstå, at jeg ikke kan sikre mig. Dét jeg egentligt gerne ville, var at sikre mig imod, at kunderne kunne anvende New keywordet på f.eks metode M
De kan jo under alle omstaendigheder lave en MM metode.
Og der er ikke rigtig forskel paa om de kalde deres MM eller new M.
Hvad er din bekymring ?
Dit eksempel med logning boer ikke vaere et problem. Al din kode vil kalde din lognings metode. Og det er vel ikke dit ansvar hvilken lognings metode deres kode kalder.
Mit "problem" er, at jeg vil være 100% sikker på, at det altid er min - og kun min - implementering der bliver kaldt.
Der er tale om udvikling af et framework, hvor kunden kan tilpasse dele af funktionaliteten via nedarvning fra abstrakte klasser, samtidig med at andre dele er låst fast - herunder logging. For at sikre at loggingen altid følger samme metodik - og skriver samme sted - er det derfor vigtigt for mig, at kunden ikke overskriver denne funktionalitet.
Hvis M er ikke virtual vil kode skrevet af dig altid kalde din M.
Hvis det er kode skrevet af kunden saa kan han kalde en MM metode eller en new M metode.
Du kan jo aabenlyst ikke forhindre ham i at lave en MM metode. Men C# giver dig heller ikke mulighed for at forhindre ham i at lave en new M metode.
Hvis hans logning skal vaere konsistent med din logning, saa maa du dokumentere hvad de skal goere.
Eller hvis du er til den slags saa lever en build procedure de skal bruge som injecter al logning via AOP.
De kan stadig bruge en anden build procedure, men at genbruge en build procedure der virker er nok mere sandsynligt end at de faktisk laeser dokumentation. Dokumentation er jo som bekdnt noget man foerst laeser naar det ikke virker.
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.