1 / 33

C# pentru începători

L1. C# pentru începători. Florin Tudor Cristea · Microsoft Student Partners. .NET Framework.

carson
Download Presentation

C# pentru începători

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. L1 C#pentruîncepători Florin Tudor Cristea· Microsoft Student Partners

  2. .NET Framework Microsoft .NET Framework reprezintă un cadru de dezvoltare software care poate fi instalat pe maşinile ce rulează familia de sisteme de operare Microsoft Windows (există însă în desfăşurare un proiect open-source şi cross-platform denumit Mono ce promite un ecosistem mai larg pentru aplicaţiile din familia .NET). Acesta include o bibliotecă vastă de soluţii la cele mai comune probleme de programare şi o maşină virtuală care gestionează execuţia programelor scrise specific pentru el.

  3. Base Class Library Base Class Library (BCL) constituie o bibliotecă standard disponibilă tuturor limbajelor ce folosesc framework-ul .NET. Oferă o paletă largă de soluţii referitoare la interfaţa cu utilizatorul, accesul la fişiere şi baze de date, criptografie, dezvoltarea de aplicaţii web, algoritmi numerici, comunicarea în reţea şi nu numai. Este folosită de către programatori, care o combină cu propriul lor cod pentru a produce aplicaţii software. System, System.Collections, System.Diagnostics, System.Globalization, System.IO, System.Net, System.Reflection, System.Runtime, System.Security, System.Text, System.Threading

  4. Common Language Runtime Programele scrise pentru framework-ul .NET sunt executate într-un mediu software care gestionează cerinţele programelor în timpul rulării. Acesta poartă numele de Common Language Runtime (CLR) şi oferă caracteristicile unei maşini virtuale, fapt ce permite programatorilor să creeze aplicaţii fără să îşi facă probleme legate de arhitectura procesorului de pe care vor rula acestea. De asemenea, CLR-ul se ocupă şi de alte servicii importante precum managementul memoriei, securitate şi manipularea excepţiilor. BCL+ CLR = .NET Framework

  5. Common Language Infrastructure Common Language Infrastructure (CLI) este o specificaţie deschisă dezvoltată de către Microsoft ce defineşte un mediu software care permite ca multiple limbaje de nivel înalt să poată fi folosite pe diferite platforme de operare fără să fie necesar ca acestea să fie rescrise pentru arhitecturi specifice (.NET Framework, Mono, Portable.NET implementează aceste standarde). Termeni cheie: Common Type System (CTS), Metadata, Common Language Specification (CLS), Virtual Execution System (VES)

  6. CIL este un limbaj de asamblare orientat obiect, bazat în întregime pe stack (stivă) în ceea ce priveşte alocarea memoriei.

  7. Limbaje CLI C#, C++/CLI, F#, J#, IronPython, VB.NET, A#, Active Oberon, APLNext, AVR.NET, Boo, Cobra, Common Larceny, Component Pascal, Delphi.NET, Delta Forth .NET, DotLisp, dylan.NET, EiffelEnvision, Fortran.NET, Gardens Point Modula-2/CLR, Haskell for .NET, Hugs for .NET, IoNET, IronLisp, IronRuby, IronScheme, Ja.NET, JScript.NET, L#, Lexico, LOLCode.NET, Lua.NET, Managed Extensions for C++, Managed Jscript, Mercury on .NET, Mondrian, Nemerle, Net Express, NetCOBOL, Oxygene, OxygenScheme, P#, Phalanger, Phrogram, PL/IL, PowerBuilder, S#, sml.net, VBx, Wildcat Cobol, Windows PowerShell, X#, Zonnon, #S, #Smalltalk, ···

  8. Despre C# C# este un limbaj de programare cu scop general, puternic tipizat, orientat obiect. Caracterizat prin simplitate, expresivitate şi performanţă, C# uşurează mult scrierea diverselor aplicaţii (este optimizat pentru cadrul de dezvoltare .NET). Cea mai recentă versiune a limbajului este 3.0, lansată concomitent cu .NET Framework 3.5 în 2007. Următoarea versiune propusă, 4.0, se află în dezvoltare (beta din mai 2009).

  9. Despre Visual Studio Microsoft Visual Studio este un mediu integrat de dezvoltare (IDE — Integrated Development Environment) produs de Microsoft. Poate fi folosit atât pentru a dezvolta aplicaţii tip consolă sau cu interfaţă grafică (Windows Forms) cât şi situri, aplicaţii şi servicii web — atât în cod nativ cât şi în cod gestionat, pe toate platformele suportate de către Microsoft Windows, Windows Mobile, Windows CE, .NET Framework, .NET Compact Framework şi Microsoft Silverlight. Versiunea 2008 Professional poate fi descărcată de pe MSDNAA (msdn.info.uaic.ro) sau DreamSpark (dreamspark.com).

  10. Crearea unui proiect Numele proiectului

  11. Rularea unui proiect using System; namespace HelloWorld { class Program { staticvoid Main(string[] args) { Console.WriteLine("Hello, world!"); } } }

  12. Elemente de sintaxă C#

  13. Elemente de sintaxă C# Cuvinte rezervate:abstract, as, base, bool, break, by, byte, case, catch, char, checked, class, const, continue, decimal, default, delegate, do, double, descending, explicit, event, extern, else, enum, false, finally, fixed, float, for, foreach, from, goto, group, if, implicit, in, int, interface, internal, into, is, lock, long, new, null, namespace, object, operator, out, override, orderby, params, private, protected, public, readonly, ref, return, switch, struct, sbyte, sealed, short, sizeof, stackalloc, static, string, select, this, throw, true, try, typeof, uint, ulong, unchecked, unsafe, ushort, using, var, virtual, volatile, void, while, where, yield Utilizarea unui cuvânt rezervat ca un identificator: string @out;

  14. Literali

  15. Elemente de sintaxă C# int a, b;// declarare multiplă int a = 2, b = 3; /*declarare cu iniţializare multiplă */ Declarare /* const vs. readonly */ class Foo { constint x1 = 1; constint x2; // eroare readonlyintx3 = 3, x4, x5; Foo() // corect deşi x5 nu e iniţ. { x4 = 4; // corect constint x6 = 6; readonlyint x7 = 7; // eroare } } /* constantele const sunt implicit statice */ /* Inferenţa de tip (type inference) */ var MyChars = newchar[] {'A', 'Ö'}; /* sau char[] MyChars = new char[] {'A', 'Ö'}; */ = identificatori cu valori asociate Declarare cu iniţializare Iniţializare

  16. Elemente de sintaxă C# void foo() { int a; { intb; a = 1; } // alt ‘scope’ a = 2; b = 3; // eroare } staticintvoid Main(string[] args) { return 0; } Metoda Main – punctul de intrare al aplicaţiei namespace Foo { class Bar { ... } class Lol { ... } class Cat { ... } } Domenii de cod (scopes) Spaţii de nume (namespaces) using System; usingDirInfo = System.IO.DirectoryInfo; Directiva using

  17. /* termeni cheie: implicit şi explicit (construcţia operatorului de conversie implicită sau explicită), as (operatorul de conversie tacită) */ /* signatura supraîncărcării unui operator binar */ public static Complexoperator +(Complex c1, Complex c2) { ... } using System; publicclass Pointer { unsafe static void Main() { int i = 5; int* j = &i; Console.WriteLine(*j); } } // Output: 5 /*compilatorul trebuie invocat cu opţiunea/unsafe*/ Operatori

  18. if (boolean) { ... } else if (boolean) { ... } else { ... } switch(pivot) { case 'A': ... break; case 'B': case 'C': ... break; default: ... break; } do { ... } while (boolean) while (boolean) { ... } for (int i = 0; i < 10; i++) { ... } foreach (int i in intList) { ... } Structuri condiţionale Structuri iterative try { /* instrucţiuni ce pot arunca excepţii */ ... } catch (Exception ex) { /* excepţia este prinsă şi tratată aici */ ... } finally { /* instrucţiuni invariabil executate ulterior */ ... } start: ... gotostart; Instrucţiuni de salt for (int i = 0; i < 10; i++) { if (i % 2 == 0) { continue; } Console.Write(i + “ “); } // 1 3 5 7 9 for (int i = 0; i < 10; i++) { if (i == 5) { break; } Console.Write(i + “ “); } // 0 1 2 3 4 Structuri de control

  19. Elemente de programare orientată obiect Concepte fundamentale Clasă Defineşte caracteristicile abstracte ale unui lucru (obiect), inclusiv caracteristicile (atribute, câmpuri, proprietăţi) şi comportamentul (acţiuni, metode, operaţii) acestuia. Poată fi privită ca o schiţă (blueprint) care descrie ceva. Spre exemplu, clasa Dog ar include caracteristici comune tuturor câinilor, precum rasa şi culoarea blănii (caracteristici), precum şi abilitatea de a lătra şi şedea (comportamente). Clasele oferă astfel modularitate şi structură într-un program orientat obiect. De obicei conceptul implementat de către o clasă este recognoscibil inclusiv unui non-programator familiar cu domeniul problemei, caracteristicile clasei pur şi simplu având sens în context. De asemenea, codul unui clase se presupune a fi relativ independent (self-contained), utilizând principiul încapsulării (encapsulation). Colectiv, proprietăţile şi metodele unei clase se numesc membri.

  20. Elemente de programare orientată obiect Obiect O instanţă a unei clase. Clasa Dog defineşte toate tipurile posibile de câini listând caracteristicile şi comportamentele pe care le pot afişa; obiectul Lassie este un câine particular, cu versiuni particulare ale acestor trăsături. Un câine (Dog) are blana de o culoare oarecare; Lassie în schimb are blana de culoare maro cu alb, fiind un collie. Ansamblul valorilor proprietăţilor unui anumit obiect definesc starea acestuia. Metodă Abilităţile unui obiect. În limbaj natural metodele (referite uneori şi drept “funcţii”) sunt verbe. Lassie, fiind un câine (Dog), poate lătra – deci bark()este una din metodele sale. Mai poate prezenta desigur şi alte metode, precum sit()sau eat()sau walk()sau save_timmy(). De obicei utilizarea unei metode în program afectează numai un obiect vizat; toţi câinii (Dog-s) pot lătra, dar ne interesează ca numai unul oarecare să facă aceasta.

  21. using System; namespace HelloWorld { classDog { string breed, fur_color; // câmpuri public Dog(string breed, string fur_color) // constructor { this.breed = breed; this.fur_color = fur_color; } publicstring Breed // accesor { get { returnthis.breed; } set { this.breed = value; } } publicstring Fur_color // <prop> + <TAB> { get { return this.fur_color; } set { this.fur_color = value; } } public void bark() { Console.WriteLine("Woof!"); Console.Beep(); } } classProgram { static void Main(string[] args) { Dog Lassie = newDog("collie", "brown-and-white"); // crearea unei instanţe a clasei Dog Lassie.Fur_color = "brown-and-pearl"; Console.WriteLine("Lassie is a " + Lassie.Breed + " with " + Lassie.Fur_color + " fur."); Lassie.bark(); } } } Exemplu Lassie is a collie with brown-and-pearl fur. Woof!

  22. Elemente de programare orientată obiect Moştenire “Sub-clasele” sunt versiuni mai specializate ale unei clase părinte care moştenesc atributele şi comportamentele acesteia, adăugând în acelaşi timp un subset propriu. Spre exemplu, clasa Dog poate avea sub-clasele denumite Collie, Chihuahua şi GoldenRetriever. În acest caz, obiectul Lassie ar fi o instanţă a sub-clasei Collie. Să presupunem că în clasa Dog sunt definite o metodă denumită bark() şi o proprietate denumită furColor. Fiecare din sub-clasele sale (Collie, Chihuahua şi GoldenRetriever) va moşteni aceşti membri, ceea ce înseamnă că programatorul trebuie să scrie codul pentru toate acestea o singură dată. Fiecare sub-clasă poate modifica caracteristicile moştenite. Spre exemplu, clasa Collie poate specifica o valoare predefinită pentru furColor, maro cu alb. Clasa Chihuahua poate utiliza o tonalitate mai înaltă la generarea unui lătrat via metoda bark(). Sub-clasele pot de asemenea să adauge noi membri – Chihuahua poate prezenta o metodă denumită tremble(). Deci o instanţă individuală de tip Chihuahua, fie aceasta Tinkerbell, ar folosi metoda bark()cu tonalitate înaltă din sub-clasă, care mai departe a moştenit metoda bark()normală din Dog. Tinkerbell ar prezenta metoda tremble(), dar Lassie nu – deoarece este un Collie, nu un Chihuahua. De fapt, moştenirea este o relaţie de tip “un… este un” între clase, în timp ce instanţierea este o relaţie de tip “este un” între un obiect şi o clasă: un Collie este un Dog, dar Lassie este un Collie. Deci obiectul numit Lassie are metodele din ambele clase Collie şi Dog.

  23. using System; namespace HelloWorld { classDog { protectedstring breed, fur_color; // public Dog() // { // } public Dog(string breed, string fur_color) { this.breed = breed; this.fur_color = fur_color; } publicstring Breed { get { returnthis.breed; } set { this.breed = value; } } publicstring Fur_color { get { returnthis.fur_color; } set { this.fur_color = value; } } public void bark() { Console.WriteLine("Woof! [" + this.GetType() + "]"); Console.Beep(); } } classCollie : Dog { public Collie() : base("collie", "brown-and-white") { // base.breed = "collie"; // base.fur_color = "brown-and-white"; } } classChihuahua : Dog { public Chihuahua(stringfur_color) : base("chihuahua", fur_color) { // base.breed = "chihuahua"; // base.fur_color = fur_color; } public new void bark() { Console.WriteLine("Woof! [" + this.GetType() + "]"); Console.Beep(1500, 250); } } classProgram { static void Main(string[] args) { Collie Lassie = newCollie(); Lassie.Fur_color = "brown-and-pearl"; Console.WriteLine("Lassie is a " + Lassie.Breed + " with " + Lassie.Fur_color + " fur."); Lassie.bark(); Chihuahua Tinkerbell = newChihuahua("caramel"); Console.WriteLine("Tinkerbell is a " + Tinkerbell.Breed + " with " + Tinkerbell.Fur_color + " fur."); Tinkerbell.bark(); } } } Exemplu Lassie is a collie with brown-and-pearl fur. Woof! [HelloWorld.Collie] Tinkerbell is a chihuahua with caramel fur. Woof! [HelloWorld.Chihuahua]

  24. Elemente de programare orientată obiect Încapsulare Încapsularea ascunde detaliile funcţionale ale unei clase de obiectele care îi transmit mesaje (pasează date sau invocă o metodă). Spre exemplu, clasa Dog are o metodă bark(). Codul pentru această metodă defineşte exact ce se întâmplă când câinele latră (inhale()apoi exhale()la o anumită tonalitate şi volum). Însă Timmy, prietenul lui Lassie, nu are nevoie să ştie aceste detalii. Încapsularea este realizată specificând anume care clase pot utiliza membrii unui obiect. Rezultatul este că fiecare obiect expune oricărei clase o anumită interfaţă – membrii accesibili acelei clase. Motivaţia din spatele încapsulării este aceea de a împiedica clienţii unei interfeţe să depindă de acele părţi ale implementării care vor fi cel mai probabil supuse schimbărilor în viitor – ceea ce facilitează procesul de modificare fără a afecta pe cineva. Membrii sunt specificaţi ca fiind public(publici), protected(protejaţi) , private (privaţi) sau internal (interni), determinând astfel dacă sunt accesibili tuturor claselor, sub-claselor, clasei ce îi defineşte sau numai claselor din acelaşi assembly (default = private).

  25. Elemente de programare orientată obiect Polimorfism Polimorfismul permite programatorilor să trateze membrii claselor derivate exact la fel precum membrii claselor părinte. Mai precis, acesta reprezintă abilitatea obiectelor de tipuri diferite să răspundă apelurilor unei metode specifice cu acelaşi nume, fiecare în maniera dictată de felul său. O metodă – sau un operator precum +, - sau * – poate fi aplicat abstract în o multitudine de situaţii. Dacă se emite comanda speak()unui obiect de tip Dog, va rezulta un apel către metoda bark(). În schimb, un obiect de tip Pig va răspunde în aceeaşi situaţie cu un apel către metoda oink(). Amândoi moştenesc speak()din Animal, dar clasele lor derivate suprascriu (override) metodele din clasa părinte – polimorfism de suprascriere. Polimorfismul de supraîncărcare (overload) constituie utilizarea unei signaturi caracteristice a metodei sau folosirea unui operator pentru a efectua diferite operaţii în funcţie de implementare. Operatorul +, de exemplu, poate fi întrebuințat pentru a executa adunarea unor întregi sau numere în virgulă mobilă sau concatenarea şirurilor. Oricare două sub-clase ale Number – precum Integer şi Double – trebuie să fie capabile să facă o sumă de termeni fără probleme, deci operatorul de adiţie, +, trebuie supraîncărcat corespunzător.

  26. using System; namespace HelloWorld { classEmployee { publicstring name; protecteddecimal basepay; public Employee(string name, decimal basepay) { this.name = name; this.basepay = basepay; } public virtualdecimal CalculatePay() { return basepay; } } sealedclassFieldEmployee : Employee // sealed = clasa nu mai poate fi moştenită { privatedecimal fieldbonus; public FieldEmployee(string name, decimal basepay, decimal fieldbonus) : base(name, basepay) { this.fieldbonus = fieldbonus; } public FieldEmployee(string name, decimal basepay) // overload : base(name, basepay) { this.fieldbonus = 0; } publicoverridedecimal CalculatePay() // override { return basepay + fieldbonus; } } classProgram { static void Main(string[] args) { FieldEmployee employee1 = newFieldEmployee("The Cheshire Cat", 1000, 500); Employee employee2 = newEmployee("Alice", 1200); Console.WriteLine(employee1.name + " earned: " + employee1.CalculatePay()); Console.WriteLine(employee2.name + " earned: " + employee2.CalculatePay()); } } } Exemplu The Cheshire Cat earned: 1500 Alice earned: 1200

  27. using System; namespace HelloWorld { classParent { public virtual void Foo() { Console.WriteLine("Parent > Foo()"); } public void Bar() { Console.WriteLine("Parent > Bar()"); } } classChild : Parent { public override void Foo() // overriding { Console.WriteLine("Child > Foo()"); } public new void Bar() // hiding { Console.WriteLine("Child > Bar()"); } } classProgram { static void Main(string[] args) { Parent parent = newParent(); Child child = newChild(); parent.Foo(); parent.Bar(); child.Foo(); child.Bar(); parent = child; parent.Foo(); // metoda apelată ţine de tipul instanţei parent.Bar(); // metoda apelată ţine de tipul variabilei } } } Parent > Foo() Parent > Bar() Child > Foo() Child > Bar() Child > Foo() Parent > Bar() Exemplu

  28. Alte particularităţi System.Object este clasa părinte a tuturor celorlalte clase din BCL (rădăcina ierarhiei de tipuri). Implicit, principalele metode (virtuale) moştenite sunt Equals (suportă compararea a două obiecte), Finalize (destructorul default, se ocupă de curăţenie înainte ca obiectul să fie rechiziţionat automat de către garbage collector), GetHashCode (generează un număr corespunzător stării unui obiect pentru a face posibilă utilizarea tabelelor hash), ToString (returnează un şir lizibil uman referitor la instanţa unei clase). Clasele sunt tipuri referinţă şi structurile sunt tipuri valoare. O structură este alocată pe stivă atunci când este declarată şi variabila corespunzătoare este direct referită prin adresa sa. Clasele sunt diferite prin aceea că memoria este alocată pe heap şi variabila în acest caz se comportă ca un pointer gestionat plasat pe stack ce indirectează către obiect (este o referinţă).

  29. using System; namespace HelloWorld { classPoint // clasa Point este derivată din System.Object { publicint x, y; public Point(int x, int y) { this.x = x; this.y = y; } public overridebool Equals(object obj) { if (obj.GetType() != this.GetType()) returnfalse; // this şi obj sunt de acelaşi tip? Point other = (Point)obj; return (this.x == other.x) && (this.y == other.y); // câmpurile x şi y se potrivesc? } public override int GetHashCode() { return x ^ y;// ^ = XOR } public override String ToString() // valoarea punctului ca un şir { return String.Format("({0}, {1})", x, y); } publicPoint Copy()// returnează o copie superficială a acestui obiect { return (Point)this.MemberwiseClone(); } } classProgram { static void Main(string[] args) { Point p1 = new Point(1, 2);// un nou obiect de tip Point Point p2 = p1.Copy();// un alt obiect de tip Point care îl copiază pe primul Point p3 = p1;// o altă variabilă care referenţiază primul obiect de tip Point Console.WriteLine(Object.ReferenceEquals(p1, p2));// p1 şi p2 se referă la două obiecte diferite Console.WriteLine(Object.Equals(p1, p2));// p1 şi p2 se referă la două obiecte diferite cu ac. valoare Console.WriteLine(Object.ReferenceEquals(p1, p3));// p1 şi p3 se referă la acelaşi obiect Console.WriteLine("p1's value is: {0}", p1.ToString()); } } } False True True p1's value is: (1, 2) Exemplu

  30. using System; namespace HelloWorld { classaClass { publicint x; } structaStruct { publicint x; } classProgram { static void doClass(aClass c) { c.x = 5; } static void doStruct(aStruct s) { s.x = 5; } static void Main(string[] args) { aClass c = newaClass(); c.x = 1; Console.WriteLine("c.x = " + c.x); aStruct s = newaStruct(); s.x = 1; Console.WriteLine("s.x = " + s.x); doClass(c);// o referinţă către clasă este pasată metodei Console.WriteLine("c.x = " + c.x); doStruct(s);// o copie a structurii este pasată metodei Console.WriteLine("s.x = " + s.x); } } } classRefExample { static void Method(refint i) { i = 1; } static void Main() { int val = 0; // ! Method(ref val); // val = 1 } } classOutExample { static void Method(out int i) { i = 1; } static void Main() { int val; Method(out val); // val = 1 } } c.x = 1 s.x = 1 c.x = 5 s.x = 1 Exemplu

  31. using System; namespace HelloWorld { partial class Point // Point1.cs { publicdouble X { get; set; } publicdouble Y { get; set; } public Point(double x, double y) { X = x; Y = y; } } partial classPoint // Point2.cs { public override string ToString() { returnString.Format("({0};{1})", X, Y); } } classOuterClass // default = internal { privateint x; public OuterClass(int x) { this.x = x; } public class InnerClass { OuterClass o; public InnerClass(OuterClass o) { this.o = o; } public override string ToString() { returnString.Format("{0}", this.o.x); } public static void doOuterClass(OuterClass o) { Console.WriteLine(o.x); } } } classProgram { static void Main(string[] args) { Point p = newPoint(1.5, 2.0); Console.WriteLine(p.ToString()); OuterClass o = newOuterClass(1); OuterClass.InnerClass i = new OuterClass.InnerClass(o); Console.WriteLine(i.ToString()); OuterClass.InnerClass.doOuterClass(o); } } } (1,5;2,0) 1 1 /* variabile de clasă vs. variabile de instanţă */ using System; namespace HelloWorld { classaClass { public static double defaultRadius = 1; public constdouble PI = 3.14159265; // implicit static public staticdouble CircleArea(double radius) { returnaClass.PI * Math.Pow(radius, 2); } } classProgram { static void Main(string[] args) { Console.WriteLine(aClass.CircleArea(aClass.defaultRadius)); aClass.defaultRadius = 2; Console.WriteLine(aClass.CircleArea(aClass.defaultRadius)); } } } 3,14159265 12,5663706 /* cod nativ */ [DllImportAttribute("Kernel32.dll")] private static externbool SetConsoleTextAttribute(IntPtr hConsoleOutput, int wAttributes); assembly – colecţie de tipuri şi resurse ce formează o unitate logică de funcţionalitate /* modificatori */ abstract, const, event, extern, internal, override, private, protected, public, readonly, sealed, static, unsafe, virtual, volatile Exemplu

  32. using System; namespace HelloWorld { abstractclassCat { publicstring Name { get; set; } publicoverridestring ToString() { return Name; } public abstract void meow(); } classCheshireCat : Cat { public CheshireCat() { this.Name = "The Cheshire Cat"; } public override void meow() // ! { Console.WriteLine(this.ToString() + " -We're all mad here! I'm mad. You're mad."); } } classProgram { static void Main(string[] args) { CheshireCat cc = new CheshireCat(); cc.meow(); } } } The Cheshire Cat - We're all mad here! I'm mad. You're mad. Data viitoare: interfeţe vs. clase abstracte Clasele abstracte sunt clase ce servesc numai drept şabloane – pot fi doar moştenite, nu şi instanţiate. Pot exista şi membri abstracţi în cadrul acestora, fără implementări, care trebuie neapărat suprascrişi după o derivare.

  33. Pe data viitoare!  http://students.info.uaic.ro/~florin.cristea/cspi

More Related