Polimorfizm metod wirtualnych

Polimorfizm metod wirtualnych jest wielorakością występowania tych samych metod w klasach dziedziczących po klasie bazowej. Obiekt potomny ma możliwość innego zachowania niż rodzic dla wywołania tych samych funkcji. Polimorfizm metod wirtualnych jest dynamicznym przysłanianiem funkcji rodzica.

Zasada tworzenia metod wirtualnych

Metoda wirtualna w klasie bazowej rodzica zadeklarowana jest począwszy od słowa kluczowego virtual. Przykładowo tworzymy klasę bazową związaną z figurami płaskim. Każda figura płaska ma pole i obwód, ale inaczej liczone. Wstępna deklaracja tych metod w klasie rodzica może wyglądać jak poniżej

Wskazówka:


virtual public float Obwod() { return 0; }
virtual public float Pole() { return 0; }
virtual public float Przekatna() { return 0; }
virtual public float Srednica() { return 0; }

W klasach potomnych związanych z konkretną figurą płaską wykonuje się właściwe przysłonięcie metody, w tym przypadku zastosowanie poprawnego wzoru liczącego daną cechę figury. Przysłonięcie metody rozpoczyna się od słowa kluczowego override.

Na przykład dla okręgu metodę Pole zdefiniujemy jak poniżej

Wskazówka:


override public float Pole()
{
	//nadpisz bazowa metodę licząca pole
	//nową tożsamą ze wzorem pola okręgu
	return (float)Math.PI*Odcinek[0]*Odcinek[0];
}

Zaś dla kwadratu będzie to poniższy kod

Wskazówka:


override public float Pole()
{
	//nadpisz bazowa metodę licząca pole
	//na nową tożsamą ze wzorem pola kwadratu
	return Odcinek[0] * Odcinek[0];
}

Ćwiczenie:

Napisz aplikację, która będzie zawierać klasę bazową z metodami wirtualnymi pozwalającymi obliczyć obwód, pole, przekątną, średnicę, promień figury płaskiej. W projekcie utwórz klasy potomne klasy bazowej przeznaczone dla okręgu, kwadratu, trójkąta, prostokąta, rombu, trapezu. W klasach potomnych oprogramuj odpowiednie metody zdefiniowane w klasie bazowej (metody pozwalające obliczyć obwód, pole itp.)

polimorfizm metod wirtualnych, Visual Studio C#

Wymagania na klasę bazową

Ta część materiału jest kontynuacją tematu Klasa w języku C#

Klasa bazowa ma zawierać listę odcinków tworzących figurę płaską. Dla okręgu będzie to jeden odcinek, który jest promieniem. Ma zawierać prywatną zmienną do przechowywani nazwy figury płaskiej. Dostęp do tej zmiennej zrealizujemy metodą get/set

Wskazówka:


internal class ObiektPlaski
{
	private int n;//ilość odcinków
	private List<float> odcinek;
	private String nazwa = "";

	//metoda przypisuje i zwraca
	//nazwę tworzonego obiektu
	public String Nazwa { 
		  set { nazwa = value; } 
		  get { return nazwa; } 
	} 

Propozycja metod wirtualnych wygląda jak poniżej

Wskazówka:


        //definicja nagłówków wirtualnych metod przeznaczonych
        //do nadpisania w klasach dziedziczących
        virtual public float Obwod() { return 0; }
        virtual public float Pole() { return 0; }
        virtual public float Przekatna() { return 0; }
        virtual public float Srednica() { return 0; }
        virtual public void Promien(float R) { }

Pełen kod klasy bazowej wraz z proponowanym konstruktorem i destruktorem

Wskazówka:


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

namespace FiguryPolimorfizmMetodWirtualnych
{
    internal class ObiektPlaski
    {
        private int n;//ilość odcinków
        private List<float> odcinek;
        private String nazwa = "";

        //metoda przypisuje i zwraca
        //nazwę tworzonego obiektu
        public String Nazwa { 
              set { nazwa = value; } 
              get { return nazwa; } 
        }  
        public int IleOdcinkow
        {
            set{n = value;//ustaw ile odcinkow ma obiekt plaski
                odcinek.Clear();//czysc liste odcinkow
                //ustaw dlugosci odcinkow na zero
                for (int i = 0; i < n; i++) odcinek.Add(0);
            }
            get { return n; }//zwróć ilość odcinków
        }

        public List<float> Odcinek { 
            //metoda zwraca liste odcinków
            //tworzacych obiekt plaski
            get { return odcinek; } 
        }

        //konstruktor
        public ObiektPlaski(int ileOdcinkow) 
        { 
            odcinek=new List<float>();
            IleOdcinkow = ileOdcinkow;
        }
        //destruktor
        ~ObiektPlaski()
        {
            odcinek.Clear();
            odcinek = null;
        }
        //definicja nagłówków wirtualnych metod przeznaczonych
        //do nadpisania w klasach dziedziczących
        virtual public float Obwod() { return 0; }
        virtual public float Pole() { return 0; }
        virtual public float Przekatna() { return 0; }
        virtual public float Srednica() { return 0; }
        virtual public void Promien(float R) { }
    }
}

Tworzymy klasę potomną dla okręgu

Wybierając menu Projekt/ Dodaj klasę? definiujemy klasę potomną o nazwie Okrag

Tworzymy klasę potomną dla okręgu. Visual Studio C#

Wewnątrz klasy Okrag utwórz konstruktor dla figury typu okrąg. Zwróć uwagę, że jest tylko jeden odcinek, i ten odcinek będzie przechowywać informację o długości promienia okręgu

Wskazówka:


public Okrag(int ileOdcinkow,float R) : base(ileOdcinkow) 
{
	//nowy konstruktor odpowiednio zmodyfikowany
	//dla okręgu
	//zerowy odcinek to promien
	Odcinek[0] = R;
	Nazwa="Okrąg";
}

Pamiętaj, że lista odcinków jest tworzona w konstruktorze klasy bazowej. W klasie potomnej konstruktor wymaga podania rozmiaru listy odcinków (czyli 1) oraz promienia okręgu (patrz w dalszej części kodu przy wywołaniu obiektu typu Okrag)

Zdefiniuj metody przysłaniające obliczanie pola, średnicy i obwodu okręgu

Wskazówka:


override public float Pole()
{
	//nadpisz bazowa metodę licząca pole
	//nową tożsamą ze wzorem pola okręgu
	return (float)Math.PI*Odcinek[0]*Odcinek[0];
}
override public float Srednica()
{
	//nadpisz bazową metodę liczącą pole
	//nową tożsamą ze wzorem na średnicę okręgu
	return 2 * Odcinek[0];
}
override public float Obwod()
{
	//nadpisz bazową metodę liczącą obwód
	//nową tożsamą ze wzorem na obwód okręgu
	return 2 * (float)Math.PI* Odcinek[0];
}

Pełny kod klasy Okrag

Wskazówka:


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

namespace FiguryPolimorfizmMetodWirtualnych
{
    //
    internal class Okrag : ObiektPlaski
    {
        public Okrag(int ileOdcinkow,float R) : base(ileOdcinkow) 
            {
                //nowy konstruktor odpowiednio zmodyfikowany
                //dla okręgu
                //zerowy odcinek to promien
                Odcinek[0] = R;
                Nazwa="Okrąg";
            }
        
        override public float Pole()
        {
            //nadpisz bazowa metodę licząca pole
            //nową tożsamą ze wzorem pola okręgu
            return (float)Math.PI*Odcinek[0]*Odcinek[0];
        }
        override public float Srednica()
        {
            //nadpisz bazową metodę liczącą pole
            //nową tożsamą ze wzorem na średnicę okręgu
            return 2 * Odcinek[0];
        }
        override public float Obwod()
        {
            //nadpisz bazową metodę liczącą obwód
            //nową tożsamą ze wzorem na obwód okręgu
            return 2 * (float)Math.PI* Odcinek[0];
        }
    }
}

Tworzymy klasą potomną dla kwadratu

Powtórz kroki związane z dodawaniem nowej klasy do projektu. Nową klasę nazwij Kwadrat i wypełnij ją poniższym kodem

Wskazówka:


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

namespace FiguryPolimorfizmMetodWirtualnych
{
    internal class Kwadrat : ObiektPlaski
    {
        public Kwadrat(int ileOdcinkow, float a) : base(ileOdcinkow)
        {
            //nowy konstruktor odpowiednio zmodyfikowany
            //dla kwadratu
            //zerowy odcinek to bok
            Odcinek[0] = a;
            Nazwa = "Kwadrat";
        }
        override public float Pole()
        {
            //nadpisz bazowa metodę licząca pole
            //na nową tożsamą ze wzorem pola kwadrau
            return Odcinek[0] * Odcinek[0];
        }
        override public float Obwod()
        {
            //nadpisz bazową metodę liczącą obwód
            //na nową tożsamą ze wzorem na obwód kawdratu
            return 4 *  Odcinek[0];
        }
        override public float Przekatna()
        {
            //nadpisz bazową metodę liczącą przekatną
            //na nową tożsamą ze wzorem na przekatną kawdratu
            return Odcinek[0]*(float)Math.Pow(2,0.5);
        }
    }
}

Tworzymy formatkę do obecnego projektu aplikacji

Na formatce umieść kontrolki pozwalające zdefiniować dowolny okrąg i kwadrat. Do wyprowadzania wyników może posłużyć jedna wspólna kontrolka typu TextBox ustawiona do pracy w układzie wielu linii

polimorfizm aplikacja. Visual Studio C#

W zdarzeniu Click odpowiednich kontrolek typu Button zdefiniuj lokalne zmienne typu Okrag i Kwadrat, i zwróć informacje o ich podstawowych właściwościach

Proponowany kod dla okręgu

Wskazówka:


private void button1_Click(object sender, EventArgs e)
{
	if (textBox1.Text.Length < 1) return;
	float r = (float)Convert.ToDouble(textBox1.Text);
	Okrag o = new Okrag(1, r);
	textBox2.Clear();
	textBox2.AppendText("UTWORZONO "+o.Nazwa + Environment.NewLine);
	textBox2.AppendText("PODSTAWOWE DANE:"+ Environment.NewLine);
	textBox2.AppendText("Promień = " + o.Odcinek[0].ToString("F2")
						 + Environment.NewLine);
	textBox2.AppendText("Średnica = " + o.Srednica().ToString("F2")
						 + Environment.NewLine);
	textBox2.AppendText("Obwód = " + o.Obwod().ToString("F2")
						 + Environment.NewLine);
	textBox2.AppendText("Pole = " + o.Pole().ToString("F2")
						 + Environment.NewLine);
}

Proponowany kod dla kwadratu

Wskazówka:


private void button2_Click(object sender, EventArgs e)
{
	if (textBox3.Text.Length < 1) return;
	float a = (float)Convert.ToDouble(textBox3.Text);
	Kwadrat k = new Kwadrat(1, a);
	textBox2.Clear();
	textBox2.AppendText("UTWORZONO " + k.Nazwa + Environment.NewLine);
	textBox2.AppendText("PODSTAWOWE DANE:" + Environment.NewLine);
	textBox2.AppendText("Bok = " + k.Odcinek[0].ToString("F2")
						 + Environment.NewLine);
	textBox2.AppendText("Obwód = " + k.Obwod().ToString("F2")
						 + Environment.NewLine);
	textBox2.AppendText("Pole = " + k.Pole().ToString("F2")
						 + Environment.NewLine);
	textBox2.AppendText("Przekątna = " + k.Przekatna().ToString("F2")
						 + Environment.NewLine);
}

Pełny kod klasy Form1.cs

Wskazówka:


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace FiguryPolimorfizmMetodWirtualnych
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            if (textBox1.Text.Length < 1) return;
            float r = (float)Convert.ToDouble(textBox1.Text);
            Okrag o = new Okrag(1, r);
            textBox2.Clear();
            textBox2.AppendText("UTWORZONO "+o.Nazwa + Environment.NewLine);
            textBox2.AppendText("PODSTAWOWE DANE:"+ Environment.NewLine);
            textBox2.AppendText("Promień = " + o.Odcinek[0].ToString("F2")
                                 + Environment.NewLine);
            textBox2.AppendText("Średnica = " + o.Srednica().ToString("F2")
                                 + Environment.NewLine);
            textBox2.AppendText("Obwód = " + o.Obwod().ToString("F2")
                                 + Environment.NewLine);
            textBox2.AppendText("Pole = " + o.Pole().ToString("F2")
                                 + Environment.NewLine);
        }

        private void button2_Click(object sender, EventArgs e)
        {
            if (textBox3.Text.Length < 1) return;
            float a = (float)Convert.ToDouble(textBox3.Text);
            Kwadrat k = new Kwadrat(1, a);
            textBox2.Clear();
            textBox2.AppendText("UTWORZONO " + k.Nazwa + Environment.NewLine);
            textBox2.AppendText("PODSTAWOWE DANE:" + Environment.NewLine);
            textBox2.AppendText("Bok = " + k.Odcinek[0].ToString("F2")
                                 + Environment.NewLine);
            textBox2.AppendText("Obwód = " + k.Obwod().ToString("F2")
                                 + Environment.NewLine);
            textBox2.AppendText("Pole = " + k.Pole().ToString("F2")
                                 + Environment.NewLine);
            textBox2.AppendText("Przekątna = " + k.Przekatna().ToString("F2")
                                 + Environment.NewLine);
        }
    }
}

Zadanie

Rozbuduj aplikację o pozostałe figury: trójkąt, romb, trapez.

Alkomat- wirtualny test

Alkomat- darmowa aplikacja na Androida

Pobierz ze sklepu Google Play
Olinowanie stałe- kalkulator średnic

Olinowanie stałe- darmowa aplikacja na Androida

Pobierz ze sklepu Google Play
przepis na gogfry

Przepis na gofry

zobacz
przepis na bitą śmietanę

Przepis na bitą śmietanę

zobacz