1 / 84

Programming II.

Programming II. Inheritance Interfaces Exceptions Generics Event handling Recursion. Programming II. Inheritance Interfaces Exceptions Generics Event handling Recursion. Topics of the practice. Inheritance syntax OO principles : encapsulation , data hiding Type polymorphism

vahe
Download Presentation

Programming II.

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. Programming II. Inheritance Interfaces Exceptions Generics Eventhandling Recursion Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

  2. Programming II. Inheritance Interfaces ExceptionsGenerics Eventhandling Recursion Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

  3. Topics of thepractice • Inheritancesyntax • OO principles: encapsulation, datahiding • Typepolymorphism • Methodpolymorphism • Virtual and non-virtualmethods • Abstractclasses and methods Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

  4. Inheritancein C# • Baseclassescan be specifiedusingthecharacter „:” (onlysingleinheritancein c#) • Thiswaywecanextendthebaseclasswithnewfields/methods classAnimal { intage; publicAnimal( ) { ... } publicvoidEat( ) { ... } } classMammal: Animal { publicMammalGiveBirth( ) { ... } } class Cat: Mammal { stringname; public voidHiss( ) { ... } } Age : int Animal() Eat() Animal GiveBirth() : Mammal Mammal Name : String Hiss() Cat Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

  5. Inheritance of constructors • Constructrorsarenotinherited • Wecan (should) callthebaseclass’ constructorusingthe „base” keyword (theproperconstructorwill be calledaccordingtothegivenparameters) • Connectingtheconstructors • Bydefault, theparameter-lessconstructor of thebase is called • Ifit is notpresent, thenwehavetomanuallyconnectone of thebaseconstructorswiththesubclass’ constructor class A { publicA( ) { ... } } class B : A { publicB( ) { ... } } classC : A { publicC(intx) { ... } } class E : C { publicE(inty) : base (y) { ... } } class F : C { publicF( ) : base (5) { ... } } Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

  6. Virtual and non-virtualmethods • Non-virtualmethods • Earlybinding • In C#, this is thedefault (nonexistantin Java) • Virtualmethods • Latebinding • Specialsyntax • Inthefirstclasswheretheyappear, they must be markedwiththekeyword „virtual” • Inthedescendantclassesthesamemethods must be markedwiththe „override” keyword (wecan, butweshouldnothidemethods) • The basemethodcanstill be accessed class A { public virtual int Method( ) { ... } } class B : A { public override int Method( ) { ... } } Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

  7. Hidingmethods • Ifwedeclare a non-virtualmethodwiththesamename • Compilerwarning, unlesswe mark themethodwiththe „new” keyword • The basemethodcanstill be accessed • Hidingvirtualmethods • „newvirtual”  newvirtualmethodchain, overcomplicated(?) • Usuallymethodhiding is notconnectedtovirtualmethods, itcanhappeniftwomethodshappentohavethesamename „byaccident” class A { public intMethodX( ) { ... } public virtual intMethodY( ) { ... } } class B : A { public new intMethodX( ) { ... } public new virtual intMethodY( ) { ... } } Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

  8. Typeconversion (typecasting) • Treat an objectasitwas of anothertype • Implicit: automatictypeconversion (e.g. intfloat, no extra syntax) • Explicit: conversionusingthe standard (newtype) operator • Animal x; Cat y = (Cat)x; ((Cat)x).Nyávog(); • „is” operator • Usage: „VARIABLE is TYPE” , returnswithboolean • Returnswithtrueifthegivenvariablecan be usedasthegiventype (= sametypeorderivedtype) • „as” operator • Usage: „VARIABLE as TYPE” • Conversion (onlyusablewithreferencetypes) • No exceptiononfailure! Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

  9. Abstractclasses / methods • They must be markedwiththe „abstract” keyword • Usage of classesforpurelyinheritancepurposes • A classwithevenoneabstractmethod must always be abstract • Wecannotcreateinstancesfromabstractclasses • Abstractmethods must be implementedinthederivedclasses abstract classFigure { public abstractdoubleArea( ); public abstractdoubleCircumference( ); } classRectangle: Figure { inta; intb; public override doubleArea( ) { returna * b; } public override doubleCircumference( ) { return2 * (a + b); } } Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

  10. Sealedclass / method • Must be markedwiththe „sealed” keyword • Sealedclassescannot be usedasbaseclass • Sealedmethodscannot be overridden sealed classRectangle: Figure { inta; intb; publicoverridedoubleArea( ) { returna * b; } publicoverridedoubleCircumference( ) { return2 * (a + b);} } Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

  11. Objectbaseclass • The rootclass of theclasstree, thebaseclassforeverything • Ifwedonotspecifyourownbaseclass, thenSystem.Objectwill be usedas a base • Somemethods: • public Type GetType()Returnsthetypeobject • public virtual bool Equals(object obj) Equalitybasedonthecontent • public virtual int GetHashCode()Calculates a hashbasedonthecontent • public virtual string ToString()Convertstheinstanceinto a string • public static bool ReferenceEquals(object objA, object objB) Equalitybasedonthereferences • public static bool Equals(object objA, object objB) Equalitybasedonthecontents Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

  12. Inheritanceexample • Shape Circle, Shape  Rectangle  Square • Solvethefollowing: • Store 50 shapesin an array • Determinetheonewiththebiggestarea • List thosewiththebiggestcircumference • List thosewherethearea isbiggerthanthecircumference • List thosewherethearea is a primenumber • Selecttheonewherethecircumferencenumber has thebiggestnumber of divisors Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

  13. Programming II. Inheritance Interfaces ExceptionsGenerics Eventhandling Recursion Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

  14. Interfacesin C# • We must usethe „interface” keyword • Interfacescancontainmethod/property/eventdeclarations • Whencreating a classthatusesinterface(s), we must usethesame „:” character (extendsvsimplements) • Multipleinterfacescan be implementedinoneclass • Wecannotcreateinterfaceinstances, butitcan be usedas a type interfaceIReceiveMessages { boolAvailable{ get; set; } voidSend(stringmsg); } classChatPartner : Person, IReceiveMessages { public boolAvailable{ get {...} set {…} } public voidSend(stringmsg) { ... } } IÜzenetFogadó x =newChatPartner(); <<interface>> IReceiveMessages Available: Boolean Send(String) IReceiveMessages ChatPartner Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

  15. Abstractclassvsinterfaces • Abstractclasscanalsoimplementinterfaces • Optionallywecanimplementtheinterfacemethodsor mark themasabstractmethods descendants must implementthose • Theycanlookthesame, buttheyservedifferentpurposes • Both canmakeotherclassesimplementsomemethods, butabstractclassesareusedininheritance and theycancontainactualmethods/fieldsaswell interfaceICanBeSold { boolPrice { get; set; } voidSell( ); } abstract classProduct: ICanBeSold { public abstract boolPrice { get; set; } public abstract voidSell( ); } Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

  16. Extendinginterfaces • Similartoobjectinheritance (usingthe „:” letter) • An interfacecanextendmultipleinterfaces • A classimplementingainterface must implementallmethodsdefinedbythegiveninterface and allotherinterfacesthatgiveninterfaceextends interfaceICanBeSold { boolPrice{ get; set; } voidSell( ); } interfaceICanBeOnSale:ICanBeSold { voidExecuteSpecialSale(doublediscount); } public classProduct: ICanBeOnSale { public boolPrice { get; set; } public voidSell ( ) { ... } public voidExecuteSpecialSale(doublediscount) { ... } } Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

  17. Implicitinterfaceimplementation • If more thanoneinterfacecontainsthesamemethod (withthesamesignature), thentheclasscan be createdsothatitfulfilstheinterfacemethodusingoneactualmethod • Inthiscaseitdoesnotmatterwhatreferenceweusefortheobjectinstance, thatonemethodwill be executedwhencalled interfaceIManageFiles { stringDelete( ); } interfaceIManageDocuments { stringDelete( ); } public classTextFile: IManageFiles,IManageDocuments { publicstringDelete( ){ … } } Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

  18. Explicitinterfaceimplementation • Ifwechoosetoimplement a separatemethodforseparateinterfaces • The executedmethoddependsonthevariable/referencetype interfaceIManageFiles { stringDelete(); } interfaceIManageDocuments { stringDelete(); } publicclassTextFile : IManageFiles, IManageDocuments { stringIManageFiles.Delete() { return"FILES"; } stringIManageDocuments.Delete() { return"DOCUMENTS"; } publicstringDelete() { return"TEXTFILE"; } } classProgram { staticvoid Main(string[] args) { TextFile a = newTextFile(); a.Delete(); (a asIManageFiles).Delete(); (a asIManageDocuments).Delete(); Console.ReadLine(); } } Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

  19. Exercise #1 • Create a classthatcanstorestudents (random name + random credit number), make a sortablearrayfromtheclassinstances The class must implementtheIComparableinterface • Generic and non-genericversionsfromthatinterface, weusethenon-genericnow • int CompareTo(Object obj)<0 – thecurrentinstance is beforeobj0 – thecurrentinstance and theobjareatthesame spot>0 – thecurrentinstance is afterobj • UseIComparable + Array.Sort(Array) Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

  20. Exercise #2 • Wewanttocreate a carrace • Car Name, protectedSpeed, protectedRnd, publicPosition+ ctor + ToString • ICanAccelerate, ICanBreakDown • BMW : Car, ICanAccelerate (everythirdtime) • Porsche : Car, ICanBreakDown (1:X chance) • Jaguar : Car, ICanAccelerate, ICanBreakDown (1:5 chanceforboth) • Program class: Init() + Main() + IsOver() Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

  21. Programming II. Inheritance Interfaces ExceptionsGenerics Eventhandling Recursion Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

  22. Multi-layerarchitectures • Three-layerarchitecture (notnecessarilythree-tier) • Typically • Everylayerperformsonedistincttask, and servesdatatothelayerabove • Eveniftheyaredeployedas a one-tierapplication, thelogicalseparation is highlyadvised • Easiertomange and changeandscalethecode • Reusablecode!!! View Controller(ViewModel, Presentation) Model(Resource) Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

  23. Topics of thepractice • EventsvsExceptions • Steps of creatingexceptions • Exceptionhierarchy • DivideByZeroException, FormatException, OverflowException • Exceptionbaseclass • NullReferenceException, IndexOutOfRangeException • ArgumentException, ArgumentNullException, ArgumentOutOfRangeException Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

  24. Programming II. Inheritance Interfaces ExceptionsGenerics Eventhandling Recursion Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

  25. Aim • Aim: create a setthatcanstorepeople, usingtheleastpossibleperson-dependentlines (e.g., ZERO) • Whattypeshould be usedas a storage? • Person – The wholething has to be rewrittenfor a set of dogs • CommonancestorforPerson and Dog – notpossibleinmanycircumstances... Nothing is common... • Object (globalancestor) – possiblesolution ArrayListin .NET1, typecastingforever • Definethetypeas a paremeter, and definetheactualtypelater Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

  26. Generics • Templateclassesin C++ • Duringthedefinition, wespecifygenerictype(s) thatwill be definedlater • Duringthedefinition, weonlyreference a typeassimply „T”, and this „T” typewill be actuallydefinedlater, whentheinstance is created • Definition:class MyGenericClass<T> { } • Declaration and instancecreationMyGenericClass<int>mgcINT = new MyGenericClass<int>(); • MyGenericClass<Person>mgcP= new MyGenericClass<Person>(); • Typicalusage: built-incollections! Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

  27. Collections • ArrayList storesobjects, typecasting is needed, deprecated • List<T>: Add(), Insert(), Remove(), RemoveAt(), Reverse(), [],Clear(), Contains(), Count • Queue<T>: Enqueue(), Dequeue(), Peek(),Clear(), Contains(), Count • Stack<T>: Push(), Pop(), Peek(),Clear(), Contains(), Count • Multiplegenerictypeparameters: classsomething<T,U> { } • Dictionary<T, U>: Add(), Remove(), TryGetValue(), Keys, Values,Clear(), ContainsKey(), ContainsValue(), Count Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

  28. Usinggenericclasses Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

  29. Initializinggenerictypes • objectreference=null; intvalue=0; stringimmutable=””; • T something = ???? • No idea abouttheexacttype, no idea abouttheexactwaytoinitialize • defaultexpression • Returnswithnullorbitwisezero T something =default(T); Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

  30. Constraints / Restrictions • Onething is sure: type T descendsfromSystem.Object • Thus, onlytheusualmethodsareaccessible (ToString(), ....) • Wecanspecifyconstraintstoenforcesomerules: thedevelopercannotuseanythingas T, onlythosetypes... • Descendant of...(where T : Person) • Implements... (where T:IComparable) • Valuetype (where T:struct) • Referencetype (where T:class) • Withconstructor(where T:new()) Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

  31. Interfacerestriction: foreach class MyClass2<T> { public void Iterate(T data) { foreach (object item in data) { Console.WriteLine(item); } } } Can I useforeachontype„T”?(The foreachloopcanonlyworkon a typeifitimplementsIenumerable, thiswill be detailedlater) class MyClass2<T>where T : IEnumerable<T>{ public void Iterate(T data) { foreach (objectitem in data) { Console.WriteLine(item); } } } Sameway: wecanuseInterfaces / Baseclassestoenforcetheexistance of somemethod/property OK Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

  32. Operator restriction class Arithmetic<T>{ public T Cubed(T number){ return number * number * number; } } Canwemultiply „T” ? class Arithmetic<T>where T : System.Int32{ public T Cubed(T number){ return number * number * number; } } Primitive / valuetypescannot be usedasconstraints! Whenusinggenerics, wecannotuse most of thebasic operators, wealwayshavetousemethods! Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

  33. class Program2 { public T Min<T>(T a, T b)where T :IComparable<T> { if (a<b) return a; else return b; } } classProgram { public T Min<T>(T a, T b) where T :IComparable<T> { if (a.CompareTo(b)<0) return a; else returnb; }… }  No standard operators Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

  34. Genericmethod • Independent fromgenericclasses: genericclassescancontainnon-genericmethods; non-genericclassescancontaingenericmethods • A method is genericifit has generictypeparameters Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

  35. Callinggenericmethods • Callinggenericmethods: theparametertypesspecify „T” :inti=Min(2, 3); //integersfloat f=Min(2.0f, 3.0f);//floats • !IMPORTANT! wecan’t havetwomethods w thesamesignature • Whatif T=int? • Whenthere is a conflict, alwaysthenon-generic version is called • IftherearetwomethodswithgenericparametersMethod(T arg), Method(U arg), and T and U happento be thesame, thenthemethodcallwillbeunavailable („ambiguouscall”) Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

  36. Staticfields class MyGenericClass<T> { private static int counter = 0; public MyGenericClass() { counter++; } public static void Count() { Console.WriteLine(counter); } } Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

  37. Accessingstaticfields/methods • Toaccessstaticmembers, an actualtype must be used:MyGenericClass<int>.Count(); • Differentstaticfieldsbelongtodifferenttypes • The staticconstructor is automaticallycalled Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

  38. Generics and inheritance • Genericclassescan be derivedfrombothgeneric and non-genericclass • Genericclassescan be theancestor of bothgeneric and non-genericclasses • However , thetypeparameter must always be accessibleorset! • IfDerived<T> : BaseGeneric<T> , and newDerived<int>()  type T will be int inbothclasses. • IfDerived : BaseGeneric<T>, and newDerived()  type T inthebaseclass is notdefined, NOT ALLOWED • IfDerived<T> : BaseGeneric<U>, and newDerived<int>()  type U inthebaseclass is notdefined, NOT ALLOWED Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

  39. Generics and inheritance Melyik eset lehetséges? Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

  40. Generics and inheritance • The restrictions must be repeatedinthedescendantclasses, thedescendantclasscanintroducenewconstraints • GenericsareaccessibleinallmanagedCLR-basedlanguage • Genericsarestoredinthe MSIL level, theactualtypereplacement is doneduringthe JIT compile Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

  41. Programming II. Inheritance Interfaces ExceptionsGenerics Eventhandling Recursion Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

  42. Multi-layerarchitectures • Three-layerarchitecture (notnecessarilythree-tier) • Typically • Everylayerperformsonedistincttask, and servesdatatothelayerabove • Eveniftheyaredeployedas a one-tierapplication, thelogicalseparation is highlyadvised • Easiertomange and changeandscalethecode • Reusablecode!!! View Controller(ViewModel, Presentation) Model(Resource) Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

  43. Topics of thepractice • EventsvsExceptions • Steps of creatingeventsusinginterfaces • Steps of creatingeventsusingdelegates Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

  44. Intheexamplestherewill be twoclasses, theeventcreator and theeventhandlerclass. This is usuallythecase, butevents (justlikeexceptions) can be created and handledwithinonesingleclass Aim: signalevents (information) toothermodules/classes Possibilities: Function/methodpointers (DOS), delegates (C#), interfaces (JAVA) Eventhandling Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

  45. Wehavetocreate an interfaceISomethingthatdescribesthesignature and thename of themethodthatwillhandleourevent The eventcreator/senderclass must maintain a privatelist of ISomethinginstances Usingpublicaccessors, anotherclass (theeventhandlerclass) can add orremoveitself (orotherclasses) tothislist (subscribe, unsubscribe) ElementsinthelisthavethetypeISomething theyallcontainthemethoddescribedintheinterface, and thismethodwillhandletheevent The eventcreatorclasssimplyloopsthroughthesubscribedclassesfoundinthelist, and callsthesamemethodforeveryinstance Usinginterfacesforevents Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

  46. A typethatallowsusto „store” methodsinavariable Inthedeclarationwe must specifythesignature of themethodsthatthegivendelegatecanstore:delegatedoubleMyDelegate(int param1, string param2); Name: MyDelegate Returntype: double Parameters: int+string Important: this is only a typedeclaration Notusablewithout a variable/field of thistype Referencetype Likeclass/enum: cannot be declaredin a method; it must be declaredin a namespaceorinsideaclass Delegate Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

  47. delegatedoubleMyDelegate(int param1, string param2); doublefunct(intfirst, stringsecond) { returnfirst + second.Length;} Unicastdelegate:MyDelegate del;del = newMyDelegate(funct);Console.WriteLine(del(5, "hello")); Usingdelegates Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

  48. delegatedoubleMyDelegate(int param1, string param2); doublefunct(intfirst, stringsecond) { returnfirst + second.Length;} Declaring a delegatefield: MyDelegate del; Multicastdelegate: del += funct;Console.WriteLine(del(5, "hello")); Aslongasthedelegate is empty, itsvaluewill be NULL  we must alwayscheckitbeforecallingthedelegate Multiplemethodscan be putintothesamedelegate Usingdelegates Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

  49. delegateboolMyComparer(objectleft, object right); classSimpleExchangeSorter { publicstaticvoid Sort(object[] Arr, MyComparerbigger) { for (int i = 0; i < Arr.Length; i++) for (int j = i + 1; j < Arr.Length; j++) if (bigger(Arr[j], Arr[i])) { objecttemp = Arr[i]; Arr[i] = Arr[j]; Arr[j] = temp; } } } Delegate-parameter Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

  50. Delegate-parameterExample classstudent { publicstringname; publicintcredits; publicdiak(stringnewname, intnewcredits) { name = newname; credits = newcredits; } publicoverridestringToString() { returnname + " - " + credits; } } student[] group= newstudent[] { newstudent("Első Egon", 52), newstudent("Második Miksa", 97), newstudent("Harmadik Huba", 10), newstudent("Negyedik Néró", 89), newstudent("Ötödik Ödön", 69) }; Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

More Related