+ All Categories
Home > Documents > Interface and Collections

Interface and Collections

Date post: 07-Jul-2018
Category:
Upload: vrnataraj
View: 215 times
Download: 0 times
Share this document with a friend

of 21

Transcript
  • 8/18/2019 Interface and Collections

    1/21

    nterface & Collections

    Defnition : "An inteace is a named collection o related abstractmembers".

    nterace is defned in C# by using the keyword "interace".

    nterace's are not associated with base class not e!en ystem.b$ect% & containsmembers that has no access modifers.

    nterace methods are imlicitly ublic( in order to allow suorting tye tomlement members.

    ).*: interace +interace name,-

    ember declarations  /

    n addition to methods interaces can ha!e roerties( e!ents & inde0ers.

    10: interace I10amle  -

      !oid Dislay%2int Aroerty

      - get2 /  /

    C# classes3structures can inherit rom interaces as shown below.class stud:I10amle struct stud:I10amle-.../ -.../4

    more than one interaces are inherited then they are listed using comma

    searated list.class stud:I10amle( I10amle5-.../

    classe's are imlicitly deri!ed rom ystem.b$ect & structures are deri!ed romystem.6alue7ye. I there is any e0licit inheritance on the class to be done( thenhe name o it must be listed frst & then interace names.

    class stud:89( I10amle5-.../

    hen interaces are inherited then all the members in it must be comulsorilydefned by the inherting entity. 7he inheriting entity has no choice on choosing themembers to imlement.10:

    class pgm:DM,IAdd,IMul {

      public void read() {

      a = int.Parse(Console.rite!ine())"

      b = int.Parse(Console.rite!ine())"

      #

    $$ met%od o& inter&ace IAdd  public void add() {

      Console.rite!ine(a'b)"

      #

      public void mul() {

      Console.rite!ine(ab)"

      #

      public static void Main()

      {

      pgm a = ne pgm()"

      a.read()"

      a.add()" a.mul()"  #

    #

    using *+stem"

    inter&ace IAdd

    {

    void add()"

    #

    inter&ace IMul

    {

      void mul()"

    #

    class DM

    {

     protected int a,b"

    #

    1

  • 8/18/2019 Interface and Collections

    2/21

    Abstract class & Interaces are in contrast to each other.

    Abstract class can defne ublic( ri!ate & rotected data members whichnterace's cannot ha!e within them.

    Abstract classe's can ha!e any number o concrete methods that can be accessedby subclasses. ;ut no defnition o methods is allowed in interaces. 1!erymember o an interace is automatically abstract.

    C# suorts only single inheritance i.e one class can ha!e only one base class%.

  • 8/18/2019 Interface and Collections

    3/21

    class gm:IAdd-  int a(b2  ublic gmint 0( int y%  - a=02b=y2/  ublic int add%  - return a>b%2 //

    class 10-  ublic static !oid ain%  -  IAdd r2  gm a = new gm%2  r = IAdd% a2 33 10licit casting  Console.rite?iner.add%%2  //

    is a reerence o interace. icne( class gm suorts the interace Add e0licitcasting is ossible & using r( add% method can be in!oked.

    class gm does not imlement interace add% then e0licit casting lilnegenerates run time error & throws an "In!alidCast10cetion".using r( only the methods in interace can be in!oked. ethods ertaining to classgm cannot be in!oked.

    2) obtaining reference via 'as' keyword

    10:  IAdd r2  gm a = new gm%2  r = a as IAdd2  r.add%2

    using 'as' keyword e0licit casting can be done as shown.

    class gm imlements methods in the interace then ob$ect a is casted to r. I 

    class gm doesn't imlement methods in the interace then( as line laces a null!alue into r rather than throwing any e0cetions.

    3) Checking interface ipleentation via 'is' keyword

    10:gm a = new gm%2i a is IAdd%Console.rite?inea.add%%2

    3

  • 8/18/2019 Interface and Collections

    4/21

    Derived class; must override getpoint()

    Abstract class; int getpoint(); Returns number of points for a shapeShape

    Triangle

    e!agon

    "ircle

    elseConsole.rite?ine"gm doesnt imlement add%"%2

    a is not add% method comatible then condition ails.

    nterfaces as paraeters

    As shown abo!e in method dis2 arameter is an interace entity. nly thenstances o a class which imlements IAdd interace can be assed as argumentsnto it.

    imilarly interace reerence can be used as a return tye o a method.

    nterface as polyorphic agents

    class pgm

    {

      static void disp(IAdd r)

    $$ parameter t+pe is re&erence o&

    $$ inter&ace t+pe

      { r.add()" #

     public static void Main()

      {

      Aint a = ne Aint(-,)"

      As%ort b = ne As%ort(/,0)"

      disp(a)"

      disp(b)"

    $$ arguments are instances o& a cla

    $$%ic% implement inter&aces

      #

    #

    inter&ace IAdd

    { void add()" #

    class Aint:IAdd

    {

      int a,b"

      public Aint(int 1, int +)

      { a=1" b=+"#

      public void add()

      { Console.rite!ine(2{3#2,(a'b))" #

    #

    class As%ort"IAdd

    {

      s%ort a,b"

      public As%ort(s%ort 1, s%ort +)

      { a=1" b=+"#

      public void add()

      {Console.rite!ine(2{3#2,(a'b))" #

    #

    #

  • 8/18/2019 Interface and Collections

    5/21

    "ontains a method int getpoint ();$Shape

    Triangle e!agon "ircle

    hae is an abstract class that defnes beha!iour common or its deri!ed class.7riangle( @e0agon & Circle are deri!ed class o shae & getoint% must becomulsorily defned in these classes.

    7riangle & @e0agon are caable o defning this method but circle does not needhis method. Drawback o abstract class is that all deri!ed tyes must defne the

    abstract method. 9ow consider shae as interace

    As shown 7riangle & @e0agon imlements Ihae & Circle doesn't imlement it.e!eral other class hierarchies can also inherit rom interaces & they canmlement them.

    Explicit Interface ipleentation

    10:abstract class b interace IAdd

    - ublic abstract !oid add%2 / - !oid add%2/

    class Aint:b(IAdd-  int a(b2  ...  ublic o!erride !oid add%  -...//

    Aint a = new Aint%2

    a.add%2IAdd r = IAdd% a2r.add%2

    Considering the e0amle both abstract class b & interace IAdd has an abstractmethod add %. Class Aint inherits rom b & IAdd. add% method has beeno!erriden in Aint.

    add% method is in!oked !ia instance o class Aint or !ia reerence o IAdd sameadd% method will be in!oked. 9ecessity o ha!ing add% methods is to ha!ediBerent unctionalities in diBerent method.

    10: add% in abstract class can add no's & see whether theresult is e!en or not.add% in interace can $ust add no's

    7o diBerentiate between the method o abstract class & the method o interaceexplicit interface ipleentation" must be used.

    %

  • 8/18/2019 Interface and Collections

    6/21

    class Aint:b(IAdd-

    int a(b2

    ...!oid I!dd"add% 33 10licit interace imlementation-Console.rtie?ine"Interace add"%2/ublic o!erride !oid add%- Console.rite?ine"Abstract class add"%2 /

    /

    hen e0ternal imlementation is done no !isibility secifer must be used likeublic(ri!ate etc.(

    ethod add% o interace can be in!oked only using interace reerence( thiscannot be in!oked using instance o the class.

    Another usage o e0licit interace imlementation is whene!er a class imlementsa number o interaces which contains same method names.

    interace IAdd- !oid oerate%2 /interace Iub- !oid oerate%2 /

    interace Iul- !oid oerate%2 /

    class gm:IAdd(Iub(Iul-

    !oid I!dd"oerate%  - Console.rite?ine"ethod o IAdd"%2 /  !oid I#$b.oerate%  - Console.rite?ine"ethod o Iub"%2 /  !oid I%$l"oerate%  - Console.rite?ine"ethod o Iul"%2 /

    /

    class 10- ublic static !oid ain% -  IAdd r2 Iub r52 Iul r2

    &

  • 8/18/2019 Interface and Collections

    7/21

      gm a = new gm%2

      r = IAdd% a2  r.oerate%2

      r = Iub% a2  r.oerate%2

      r = Iul% a2

      r.oerate%2  / /

    $ilding interface hierarchies

    imilar to a class ha!ing hierarchies interaces can also ha!e hierarchies. 7omostnterace defnes a general beha!iour( while the most deri!ed interace defnesmore secifc beha!iors.

    10:interace IAdd

    - !oid add%2 /interace Iub:IAdd- !oid sub%2 /interace Iul:Iub- !oid ul%2 /

    class gm:Iul-  !oid add%  - Console.rite?ine"In add"%2 /  !oid sub%

      - Console.rite?ine"In sub"%2 /  !oid mul%  - Console.rite?ine"In mul"%2 //

    class 10-  ublic static !oid ain%  -

      gm a = new gm%2  Iul r = Iul% a2  r.add%2  r.sub%2  r.mul%2  //

    '

  • 8/18/2019 Interface and Collections

    8/21

    10amle deicts interace hierarchy. Class gm imlements each beha!iour in thenterace hierarchy2 since it deri!es rom the nth most interaces in hierarchy.ul has all the beha!iors o IAdd & Iub due to interace hierarchy

    %$ltiple ase interfaces

    nterace IAdd interace Iub interace Iul:IAdd(Iub-!oid add%2 / -!oid sub%2 / -!oid mul%2 /

    class gm:Iul-  !oid add%  - Console.rite?ine"In add"%2 /  !oid sub%  - Console.rite?ine"In sub"%2 /  !oid mul%  - Console.rite?ine"In mul"%2 //

    class 10-

      ublic static !oid ain%  -  gm a = new gm%2  Iul r = Iul% a2  r.add%2  r.sub%2  r.mul%2  //

    Convertible interface

    nteraces are used e0tensi!ely throughout the .917 base class library2 one o thems ICon!ertible interace.

    ain usage o this interace is to con!ert inormation rom one tye to anotherdynamically using interace based rogramming techniue.

    Con!ertible interace is defned in .917 rame work as shown

    ublic interace ICon!ertible-

    7yeCode )et7yeCode%2bool 7o;oolean I*ormatro!ider ro!ider%2byte 7o;yte I*ormatro!ider ro!ider%2char 7oChar I*ormatro!ider ro!ider%2......uIntEF 7o

  • 8/18/2019 Interface and Collections

    9/21

    All intrinsic data tyes o C# are aliases to structures resent in ystemnamesace. 1ach o these structures defnes within them many methods &mlements many interaces.

    ublic struct ;oolean:IComarable( ICon!ertible-

    ...

    .../

    En$erable & IEn$erator interface

    1numerable and I1numerator interace are used to iterate through a collection o custom tyes e0: array o class( structures%1numerable interace contain only one abstract member unction called

    )et1numerator%. 7his method will return an Interace called I1numerator.

    nterace I1numerable

    - I1numerator )et1numerator%2 /

     public IEnumerator GetEnumerator(){  //return IEnumerator of our Custom Type  return(IEnumerator)this;}

    1numerator is an interace which hels to iterate through any custom collectionhat is internal to a class.

  • 8/18/2019 Interface and Collections

    10/21

    G 7he 8eset method resets the collection inde0 to its initial!alue o H5. 7his in!alidates the enumerator.

    G 7he Current method returns the current ob$ect at ositionJ.

    ;oth I1numerable & I1numerator interaces are defned under ystem.Collectionsnamesaces.

    10:using ystem2using ystem.Collections2class stud -

    string name( usn2  ublic studarams stringJ a%  - name = aKJ2 usn = a5J2 /  ublic o!erride string 7otring%  - return "9ame : " > name > "

  • 8/18/2019 Interface and Collections

    11/21

    using ystem2 using ystem.Collections2class stud

    -M./

    class cstud : I1numerable(I1numerator

    -

    M

    int os2

    ublic cstud%- os = H52MM.

    /

    cstud a = new cstud%2

    a.o!e9e0t%2Console.rite?ine a.Current %2a.8eset%2

    oreachstud 0 in a%

    Console.rite?ine0%2

    a.o!e9e0t% are e0licit in!ocations o I1numerator methods. 1!en withoute0licit in!ocation using oreach loo all the elements will be read.

    7o a!oid the imlementation o I1numerator methods( ollowing code must bewritten.

      public bool MoveNext()

      { if (pos < a.Length-1)

      { pos++; return true;   else

      return false;

     

      public voi! "eset() { pos # -1;

      public ob$ect %urrent

      { get { return a&pos';

      public nu*erator etnu*erator()

      { return (nu*erator)this;

    11

  • 8/18/2019 Interface and Collections

    12/21

    class stud+ public string name, usn; public stud(string n, string u)

     + name - n; usn - u; . public override string ToString()

     + return name / 0 0 / usn;..

    stud p - ne stud(0aa0,0110);

    stud - p;usn - 0220;"onsole4rite5ine(p);"onsole4rite5ine();

    public IEnumerator GetEnumerator(){ return a.GetEnumerator(); }

    Data member a is an array. ystem.Array already imlements I1numerator itNs notnecessary to imlement I1numerator methods once again.

    Cloneable Interface

    ntrod$ction

    7he ystem.ICloneable interace defnes a method o cloning coying% to create anew ob$ect o a class with the identical !alue as an e0isting ob$ect. 7his interacedefnes a single method named Clone% as shown below.

     public interface ICloneable

    {

    object Clone( );

    }

    7here are two ways to clone an ob$ect:

    1 #hallow copy H ame data may be shared by both new & old ob$ect.

    2 eep copy H ;oth new & old ob$ect will ha!e its own coy o data.

    A shallow coy is the easiest way to clone an ob$ect. 7his can be achie!ed with theemberwiseClone% method inherited by all classes rom b$ect. @owe!er( this tyeo cloning is not eBecti!e.

     

    12

  • 8/18/2019 Interface and Collections

    13/21

    class stud :ICloneable

    + public string name, usn; public stud(string n, string u) + name - n; usn - u; . public override string ToString()

     + return name / 0 0 / usn;. public object Clone( )

     { return new stud(name,usn); }

    .

    stud p - ne stud(0aa0,0110);stud - (stud)p.Clone();usn - 0220;

    "onsole4rite5ine(p);"onsole4rite5ine();

    class stud :ICloneable

    + public string name, usn; public stud(string n, string u)

     + name - n; usn - u; . public override string ToString() + return name / 0 0 / usn;. public object Clone( )

     { return this.MemberwiseClone(); }

    .

    stud p - ne stud(0aa0,0110);

    stud - (stud)p.Clone();

    usn - 0220;"onsole4rite5ine(p);"onsole4rite5ine();

    class addr +

     public int hno; public addr(int h)

     + hno - h; . public override string ToString()

     + return hnoToString(); . .

    class stud 6 $"loneable+public string name;

     public addr r;

     public stud(string n)

     + name - n; r = new addr(); .

     public override string ToString() + return (name / 0 0 /r);. public ob7ect "lone()

     +return this8emberise"lone(); ..

    stud a - ne stud(0aa0);stud b - (stud)a"lone(); ;

    b.r.hno = !!;

    "onsole4rite5ine(a);

    "onsole4rite5ine(b);

    = 2 assignment results in two reerences to the same stud ob$ect on the hea2modifcations using either reerence aBect the same ob$ect on hea.

    n order to ha!e a coy o in 2 a searate memory or has to be acuired and!alue o has to be coied into it. In order to imlement this( stud class mustmlement ICloneable interace as shown below.

    Clone% method coy the !alues o dataHmembers o in!oking o$bect into a newob$ect and return it to the . 9ow .usn will ha!e !alue 55 and .usn will ha!e!alue .

    7he abo!e rogram can be written as shown below.

    emberwiseClone% is inherited by ob$ect and it is in!oked by this reerence.emberwiseClone% will do the same task as seen beore.

    Elaborate Cloning

    13

  • 8/18/2019 Interface and Collections

    14/21

    class stud 6 $"loneable+ 9  9  public object Clon()  {

    stud temp = new stud();

      temp.name = name;

      temp.r = new addr(r.hno);

      return temp;

      }

    .

    This implements Deep cop:

    Class stud contains a reerence to addr class.

    As( each ob$ect o stud is created r acuires memory and then !alue will be lacednto it.

    cloning shallow coy% is alied on ob$ect o tye stud using emberwiseClone%as shown abo!e( then b.r.hno and a.r.hno will be holding same data.

    n other words b.r.hno and a.r.hno will be ointing to same memory. 7o a!oid this(emberwiseClone% will not be in!oked2 but e0licit code will be written tomlement dee coy.

    the abo!e code is relaced then b.r.hno will be 5KK and a.r.hno will be 5.

    #yste"ICoparable

    ystem.IComarable interace secifes a beha!ior that allows an collection oob$ects to be sorted based on a secifed key.

    interface IComparable{

      int CompareTo(ob"ect o);} 

    7his interace is used to comare similar tye ob$ects on a secifed keyon datamember%.

    Collection o inormation can be o tyes5% Collection o intrinsic tyes% Collection o user defned tyes

    1#

  • 8/18/2019 Interface and Collections

    15/21

    class stud : IComparable+

     string name;

     int id;

     public stud(string n,int i)

     + name - n; id - i; .

     public override string ToString() + return(name / 0 0 / id); .

     

    int IComparable.Compare"o(object o)

     {

      i# (id $ ((stud)o).id)

      return ;  i# (id % ((stud)o).id)

      return &;

      else

      return !;

     } 

    .

    class pgm+

     public static void ()

      +

      stud< a - ne stud3

  • 8/18/2019 Interface and Collections

    16/21

    *or a better e0lanation( add a Console.rite?ine% call inside yourcomare method and then call Array.ort. Rou'll see your method gets

    called many times.J

    Comare7o% is imlemented as Se0licit interace imlementationT.

    #yste"ICoparer

    7he role o ICoparer is to ro!ide additional comarison mechanisms.

    As( shown in the e0amle collection SaT is sorted on id. I it has to be sorted onname also( then IComarer interace has to be imlemented. IComarer cannot bemlemented on the same class stud but must be imlemented by heler class orstud.).*:nterface IComparer { int Compare(ob"ect o&' ob"ect o); } 

    @eler class is one which imlements IComarer interace or class stud byecei!ing two !alues o tye stud. @eler class $ust contains one method i.e

    Comare% method.

    10:

    class stud : IComparable

    {

     string name"

     int id" public stud(string n,int i)

     { name = n" id = i" #

     public override string 6o*tring()

     { return(name ' 2 2 ' id)" #

     int IComparable.CompareTo(object o)

     {

      if (id > ((stud)o).id)

      return 1;

      if (id < ((stud)o).id)

      return -1;

      else  return ;

     ! 

    #

    1&

  • 8/18/2019 Interface and Collections

    17/21

    nterfaces in #yste"Collections naespace

    ystem.Collections defnes a number o interaces. ost o the classes defnedwithin ystem.Collections namesace imlement these interaces.

    #yste"CollectionsInterface

    %eaning

    I1numerable 8eturn I1numerator interace or a gi!en ob$ect

    $$78!P89 C!A**

    class "elper : IComparer

    {

      int IComparer.Compare(object o1# object o$)

      {

     

    return strin%.Compare(

      ((stud)o1).ret#

    ((stud)o$).ret);

      !

    !

    class pgm {

    public static void Main() {

      stud45 a = ne stud4/5"

      a435 = ne stud(2bb2, )"

      a4-5 = ne stud(2cc2, -)"

      a45 = ne stud(2aa2, /)"

      &oreac% (stud 1 in a)

      Console.rite!ine(1)"

     &rra'.ort(a);

     Console.rite!ine(2nnn2)"

    &oreac% (stud 1 in a)

      Console.rite!ine(1)"

     &rra'.ort(a# ne "elper());

    Console.rite!ine(2nnn2)"

    Console.rite!ine(2*orting on name2)"

    &oreac% (stud 1 in a)

     Console.rite!ine(1)"

      Console.9ead()"#

    #

    1'

  • 8/18/2019 Interface and Collections

    18/21

    $ash"ode>rovider 

    $"omparer 

    $?numerator 

    $Dictionar:?numerator 

    $?numerable

    $"ollection

    $5ist

    $Dictionar:

    I1numerable )enerally used to suort oreach style iteration o subtyes

    IComarer Allows to ob$ects to be comaredI?ist ro!ides acility to add( remo!e( and inde0 items

    in a list o ob$ectsIDictionary Allows an ob$ect to reresent its contents using

    name3!alue airs.ICollection Defnes generic characteristics or a collection

    class

    any o these interaces are related by an interace hierarchy( others are standHalone entities.

    Collection interface

    7his interace ro!ides a small set o roerties that allows rogrammer todetermine.

    a% number o items in the containerb% threadHsaety o the container

    c% ability to coy contents into a ystem.Array

    p$blic interface ICollection * IEn$erable+

    ,,IEn$erable eberint Co$nt +get- .bool Is#ynchroni/ed + get- .ob0ect #yncoot +get- .

    void Copy(o!rray array int index)-.

    ictionary interface

    Dictionary is a collection o name & !alue airs.10 : tudent name and marks  Car name and no.

    Dictionary imlements all the unctionalities o ICollection & I1numerable.

    1

  • 8/18/2019 Interface and Collections

    19/21

    p$blic interface Iicitionary * ICollection IEn$erable+,,ICollection and IEn$erable ebersbool Isixed#i/e+ get- .bool Isead4nly + get- .5"void !ddob0ect key ob0ect val$e)-void Clear)-

    5".

    6ist interface

    7his interace ro!ides the ability to insert( remo!e and inde0 items into acontainer

    ublic interace I?ist : ICollection( I1numerable-

    M..

    !oid Clear%2!oid Insertob$ect !alue%2!oid Insertint inde0( ob$ect !alue%2!oid 8emo!eob$ect !alue%2!oid 8emo!eint inde0%2M../

    Classes in #yste"Collections naespace

    #yste"CollectionsClass

    %eaning Interfaces ipleented bythe class

    Array?ist Dynamically siOed arrayo ob$ects.

    I?ist( ICollection( I1numerable &ICloneable

    Queue *I* ueue ICollection(ICloneable &I1numerable

    tack ?I* ueue ro!idingush( o & eek

    unctionality

    ICollection & I1numerable

    orted?ist imilar to dictionary IDictionary( ICollection(I1numerable & ICloneable

    7orking with !rray6ist (ype

    As the name Array?ist is used to store a collection o similar tyes o ntrinsic3standard tye. e!eral methods are suorted within this class to insert(delete & modiy the inormation stored within the collection.10: Array?ist cmA?ist = new Array?ist%2

    1

  • 8/18/2019 Interface and Collections

    20/21

    cmA?ist.Add8angenew cmJ - new cm5(%( new cmL(F%/%2

    Console.rite?ineS9o o cms -K/S(cmA?ist.Count%2

    oreachcm c in cmA?ist%- Console.rite?inec.rint%%2 /

    cmA?ist.Insert(new cm5K(K%%2

    Console.rite?ineS9o o cms -K/S(cmA?ist.Count%2

    Add8ange% method o Array?ist is used to oulate Array?ist with a set o comle0 tyes2 which is basically a shorthand notation or calling Add% method nnumber o times.9umber o inormations in the collection is obtained by Count roerty. Insertallows to ut an inormation into the Array?ist at a secifed inde0.

    7rking with 8$e$e (ype

    Queues are containers into which items are accessed using frstHin( frstHout basis.

    %ebers of #yste"Collection"8$e$e

    %ening

    Deueue% 8emo!es & returns the ob$ect atthe beginning o the ueue

    1nueue% Adds an ob$ect to the end o theueue

    eek% 8eturns the ob$ect at thebeginning o the ueue withoutremo!ing it.

    10:

    Queue cmQ = new Queue%2

    cmQ.1nueuenew cm5( %%2cmQ.1nueuenew cmL( F%%2cmQ.1nueuenew cmU( E%%2

    Console.rite?ine"Queue siOe -K/"( cmQ.Count%2

    cm%cmQ.eek%%%.rint%2

    cm%cmQ.Deueue%%%.rint%2cm%cmQ.Deueue%%%.rint/2

    tems are insereted into the ueue using the method 1nueue%. eek% methodallows to !iew the frst item currently in the ueue.

    2*

  • 8/18/2019 Interface and Collections

    21/21

    Deueue% remo!es the item rom the ueue. eek% and Dueue% methods areha!ing the return tye as ob$ect( which is o tye generic. 1nueue% method isha!ing a arameter which is o tye generic3ob$ect.

    7orking with #tack (ype

    tack maintains inormation using a lastHin( frstHout basis. tack defnes amember named ush% & o% to lace an item onto & remo!e items rom thestack. eek% method used to !iew the frst element on the stack.

    10:

    tack cmQ = new tack%2

    cmQ.ushnew cm5( %%2cmQ.ushnew cmL( F%%2cmQ.ushnew cmU( E%%2Console.rite?ine"Queue siOe -K/"( cmQ.Count%2

    cm%cmQ.eek%%%.rint%2

    cm%cmQ.o%%%.rint%2cm%cmQ.o%%%.rint%2


Recommended