• 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,397 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,022 wizyt
pytanie zadane 8 grudnia 2018 w C i C++ przez dawid2002 Mądrala (5,190 p.)
0 głosów
1 odpowiedź 191 wizyt
0 głosów
4 odpowiedzi 414 wizyt
pytanie zadane 3 maja 2015 w C i C++ przez Waszek Gaduła (4,130 p.)

92,570 zapytań

141,422 odpowiedzi

319,643 komentarzy

61,958 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

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

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!

...