Joskus kaikkia toimintoja ei voida toteuttaa perusluokassa, koska emme tiedä toteutusta. Tällaista luokkaa kutsutaan an abstrakti luokka .Annetaan esimerkiksi Shapen perusluokka. Emme voi tarjota funktion draw() toteutusta Shapessa, mutta tiedämme, että jokaisessa johdetussa luokassa on oltava draw() toteutus. Vastaavasti Animal-luokassa ei ole move()-toteutusta (olettaen, että kaikki eläimet liikkuvat), mutta kaikkien eläinten on osattava liikkua. Emme voi luoda abstraktien luokkien objekteja.
A puhdas virtuaalinen toiminto (tai abstrakti funktio) C++:ssa on virtuaalinen funktio, jolle meillä voi olla toteutus, mutta meidän on ohitettava tämä funktio johdetussa luokassa, muuten johdetusta luokasta tulee myös abstrakti luokka. Puhdas virtuaalinen funktio ilmoitetaan määrittämällä 0 ilmoituksessa.
Esimerkki puhtaista virtuaalifunktioista
C++
// An abstract class> class> Test {> >// Data members of class> public>:> >// Pure Virtual Function> >virtual> void> show() = 0;> >/* Other members */> };> |
>
>
Täydellinen esimerkki
Puhdas virtuaalinen funktio toteutetaan luokilla, jotka on johdettu abstraktista luokasta.
C++
// C++ Program to illustrate the abstract class and virtual> // functions> #include> using> namespace> std;> class> Base {> >// private member variable> >int> x;> public>:> >// pure virtual function> >virtual> void> fun() = 0;> >// getter function to access x> >int> getX() {>return> x; }> };> // This class inherits from Base and implements fun()> class> Derived :>public> Base {> >// private member variable> >int> y;> public>:> >// implementation of the pure virtual function> >void> fun() { cout <<>'fun() called'>; }> };> int> main(>void>)> {> >// creating an object of Derived class> >Derived d;> >// calling the fun() function of Derived class> >d.fun();> >return> 0;> }> |
>
arraylist java
>Lähtö
fun() called>
Muutamia mielenkiintoisia faktoja
1. Luokka on abstrakti, jos sillä on vähintään yksi puhdas virtuaalifunktio.
Esimerkki
Alla olevassa C++-koodissa Testi on abstrakti luokka, koska sillä on puhdas virtuaalinen funktio show().
C++
// C++ program to illustrate the abstract class with pure> // virtual functions> #include> using> namespace> std;> class> Test {> >// private member variable> >int> x;> public>:> >// pure virtual function> >virtual> void> show() = 0;> >// getter function to access x> >int> getX() {>return> x; }> };> int> main(>void>)> {> >// Error: Cannot instantiate an abstract class> >Test t;> >return> 0;> }> |
kuinka monta kaupunkia on yhdysvalloissa
>
>
Lähtö
Compiler Error: cannot declare variable 't' to be of abstract type 'Test' because the following virtual functions are pure within 'Test': note: virtual void Test::show()>
2. Meillä voi olla abstrakteja luokkatyyppisiä osoittimia ja viittauksia.
Esimerkiksi seuraava ohjelma toimii hyvin.
C++
// C++ program that demonstrate that> // we can have pointers and references> // of abstract class type.> #include> using> namespace> std;> class> Base {> public>:> >// pure virtual function> >virtual> void> show() = 0;> };> class> Derived :>public> Base {> public>:> >// implementation of the pure virtual function> >void> show() { cout <<>'In Derived
'>; }> };> int> main(>void>)> {> >// creating a pointer of type> >// Base pointing to an object> >// of type Derived> >Base* bp =>new> Derived();> >// calling the show() function using the> >// pointer> >bp->näytä();> >return> 0;> }> |
>
>Lähtö
In Derived>
3. Jos emme ohita johdetun luokan puhdasta virtuaalista funktiota, niin johdetusta luokasta tulee myös abstrakti luokka.
Seuraava esimerkki osoittaa saman.
C++
// C++ program to demonstrate that if we do not override> // the pure virtual function in the derived class, then> // the derived class also becomes an abstract class> #include> using> namespace> std;> class> Base {> public>:> >// pure virtual function> >virtual> void> show() = 0;> };> class> Derived :>public> Base {> };> int> main(>void>)> {> >// creating an object of Derived class> >Derived d;> >return> 0;> }> |
>
>
Lähtö
Compiler Error: cannot declare variable 'd' to be of abstract type 'Derived' because the following virtual functions are pure within 'Derived': virtual void Base::show()>
4. Abstraktilla luokalla voi olla konstruktoreita.
Esimerkiksi seuraava ohjelma käännetään ja toimii hyvin.
C++
silmukalle bashissa
// C++ program to demonstrate that> // an abstract class can have constructors.> #include> using> namespace> std;> // An abstract class with constructor> class> Base {> protected>:> >// protected member variable> >int> x;> public>:> >// pure virtual function> >virtual> void> fun() = 0;> >// constructor of Base class> >Base(>int> i)> >{> >x = i;> >cout <<>'Constructor of base called
'>;> >}> };> class> Derived :>public> Base {> >// private member variable> >int> y;> public>:> >// calling the constructor of Base class> >Derived(>int> i,>int> j)> >: Base(i)> >{> >y = j;> >}> >// implementation of pure virtual function> >void> fun()> >{> >cout <<>'x = '> << x <<>', y = '> << y <<>'
'>;> >}> };> int> main(>void>)> {> >// creating an object of Derived class> >Derived d(4, 5);> >// calling the fun() function of Derived class> >d.fun();> >// creating an object of Derived class using> >// a pointer of the Base class> >Base* ptr =>new> Derived(6, 7);> >// calling the fun() function using the> >// pointer> >ptr->hauskaa();> >return> 0;> }> |
>
>Lähtö
Constructor of base called x = 4, y = 5 Constructor of base called x = 6, y = 7>
5. Abstrakti luokka C++:ssa voidaan määritellä myös struct-avainsanalla.
Esimerkki
struct shapeClass { virtual void Draw()=0; }> Vertailu Javaan
Javassa luokka voidaan tehdä abstraktiksi käyttämällä abstraktia avainsanaa. Vastaavasti funktiosta voidaan tehdä puhdas virtuaalinen tai abstrakti käyttämällä abstraktia avainsanaa. Katso Abstraktit luokat Javassa Lisätietoja.
Käyttöliittymä vs. abstraktit luokat
Liitännässä ei ole toteutettua sen menetelmiä, vaan sitä voidaan pitää kokoelmana menetelmän määrittelyjä. C++:ssa käyttöliittymää voidaan simuloida tekemällä kaikista menetelmistä puhtaita virtuaalisia. Javassa käyttöliittymälle on erillinen avainsana.
Voimme ajatella Interfacea otsikkotiedostoina C++:ssa, kuten otsikkotiedostoissa, tarjoamme vain sen luokan rungon, joka aikoo toteuttaa sen. Vastaavasti Java in Interface -sovelluksessa tarjoamme vain luokan rungon ja kirjoitamme varsinaisen koodin siihen luokkaan, joka sen toteuttaa.