• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Metoda wirtualna vs czysto wirtualna

Object Storage Arubacloud
0 głosów
2,425 wizyt
pytanie zadane 11 marca 2018 w C i C++ przez Utau Użytkownik (900 p.)

Hej. Na podstawię tego wpisu dotyczącego polimorfizmu w C#:

https://www.p-programowanie.pl/c-sharp/metody-wirtualne-abstrakcyjne-i-polimorfizm/

Postanowiłam napisać taki prosty programik w C++ aby utrwalić zdobytą wiedzę dotycząca róznic między metodami wirtualnymi a abstrakcyjnymi. Z tacji tego, ze C++ metod abstrakcyjnych nie ma to wykorzystałam metodę czysto wirtualna w przypadku figur i zwykła wirtualna w przypadku pracowników. Wybaczcie istnienie zmiennych napisanych po polsku ale nie miałam zbytnio czasu no i zapomniałam o zasadach nazewnictwa xD.

#ifndef KSZTALT_H
#define KSZTALT_H

class Ksztalt
{
public:
    virtual float Oblicz() = 0;
};

class Kwadrat: public Ksztalt
{
    float a;
public:
    Kwadrat(int x)
    {
        a=x;
    }
    float Oblicz()
    {
        return a*a;
    }
};

class Prostokat: public Ksztalt
{
    float a;
    float b;
public:
    Prostokat(int x, int y)
    {
        a=x;
        b=y;
    }
    float Oblicz()
    {
        return a*b;
    }
};

class Kolo: public Ksztalt
{
    float r;
    const float PI = 3.14;
public:
    Kolo (int x)
    {
        r=x;
    }
    float Oblicz()
    {
        return 2*PI*r;
    }
};

#endif // KSZTALT_H
#define PRACOWNIK_H
#include <iostream>

using namespace std;

class Pracownik
{
public:
    virtual void Pracuj()
    {
        cout <<"Przychodze do pracy i wykonuje ja."<<endl;
    }
};

class Sekretarka: public Pracownik
{
    int wiek = 21;
public:
    void Pracuj()
    {
        Pracownik x;
        x.Pracuj();
        cout<<"Mam "<<wiek<<" lat."<<"Odbieram telefony od klientow"<<endl;
    }
};

class Sprzataczka: public Pracownik
{
    int wiek = 34;
public:
    void Pracuj()
    {
        Pracownik y;
        y.Pracuj();
        cout<<"Mam "<<wiek<<" lat. Sprzatam zaklad pracy."<<endl;
    }
};


#endif // PRACOWNIK_H
#include <iostream>
#include "Ksztalt.h"
#include "Pracownik.h"

using namespace std;

int main()
{
  float wynik;

  Ksztalt *a = new Kwadrat(3);
  Ksztalt *b = new Prostokat(2,3);
  Ksztalt *c = new Kolo(2);

  Pracownik *d = new Sprzataczka();
  Pracownik *e = new Sekretarka();

  cout<<"------------METODY CZYSTO WIRTUALNE----------------"<<endl;
  wynik = a->Oblicz();
  cout<<"Pole kwadratu wynosi: "<<wynik<<endl;
  wynik = b->Oblicz();
  cout<<"Pole prostokata wynosi: "<<wynik<<endl;
  wynik = c->Oblicz();
  cout<<"Pole kola wynosi: "<<wynik<<endl;
  cout<<"------------METODY WIRTUALNE-----------------------"<<endl;
  d->Pracuj();
  e->Pracuj();

  return 0;

}

Przeanalizujcie to bo chcę wiedzieć, czy dobrze to zrozumiałam...rozumiem, ze jak klasy pochodne nie mają metod wykonujących dokładnie to samo to wykorzystujemy metody czysto wirtualne (w C# klasę abstrakcyjną) a jeśli tak to zwykłe wirtualne ?

2 odpowiedzi

+1 głos
odpowiedź 11 marca 2018 przez Patrycjerz Mędrzec (192,320 p.)
wybrane 11 marca 2018 przez Utau
 
Najlepsza
Metody czysto wirtualne służą do stworzenia interfejsu polimorficznego, za pomocą np. wskaźnika na klasę zawierającą takie metody. Chodzi tutaj o to, że z jednego punktu (czyli wskaźnika) możemy wywoływać metody różnych obiektów pochodnych, co ogranicza kopiowanie tego samego kodu dla różnych typów.

Metody wirtualne zaś działają tak samo jak metody czysto wirtualne, ale umożliwiają stworzenie obiektu klasy bazowej. We wcześniejszym przypadku klasa służyła nam jedynie za interfejs.
komentarz 11 marca 2018 przez Utau Użytkownik (900 p.)
Hmm czyli w moim przykładzie zastosowałam to i dobrze to rozumuje ? :P
1
komentarz 11 marca 2018 przez Patrycjerz Mędrzec (192,320 p.)

Sam kod wygląda spoko, wykorzystuje polimorfizm, ale mam jedno zastrzeżenie. Niepotrzebnie tworzysz obiekty klasy Pracownik w metodach Pracuj. Zauważ, że klasa pochodna dziedziczy wszystkie metody, nawet te zasłonięte. Możesz się do nich dostać za pomocą nazwy klasy bazowej i operatora ::.

Pracownik::Pracuj();
komentarz 11 marca 2018 przez Utau Użytkownik (900 p.)
Dzięki! Już notuje :)

Widzę alternatywę do C# base
komentarz 11 marca 2018 przez Patrycjerz Mędrzec (192,320 p.)
Drobna korekta w odpowiedzi.
0 głosów
odpowiedź 11 marca 2018 przez Utau Użytkownik (900 p.)

Czyli w C# będzie to wyglądało tak ? (znów wybaczcie polski język w kodzie xD):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Metody_wirtualne_i_abstrakcyjne
{
    abstract public class Figury2D
    {
        abstract public double Oblicz();
        abstract public void Rysuj();
    }

    class Kwadrat: Figury2D
    {
        protected float a;
        public Kwadrat(float x)
        {
            a = x;
        }
        public override double Oblicz()
        {
            return a*a;
        }
        public override void Rysuj()
        {
            Console.WriteLine("Pole kwadratu jest rowne: "+Oblicz().ToString());
        }
    }

    class Prostokat: Kwadrat
    {
        private float b;
        public Prostokat(float x, float y): base(x)
        {
            a = x;
            b = y;
        }
        public override double Oblicz()
        {
            return a * b;
        }

        public override void Rysuj()
        {
            Console.WriteLine("Pole prostokata jest rowne: " + Oblicz().ToString());
        }
    }

    class Kolo: Kwadrat
    {
        private const double PI = 3.14;
        public Kolo(float x): base(x)
        {
            a = x;
        }
        public override double Oblicz()
        {
            return 2 * PI * a;
        }
        public override void Rysuj()
        {
            Console.WriteLine("Pole kola wynosi: " + Oblicz().ToString());
        
        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Metody_wirtualne_i_abstrakcyjne
{
    class Program
    {
        static void Main(string[] args)
        {

            Figury2D kw = new Kwadrat(2);
            Figury2D pr = new Prostokat(3, 4);
            Figury2D kol = new Kolo(2);

            kw.Rysuj();
            pr.Rysuj();
            kol.Rysuj();


            Console.ReadLine();
        }
    }
}

Tak wiem, męczę :P

Podobne pytania

0 głosów
2 odpowiedzi 1,049 wizyt
pytanie zadane 8 grudnia 2018 w C i C++ przez dawid2002 Mądrala (5,190 p.)
0 głosów
1 odpowiedź 199 wizyt
0 głosów
4 odpowiedzi 425 wizyt
pytanie zadane 3 maja 2015 w C i C++ przez Waszek Gaduła (4,130 p.)

92,695 zapytań

141,606 odpowiedzi

320,106 komentarzy

62,052 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...