Temat: Polimorfizm. Metody. Dziedziczenie.
Dodamy pozycję menu Edycja stopnia, która będzie miał 3 pozycje:
1. Gwint (zrealizujemy rysowanie gwintu na wskazanym stopniu), 2. Pręt (rysowanie, w uproszczeniu, symbolu rysunkowego pręta), 3. Usuń modyfikację (usuwanie powyższych modyfikacji
rysowanych na stopniu)
Zrealizujemy powyższe zamierzenia następująco:
Dodamy nowe pozycje w zmiennej wyliczeniowej TrybPracy:
- UsunModyfikacje - StworzPret - StworzGwint
Dodamy klasę bazową Modyfikacja_stopnia, która
(1) będzie musiała mieć 3 klasy potomne (atrybut MustInherit).
będą to klasy Bez_modyfikacji, Pret i Gwint.
(2) Dodatkowo klasa Gwint będzie posiadała zmienną lokalną _gwint, z atrybutem Protected - określającą, przy pomocy konstruktora (New) głębokość gwintu.
(3) klasa Modyfikacja_stopnia będzie posiadała metodę abstrakcyjną (polimorfizm), o nazwie Narysuj() (rysującą modyfikację stopnia), ale metoda ta, w klasie bazowej, nie będzie nic rysowała. Metoda będzie bez treści i nawet bez „End Sub”, za to z atrybutem MustOverride („będzie nadpisywana”).
Jej 3 klasy potomne, natomiast, będą posiadały metodę Narysuj() (z atrybutem Overrides) rysującą, w uproszczeniu, modyfikację stopnia, czyli pręt, gwint lub dla klasy Bez_modyfikacji – nic nie rysującą.
Aby stopień wału posiadał informację („wiedział”) o tym jaka modyfikacja jest na nim realizowana – dodamy do klasy Stopien_walu właściwość _powStopnia klasy Modyfikacja_stopnia. Dzięki temu na stopniu będzie można rysować wymaganą modyfikację (pręt, gwint lub bez modyfikacji).
Edycja stopnia
Aby móc edytować (zmieniać powierzchnię, modyfikację stopnia - gwint, pręt, nic) - do klasy Stopien_walu i jej klas potomnych StopienFazaZPrawej i StopienFazaZLewej, dodamy metody:
- ZmienPowierzchnieNaGwint, - ZmienPowierzchnieNaPret
- a do klasy Stopien_walu – jeszcze metodę ZmienPowierzchnieNaZwykla.
Dla klasy Stopien_walu metody powyższe uruchamiają konstruktory (New) - tworzące instancje obiektów klasy Bez_modyfikacji, Pret lub Gwint(8).
Dla klas potomnych StopienFazaZPrawej i StopienFazaZLewej utworzymy metody - ZmienPowierzchnieNaGwint z konstruktorem (New) definiującym gwint,
- ZmienPowierzchnieNaPret z ostrzeżeniem (MsgBox), że na stopniu z fazą nie można zbudować pręta.
Musimy także dopisać do każdej metody Rysuj(...) wiersz _powStopnia.Narysuj(...) uruchamiający metodę rysującą modyfikację dla tego stopnia.
Class1.vb
Public Class Stopien_walu
'Private _Srednica_stopnia As Single 'Private _Dlugosc_stopnia As Single Protected _Srednica_stopnia As Single Protected _Dlugosc_stopnia As Single
Protected _powStopnia As Modyfikacja_stopnia Sub New()
_powStopnia = New Bez_modyfikacji End Sub
Public Property Srednica_stopnia As Single Get
Return _Srednica_stopnia End Get
Set(value As Single)
_Srednica_stopnia = value End Set
End Property
Public Property Dlugosc_stopnia As Single Get
Return _Dlugosc_stopnia End Get
Set(value As Single)
_Dlugosc_stopnia = value End Set
End Property
Public Overridable Sub Rysuj(ByVal objRys As Graphics, ByVal objPioro As Pen, ByVal pozycja_x As Single, ByVal pozycja_y As Single) 'Rysowanie stopnia zykłego, czyli prostokąta
objRys.DrawRectangle(objPioro, pozycja_x, pozycja_y - _Srednica_stopnia / 2, _ _Dlugosc_stopnia, _Srednica_stopnia)
_powStopnia.Narysuj(objRys, pozycja_x, pozycja_y, Me) 'Rysowanie modyfikacji End Sub
Public Sub ZmienPowierzchnieNaZwykla() _powStopnia = New Bez_modyfikacji End Sub
Public Overridable Sub ZmienPowierzchnieNaPret() _powStopnia = New Pret
End Sub
Public Overridable Sub ZmienPowierzchnieNaGwint() _powStopnia = New Gwint(8)
End Sub End Class
Public Class StopienFazaZLewej Inherits Stopien_walu
Private _faza As Single
Public Property Faza As Single Get
Return _faza End Get
Set(value As Single) _faza = value End Set
End Property
Public Overrides Sub Rysuj(ByVal objRys As System.Drawing.Graphics, _ ByVal objPioro As Pen,
ByVal pozycja_x As Single, ByVal pozycja_y As Single) 'Rysowanie stopnia z fazą z lewej strony
objRys.DrawRectangle(objPioro, pozycja_x + _faza, pozycja_y - _Srednica_stopnia / 2, _
_Dlugosc_stopnia - _faza, _Srednica_stopnia) objRys.DrawLine(objPioro, pozycja_x, pozycja_y - _Srednica_stopnia / 2 + _faza, _ pozycja_x + _faza, pozycja_y - _Srednica_stopnia / 2) objRys.DrawLine(objPioro, pozycja_x, pozycja_y + _Srednica_stopnia / 2 - _faza, _ pozycja_x + _faza, pozycja_y + _Srednica_stopnia / 2) objRys.DrawLine(objPioro, pozycja_x, pozycja_y + _Srednica_stopnia / 2 - _faza, _ pozycja_x, pozycja_y - _Srednica_stopnia / 2 + _faza) _powStopnia.Narysuj(objRys, pozycja_x, pozycja_y, Me) 'Rysowanie modyfikacji End Sub
Public Overrides Sub ZmienPowierzchnieNaGwint() _powStopnia = New Gwint(_faza)
End Sub
Public Overrides Sub ZmienPowierzchnieNaPret()
MsgBox("Na tym stopniu nie można zbudować pręta") End Sub
End Class
Public Class StopienFazaZPrawej Inherits Stopien_walu
Private _faza As Single
Public Property Faza As Single Get
Return _faza End Get
Set(value As Single) _faza = value End Set
End Property
Public Overrides Sub Rysuj(ByVal objRys As System.Drawing.Graphics, _ ByVal objPioro As Pen,
ByVal pozycja_x As Single, ByVal pozycja_y As Single) 'Rysowanie stopnia z fazą z prawej strony
objRys.DrawRectangle(objPioro, pozycja_x, pozycja_y - _Srednica_stopnia / 2, _ _Dlugosc_stopnia - _faza, _Srednica_stopnia) objRys.DrawLine(objPioro, _
pozycja_x + _Dlugosc_stopnia, pozycja_y - _Srednica_stopnia / 2 + _faza, _ pozycja_x + _Dlugosc_stopnia - _faza, pozycja_y - _Srednica_stopnia / 2) objRys.DrawLine(objPioro, _
pozycja_x + _Dlugosc_stopnia, pozycja_y + _Srednica_stopnia / 2 - _faza, _ pozycja_x + _Dlugosc_stopnia - _faza, pozycja_y + _Srednica_stopnia / 2) objRys.DrawLine(objPioro, _
pozycja_x + _Dlugosc_stopnia, pozycja_y + _Srednica_stopnia / 2 - _faza, _ pozycja_x + _Dlugosc_stopnia, pozycja_y - _Srednica_stopnia / 2 + _faza) _powStopnia.Narysuj(objRys, pozycja_x, pozycja_y, Me) 'Rysowanie modyfikacji End Sub
Public Overrides Sub ZmienPowierzchnieNaGwint() _powStopnia = New Gwint(_faza)
End Sub
Public Overrides Sub ZmienPowierzchnieNaPret()
MsgBox("Na tym stopniu nie można zbudować pręta") End Sub
End Class
'Nowa klasa – Modyfikacja_stopnia + 3 klasy potomne(1) Bez_modyfikacji, (2) Pret, (3) Gwint
Public MustInherit Class Modyfikacja_stopnia
Public MustOverride Sub Narysuj(ByVal objRys As Graphics, _
ByVal pozycja_x As Single, ByVal pozycja_y As Single, ByVal st As Stopien_walu) 'Rysowanie modyfikacji na wskazanym stopniu
End Class
Public Class Bez_modyfikacji Inherits Modyfikacja_stopnia
Public Overrides Sub Narysuj(ByVal objRys As Graphics, ByVal pozycja_x As Single, _ ByVal pozycja_y As Single, ByVal st As Stopien_walu) 'Rysowanie modyfikacji na stopniu
'ale tu klasa Bez_modyfikacji, a więc nic nie jest rysowane.) End Sub
End Class
Public Class Pret
Inherits Modyfikacja_stopnia
Public Overrides Sub Narysuj(ByVal objRys As Graphics,
ByVal pozycja_x As Single, ByVal pozycja_y As Single, ByVal st As Stopien_walu)
'Rysowanie modyfikacji czyli Pręta na stopniu Dim objPioro As New Pen(Color.Red, 1)
'Linia 1-3
objRys.DrawLine(objPioro, _
pozycja_x, pozycja_y + st.Srednica_stopnia / 2, _
pozycja_x + st.Dlugosc_stopnia, pozycja_y - st.Srednica_stopnia / 2) 'Linia 2-4
objRys.DrawLine(objPioro, _
pozycja_x, pozycja_y - st.Srednica_stopnia / 2, _
pozycja_x + st.Dlugosc_stopnia, pozycja_y + st.Srednica_stopnia / 2) End Sub
End Class
Public Class Gwint
Inherits Modyfikacja_stopnia Private _gwint As Single
Sub New(ByVal glebokosc_gwintu As Single) _gwint = glebokosc_gwintu
End Sub
Public Overrides Sub Narysuj(ByVal objRys As Graphics,
ByVal pozycja_x As Single, ByVal pozycja_y As Single, ByVal st As Stopien_walu)
'Rysowanie modyfikacji czyli Gwintu na stopniu
Dim objPioro As New System.Drawing.Pen(Brushes.Red, 1) 'Linia 1-2
objRys.DrawLine(objPioro, _
pozycja_x, pozycja_y - st.Srednica_stopnia / 2 + _gwint, _
pozycja_x + st.Dlugosc_stopnia, pozycja_y - st.Srednica_stopnia / 2 + _gwint) 'Linia 4-3
objRys.DrawLine(objPioro, _
pozycja_x, pozycja_y + st.Srednica_stopnia / 2 - _gwint, _
pozycja_x + st.Dlugosc_stopnia, pozycja_y + st.Srednica_stopnia / 2 - _gwint) End Sub
End Class
Public Enum TrybPracy NicNieRob
NowyStopien
UsunStopien StworzGwint StworzPret UsunModyfikacje End Enum
Form1.vb
Public Class Form1
Dim objRys As System.Drawing.Graphics
Dim objPioroWal As New System.Drawing.Pen(Color.Red, 2) Dim objPioroOs As New System.Drawing.Pen(Color.Green) Dim X_osi As Integer = 50
Dim Y_osi As Integer = 200 Dim x_pocz As Integer = X_osi Dim mode As TrybPracy
Dim Kolekcja_stopni_walu As New List(Of Stopien_walu) Dim faza As Single
Private Sub Form1_MouseMove(sender As Object, e As MouseEventArgs) _
Handles MyBase.MouseMove LabelKoordynaty.Text = "X=" & e.X & " Y=" & e.Y
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load objRys = Me.CreateGraphics
mode = TrybPracy.NicNieRob End Sub
Private Sub Form1_Paint(sender As Object, e As PaintEventArgs) Handles MyBase.Paint Call RysujOsie(e.Graphics)
End Sub
Private Sub RysujOsie()
objRys.DrawLine(objPioroOs, X_osi, 50, X_osi, 350) objRys.DrawLine(objPioroOs, X_osi, Y_osi, 700, Y_osi) End Sub
Private Sub Form1_MouseClick(sender As Object, e As MouseEventArgs) _
Handles MyBase.MouseClick Dim x1 As Single
Dim y1 As Single
Dim mojStopien As Stopien_walu
''Dim mojStopien As New Stopien_walu Dim mojStopienL As StopienFazaZLewej Dim mojStopienP As StopienFazaZPrawej x1 = e.X
y1 = e.Y
If mode = TrybPracy.NowyStopien Then ''mojStopien = New Stopien_walu If faza = 0 Then
mojStopien = New Stopien_walu Else
If faza > 0 Then
mojStopienL = New StopienFazaZLewej mojStopienL.Faza = faza
mojStopien = mojStopienL Else
mojStopienP = New StopienFazaZPrawej mojStopienP.Faza = Math.Abs(faza) mojStopien = mojStopienP
End If End If
mojStopien.Dlugosc_stopnia = x1 - x_pocz
mojStopien.Srednica_stopnia = (Y_osi - y1) * 2
''objRys.DrawRectangle(objPioroWal, x_pocz, y1, x1 - x_pocz, (Y_osi - y1) * 2) ''x_pocz = x1
mojStopien.Rysuj(objRys, objPioroWal, x_pocz, Y_osi) x_pocz = x_pocz + mojStopien.Dlugosc_stopnia
Kolekcja_stopni_walu.Add(mojStopien) ElseIf mode = TrybPracy.UsunStopien Then
Kolekcja_stopni_walu.Remove(KliknietyStopien(x1)) Call OdswiezWalek()
ElseIf mode = TrybPracy.UsunModyfikacje Then mojStopien = KliknietyStopien(x1)
mojStopien.ZmienPowierzchnieNaZwykla() Call OdswiezWalek()
ElseIf mode = TrybPracy.StworzPret Then mojStopien = KliknietyStopien(x1) mojStopien.ZmienPowierzchnieNaPret() Call OdswiezWalek()
ElseIf mode = TrybPracy.StworzGwint Then mojStopien = KliknietyStopien(x1) mojStopien.ZmienPowierzchnieNaGwint() Call OdswiezWalek()
End If End Sub
Private Sub NowyWałekToolStripMenuItem_Click(sender As Object, e As EventArgs) _ Handles NowyWałekToolStripMenuItem.Click mode = TrybPracy.NicNieRob
x_pocz = X_osi
Kolekcja_stopni_walu.Clear()
objRys.Clear(SystemColors.Control) Call RysujOsie()
End Sub
Private Sub StopnieBezFazyToolStripMenuItem_Click(sender As Object, e As EventArgs) _ Handles StopnieBezFazyToolStripMenuItem.Click mode = TrybPracy.NowyStopien
faza = 0 End Sub
Private Sub NicNieRóbToolStripMenuItem_Click(sender As Object, e As EventArgs) _ Handles NicNieRóbToolStripMenuItem.Click mode = TrybPracy.NicNieRob
End Sub
Private Sub SkasujToolStripMenuItem_Click(sender As Object, e As EventArgs) _
Handles SkasujToolStripMenuItem.Click objRys.Clear(SystemColors.Control)
RysujOsie(Me.CreateGraphics) End Sub
Private Sub PokażToolStripMenuItem_Click(sender As Object, e As EventArgs) _
Handles PokażToolStripMenuItem.Click Call Narysuj()
End Sub
Private Sub Narysuj()
Dim wsk_kolekcji As Stopien_walu x_pocz = X_osi
For Each wsk_kolekcji In Kolekcja_stopni_walu ''objRys.DrawRectangle(objPioroWal, _
''x_pocz, Y_osi - wsk_kolekcji.Srednica_stopnia / 2, _
''wsk_kolekcji.Dlugosc_stopnia, wsk_kolekcji.Srednica_stopnia) wsk_kolekcji.Rysuj(objRys, x_pocz, Y_osi)
x_pocz = x_pocz + wsk_kolekcji.Dlugosc_stopnia Next
End Sub
Private Sub StopnieZFaząZLewejStronyToolStripMenuItem_Click(sender As Object, _ e As EventArgs) Handles StopnieZFaząZLewejStronyToolStripMenuItem.Click mode = TrybPracy.NowyStopien
faza = 8 End Sub
Private Sub StopnieZFaząZPrawejStronyToolStripMenuItem_Click(sender As Object, _ e As EventArgs) Handles StopnieZFaząZPrawejStronyToolStripMenuItem.Click mode = TrybPracy.NowyStopien
faza = -8 End Sub
Private Sub UsuńStopieńToolStripMenuItem_Click(sender As Object, e As EventArgs) _ Handles UsuńStopieńToolStripMenuItem.Click mode = TrybPracy.UsunStopien
End Sub
Private Sub OdswiezWalek()
objRys.Clear(SystemColors.Control) Call Narysuj()
Call RysujOsie() 'Ewentualnie, jeśli system "się leni" :-) End Sub
Private Function KliknietyStopien(ByVal x As Single) As Stopien_walu Dim x_temp As Single = X_osi
Dim i As Integer = 0
Do Until x > x_temp And x <= _
x_temp + Kolekcja_stopni_walu.Item(i).Dlugosc_stopnia x_temp = x_temp + Kolekcja_stopni_walu.Item(i).Dlugosc_stopnia
i = i + 1 Loop
Return Kolekcja_stopni_walu.Item(i) End Function
Private Sub GwintToolStripMenuItem_Click(sender As Object, e As EventArgs) _ Handles GwintToolStripMenuItem.Click mode = TrybPracy.StworzGwint
End Sub
Private Sub PrętToolStripMenuItem_Click(sender As Object, e As EventArgs) _
Handles PrętToolStripMenuItem.Click mode = TrybPracy.StworzPret
End Sub
Private Sub UsuńModyfikacjęToolStripMenuItem_Click(sender As Object, e As EventArgs) _ Handles UsuńModyfikacjęToolStripMenuItem.Click mode = TrybPracy.UsunModyfikacje
End Sub End Class
-- * --
Diagram UML
1Rysunek 1. Diagram klas
1 Uwaga, w wersji Visual Studio 2017 Community – brak możliwości uzyskania Diagramu klas (uwaga z dn.2017.12.03)