Janusz Górczyński. Wprowadzenie do programowania obiektowego w VB.NET
|
|
- Sylwia Krupa
- 9 lat temu
- Przeglądów:
Transkrypt
1 Janusz Górczyński Wprowadzenie do programowania obiektowego w VB.NET WSZiM w Sochaczewie, 2011
2 Spis treści 1 KLASY I ICH WYKORZYSTANIE WPROWADZENIE DO KLAS Definiowanie klasy Utworzenie instancji klasy ZDARZENIA GENEROWANIE I ODBIERANIE PRZECIĄŻENIE METODY DZIEDZICZENIE INTERFEJS KLASY POLIMORFIZM Polimorfizm wg dziedziczenia Polimorfizm wg interfejsu DIAGRAM KLAS UML PRZYKŁADY KLAS CKWOTASLOWNIE CVALIDACJA KLASA CDATAGRIDPRINT UTWORZENIE WŁASNEJ BIBLIOTEKI DLL KOMPILACJA KLASY CVALIDACJA TESTOWANIE BIBLIOTEKI CVALIDACJA.DLL
3 1 Klasy i ich wykorzystanie Pojęcie klasy jest ściśle związane z obiektowo zorientowanym programowaniem (OOP Object Oriented Programming). Klasy, jako abstrakcyjne wzorce obiektów są podstawą praktycznie wszystkich współczesnych języków programowania wysokiego poziomu, a więc i VB.NET. 1.1 Wprowadzenie do klas Klasa w języku programowania oznacza abstrakcyjny model użyty do zdefiniowania nowego typu danych. Zawiera połączenie zarówno danych jak i kodu operującego na tych danych. Jako przykład można tu podać klasę String w przestrzeni nazw System. Klasa ta zawiera tablicę znaków jako dane oraz kod, który obsługuje różne działania, jakie mogą być wykonane na tych danych. Kod tego typu tworzy tzw. metody (ang. Methods), a ich przykładem mogą być np. Substring() czy Trim(). Klasa może zawierać także kod opisujący właściwości obiektu (ang. Property), przykładem może być np. właściwość Length. VB.NET oferuje uproszczoną strukturę obiektową zapewniając jednocześnie obsługę czterech podstawowych mechanizmów programowania obiektowego. Są to: Abstrakcja czyli możliwość tworzenia kodu w postaci czarnej skrzynki, czyli abstrakcyjnej reprezentacji danej koncepcji w programie; Hermetyzacja jest to mechanizm pozwalający na oddzielenie interfejsu (czyli sposobu dostępu do metody) od implementacji (sposobu jej zaprogramowania). Pozwala na ukrycie szczegółów implementacji metod wewnątrz klasy; Dziedziczenie możliwość tworzenia klas potomnych, które przejmują z klasy bazowej jej interfejs, właściwości, metody i zmienne prywatne; Polimorfizm jest to możliwość tworzenia funkcji, która operuje na obiektach więcej niż jednej klasy Definiowanie klasy W VB.NET klasa definiowana jest z użyciem słów kluczowych Class i End Class, miedzy nimi zawarte są definicje danych i kod tworzący procedury klasy (metody, właściwości, prywatne procedury i funkcje klasy). Dane wykorzystywane w klasie mogą być dowolnego typu, ich deklaracja powinna być poprzedzona słowem kluczowym Private, co zapewnia ich skuteczną hermetyzację. Dane te 3
4 są wtedy prywatnymi danymi klasy i nie są dostępne bezpośrednio spoza kodu klasy. W praktyce programowania dane te noszą nazwę pól lub zmiennych prywatnych klasy. W prezentowanych aplikacjach przyjęto zasadę, że nazwa zmiennych prywatnych klasy będzie zawsze zaczynała się od małej litery m. Kod metod i właściwości poprzedzony jest słowem kluczowym (specyfikatorem dostępu) Public, ponieważ chcemy, aby procedury te były dostępne spoza kodu klasy. Wyjątkiem są tu pomocnicze procedury i funkcje klasy, które będą wykorzystywane jedynie w tej klasie, wtedy poprzedzamy je słowem Private. Innym wyjątkiem jest tworzenie klasy bazowej (takiej, która będzie wykorzystana do utworzenia klas potomnych), dla zapewnienia dziedziczenia jej procedur poprzedzamy je słowem kluczowym Protected. Zadaniem procedur typu Property jest ustawianie lub zwracanie wartości zmiennej prywatnej. Procedura Propery może być poprzedzona słowami kluczowymi ReadOnly lub WriteOnly, co prowadzi do procedury pozwalającej odpowiednio jedynie na odczyt lub zapis danej właściwości. Specjalną rolę w kodzie klasy spełniają procedury publiczne o wspólnej nazwie New, noszą one nazwę konstruktorów, a ich przeznaczeniem jest zainicjowanie klasy w momencie tworzenia jej instancji (obiektu). Przykład definicji klasy pokazany jest niżej. W klasie CStudent zadeklarowano trzy zmienne prywatne, dwa konstruktory (procedury inicjalizujące), jedną metodę o nazwie NazwiskoImie oraz trzy procedury typu Property pozwalającą na ustawienie lub zwrócenie nazwiska studenta, jego imię oraz numer albumu. Public Class CStudent Private mnralbumu as Integer Private mnazwisko as String Private mimie as String Public Sub New() End Sub Public Sub New(ByVal naz As String, _ ByVal imie as String, ByVal idr as Integer) mnazwisko = naz mimie = imie mnralbumu = idr End Sub 4
5 Public Function NazwiskoImie As String() Return mnazwisko & & mimie & nr albumu & _ mnralbumu.tostring End Function Public Property Nazwisko As String() Get Return mnazwisko End Get Set (ByVal value as String) mnazwisko = value End Set End Property Public Property Imie As String() Get Return mimie End Get Set (ByVal value as String) mimie = value End Set End Property Public Property NumerAlbumu As Integer Get Return mnralbumu End Get Set (ByVal value as Integer) mnralbumu = value End Set End Property dalsze instrukcje tej klasy End Class Utworzenie instancji klasy Utworzenie instancji (egzemplarza) klasy wymaga użycia słowa kluczowego New. Kilka możliwych sposobów utworzenia instancji klasy CStudent pokazanych jest niżej. Pierwszy z nich zawiera najpierw deklarację utworzenia obiektu klasy, a w drugim wierszu instrukcję jego utworzenia. Dim student As CStudent Student = New CStudent 5
6 Obie te instrukcje można zawrzeć w jednej, tak jak to pokazano niżej. Dim student As New CStudent() Powyższa instrukcja korzysta z domyślnego konstruktora (bezparametrowego). Jeżeli chcielibyśmy przypisać obiektowi student takie właściwości jak nazwisko, imie czy numer albumu, to korzystamy z pokazanych niżej instrukcji przypisania. student.nazwisko = Kowalski student.imie = Jan student.numeralbumu = 1345 W przypadku, gdyby w klasie CStudent był utworzony konstruktor z trzema parametrami (nazwisko, imie oraz numer albumu), to instrukcja (jednowierszowa) utworzenia instancji tej klasy mogłaby mieć postać jak niżej. Dim student As New CStudent( Kowalski, Jan, 1345) Dwuwierszowa instrukcja utworzenia instancji klasy jest niezbędna wtedy, gdy chcemy wykorzystać jeden ze zdefiniowanych interfejsów. Prześledzimy taką sytuację na przykładzie klasy CStudent z poprzedniego podrozdziału. W kodzie przykładowego formularza spróbujemy teraz utworzyć dwa obiekty w oparciu o klasę CStudnet, pierwszy z wykorzystaniem interfejsu IDaneStudenta, a drugi bez korzystania ze zdefiniowanego interfejsu. Deklaracja i utworzenie instancji klasy CStudnet w oparciu o jeden z jego zdefiniowanych interfejsów wymaga dwóch wierszy instrukcji. W pierwszym wierszu deklarujemy utworzenie obiektu w oparciu o wybrany interfejs klasy, w drugim tworzymy nową instancję z wykorzystaniem jednego z konstruktorów. W pokazanej niżej sytuacji tak zadeklarowano i utworzono obiek w. Dzieki deklaracji z wykorzystaniem interfejsu obiekt w udostępnia tylko te metody, które są udostępnione przez interfejs, w naszym przypadku będą to metody FullName oraz ShortName. A co by było, gdybyśmy utworzyli instancję klasy w oparciu o domyślny interfejs? Sytuacja taka pokazana jest poniżej, został zadeklarowany i utworzony obiekt z w oparciu o pierwszy konstruktor. 6
7 Efektem takiej deklaracji (bez użycia zdefiniowanego interfejsu) jest udostępnienie wszystkich publicznych metod klasy, chociaż tylko trzy z nich mają w tym wypadku sens (FullName, ShortName i Komunikat). W rezultacie mamy szansę popełnienia dość niebezpiecznej pomyłki próbując odwołać się do metod, które przy tym konstruktorze nie są określone (Oceny, Rejestr, SredniaOcen). 1.2 Zdarzenia generowanie i odbieranie Klasa może generować zdarzenia, które następnie mogą być odebrane przez program tworzący instancję (egzemplarz) klasy. Zdarzenie deklarujemy w klasie za pomocą słów Public Event Nazwa_zdarzenia(opcjonalnie lista argumentów). Zdarzenie jest generowane za pomocą słowa kluczowego RaiseEvent nazwa_zdarzenia(opcjonalnie argumenty). Poniżej przykład klasy CStudent z projektu ZdarzeniaOrazPrzeciazanieMetod, zdefiniowano w nim zdarzenie o nazwie ZleDane z dwoma argumentami. Zdarzenie to będzie generowane w sytuacji, gdy dane przekazane do metody klasy będą nieodpowiednie. Public Class CStudent Private mid As Integer Private mnazwisko As String Private mimie As String Private mdataurodzenia As Date Private mkomunikat As String = "" Public Event ZleDane(ByVal komunikat As String, _ ByVal obiekt As Integer) 7
8 Public Sub KompletDanych(ByVal pnazwisko As String, _ ByVal pimie As String, ByVal pid As Integer, _ ByVal pdatau As Date) If pnazwisko.length < 5 Then ' jeżeli długość nazwiska będzie mniejsza niż 5 znaków, ' to zostanie wywołane zdarzenie RaiseEvent ZleDane("Nazwisko zbyt krótkie (min. 5 znaków)", 1) Exit Sub ElseIf pnazwisko.length > 50 Then ' jeżeli długość nazwiska będzie większa niż 50 znaków, to ' zostanie wywołane zdarzenie RaiseEvent ZleDane("Nazwisko zbyt długie (max. 5 znaków)", 1) Exit Sub Else mnazwisko = UCase(mNazwisko.Substring(0, 1)) & _ LCase(mNazwisko.Substring(1, mnazwisko.length - 1)) If pimie.length < 3 Then RaiseEvent ZleDane("Imię zbyt krótkie (min. 3 znaki)") Exit Sub ElseIf pimie.length > 25 Then RaiseEvent ZleDane("Imię zbyt długie (max. 25 znaków)") Exit Sub Else mimie = UCase(mImie.Substring(0, 1)) & _ LCase(mImie.Substring(1, mimie.length - 1)) If pid < 2000 OrElse pid > 5000 Then RaiseEvent ZleDane( _ "Nunmer albumu musi być z przedziału ", 2) Exit Sub Else mid = pid If pdatau < CDate(" ") OrElse _ pdatau > CDate(" ") Then RaiseEvent ZleDane("Data urodzenia musi być z zakresu " & _ "' '", 3) Exit Sub Else mdataurodzenia = pdatau End Sub 8
9 Public Sub New(ByVal p1 As Integer, ByVal p2 As Integer, _ ByVal p3 As Integer, ByVal p4 As Integer) mkomunikat = (p1 + p2 + p3 + p4).tostring End Sub Public Sub New(ByVal p1 As String, ByVal p2 As String) mnazwisko = p1 mimie = p2 End Sub Public Function Komunikat() As String Return mkomunikat End Function ' definicja właściwości Public Property Nazwisko() As String Get Return mnazwisko End Get Set(ByVal value As String) If value.length < 5 Then RaiseEvent ZleDane("Nazwisko zbyt krótkie", 1) Else mnazwisko = value End Set End Property Public Property Imie() As String Get Return mimie End Get Set(ByVal value As String) If value.length < 3 Then RaiseEvent ZleDane("Imię zbyt krótkie", 2) Else mimie = value End Set End Property End Class W projekcie ZdarzeniaOrazPrzeciazenieMetod utworzono formularz frmtest zawierający cztery pola tekstowe o nazwach odpowiednio txtnazwisko, txtimie, txtnralbumu oraz txtdatau, odpowiadające im etykiety ze stosownymi tekstami, formant 9
10 listy o nazwie lststudenci oraz cztery przyciski o nazwach btndodaj, btnclear, btnsumatekstow oraz btnsumaliczb. Projekt tego formularza pokazany jest niżej. W kodzie klasy tego formularza wpisano instrukcje niezbędne do obsługi jego formantów. Będziemy korzystać z klasy CStudent tworząc egzemplarz tej klasy, przy czym musimy tak to zrobić, aby mieć możliwość odebrania zdarzenia wygenerowanego w tej klasie. Możemy to zrobić dwojako, deklarując egzemplarz tej klasy z użyciem słowa kluczowego WithEvents lub bez użycia tego słowa. W pokazanym niżej kodzie wykorzystano to pierwsze rozwiązanie. Public Class frmtest Dim bflaga As Boolean ' dekalracja instancji klasy CStudent zależy od tego, ' czy do obsługi zdarzenia użyjemy AddHandler czy nie Private WithEvents w As CStudent ' Private w As CStudent Private Sub btndodaj_click(byval sender As System.Object, _ ByVal e As System.EventArgs) Handles btndodaj.click ' zmienna logiczna otrzymuje wartość True, wykorzystamy ją ' do podjęcia decyzji, czy dodać element do listy 10
11 bflaga = True ' utworzenie instancji klasy w = New CStudent ' AddHandler w.zledane, AddressOf ObslugaZdarzenia w.kompletdanych(me.txtnazwisko.text, Me.txtImie.Text, _ CType(Me.txtNrAlbumu.Text, Integer), _ CType(Me.txtDataU.Text, Date)) ' dodanie do formantu ListBox elementu typu CStudent, ale po ' sprawdzeniu, czy obiekt w został poprawnie zbudowany If bflaga Then Me.lstStudenci.Items.Add(w) End if End Sub Private Sub txtnralbumu_keypress(byval sender As Object, _ ByVal e As System.Windows.Forms.KeyPressEventArgs) _ Handles txtnralbumu.keypress ' obsługa zdarzenia KeyPress - chodzi o to, aby nie przyjąć ' innego znaku niż cyfra If e.keychar < "0" Or e.keychar > "9" Then Beep() e.handled = True ' przypisanie właściwości Handled wartości ' True oznacza odrzucenie wprowadzonego znaku End Sub ' procedura obsługująca zdarzenie ZleDane zgłoszone przez instancję ' klasy CStudent ' jeżeli obsługujemy zdarzenie z użyciem deklaracji WithEvents to ' fragment Handles w.zledane jest konieczny ' a jeżeli z użyciem AddHandler, to Handles w.zledane musimy ' zamarkować lub usunąć Private Sub ObslugaZdarzenia(ByVal tekst As String, _ ByVal co As Integer) Handles w.zledane bflaga = False MsgBox(tekst, MsgBoxStyle.Critical, "Obsługa zdarzenia") Select Case co ' zależenie od wartości zmiennej co komponowany ' jest komunikat Case 1 Me.txtNazwisko.Focus() Case 2 Me.txtImie.Focus() Case 3 Me.txtNrAlbumu.Focus() Case 4 11
12 Me.txtDataU.Focus() End Select End Sub Private Sub lststudenci_selectedindexchanged(byval sender As _ Object, ByVal e As System.EventArgs) _ Handles lststudenci.selectedindexchanged Dim z As CStudent = CType(Me.lstStudenci.SelectedItem, CStudent) MsgBox("Student " & z.nazwiskoimienralbumu, _ MsgBoxStyle.Information, "JG") End Sub Private Sub btnclear_click(byval sender As System.Object, _ ByVal e As System.EventArgs) Handles btnclear.click Me.lstStudenci.Items.Clear() End Sub Private Sub btnsumatekstow_click(byval sender As System.Object, _ ByVal e As System.EventArgs) Handles btnsumatekstow.click Dim w As New CStudent MsgBox("Suma tekstów to: " & w.dodaj(me.txtnazwisko.text, _ Me.txtImie.Text), MsgBoxStyle.Information, "Przeciążenie") End Sub Private Sub btnsumaliczb_click(byval sender As System.Object, _ ByVal e As System.EventArgs) Handles btnsumaliczb.click If IsNumeric(Me.txtNazwisko.Text) AndAlso _ IsNumeric(Me.txtImie.Text) Then Dim w As New CStudent MsgBox("Suma liczb = " & w.dodaj(cint(me.txtnazwisko.text), _ CInt(Me.txtImie.Text)).ToString, MsgBoxStyle.Information, _ "Przeciążenie") Else MsgBox("Dane nie reprezentują liczb", MsgBoxStyle.Critical, _ "Błąd przygotowania danych") End Sub End Class 12
13 1.3 Przeciążenie metody Pod tym pojęciem rozumiemy utworzenie więcej niż jednej metody o tej samej nazwie, ale różnym zestawie argumentów co do ich liczby i typu danych. W poprzednim podrozdziale w kodzie klasy CStudent utworzono dwa konstruktory różniące się liczbą argumentów (z założenia mają tę samą nazwę New). Przeciążanie metod pozwala nam na doprowadzenie do sytuacji, w której interfejs klasy jest zwarty (nie zawiera kilku metod realizujących podobne zadania). Inna korzyść, to logiczna możliwość wywołania tej samej metody niezależnie od rodzaju i liczby danych, które chcemy przekazać do metody. Poniżej dwie metody o tej samej nazwie, słowo kluczowe Overloads jest niezbędne do poprawnego przeciążenia metody (wyjątkiem jest konstruktor, który nie potrzebuje tego słowa kluczowego). Public Overloads Function Dodaj(ByVal arg1 As Integer, _ ByVal arg2 As Integer) As Integer Return arg1 + arg2 End Function Public Overloads Function Dodaj(ByVal arg1 As String, _ ByVal arg2 As String) As String Return arg1 & " " & arg2 End Function Metody są poprawnie przeciążone, jeżeli różnica w zestawie argumentów dotyczy innych argumentów niż opcjonalne. 13
14 1.4 Dziedziczenie Pod tym pojęciem rozumiemy możliwość budowania nowej klasy na bazie (podstawie) istniejącej klasy. Klasę, na podstawie której tworzymy nową klasę nazywamy klasą bazową, a powstałą w ten sposób nową klasę klasą potomną. Klasa potomna ma co najmniej te same metody i właściwości, co klasa bazowa. Ta cecha pozwala nam (między innymi) na przekazywanie do procedury czy funkcji instancji klasy potomnej, jeżeli jej argument został określony jako klasa bazowa. Prześledzimy problem dziedziczenia na przykładzie klasy CForStorageSub, która zawiera metody pozwalające na uruchamianie procedur przechowywanych na serwerze MS SQL Server. Poniżej fragment kodu klasy CForStorageSub, prezentuje on zaimportowanie dwóch przestrzeni nazw, definicję wyliczania jgtyp oraz metodę (funkcję) DajRekordset. Zadaniem funkcji DajRekordset jest wykonanie procedury przechowywanej zwracającej odpowiedni rekordset. Funkcja zwraca obiekt typu DataTable, a do jego wypełnienia danymi wykorzystuje obiekt DataReader i metodę ExecuteReader. Imports System.Data Imports System.Data.SqlClient Public Class CForStorageSub ' wyliczenie na potrzeby określania typu parametrów Protected Enum jgtyp As Integer jginteger = 1 jgchar = 2 jgmoney = 3 jgdata = 4 jgstring = 5 jgbit = 6 jgsingle = 7 End Enum Protected Function DajRekordset(ByVal conn As SqlConnection, _ ByVal sp_nazwa As String, _ ByVal ParamArray Par() As Object) As DataTable Dim cmd As SqlCommand, i As Integer, ip As Integer cmd = New SqlCommand ip = fprzygotujcmd(cmd, sp_nazwa, False, Par) cmd.connection = conn Dim dr As SqlDataReader, dt As New DataTable 14
15 dr = cmd.executereader dt.load(dr) cmd = Nothing DajRekordset = dt End Function ' dalsze metody publiczne i prywatne klasy End Class Klasa CForStorageSub będzie podstawą (bazą) do konstrukcji szczegółowych klas potomnych wyspecjalizowanych do rozwiązywania problemów komunikacji z bazą danych dla konkretnych formularzy czy raportów. Poniżej przykład takiej klasy wykorzystywanej w raportach. Słowo kluczowe MyBase daje dostęp do publicznych metod klasy bazowej, w tym przypadku do metody DajRekordset. Zapis MyBase.DajRekordset jest równoważny z zapisem DajRekordset, a użycie słowa kluczowego MyBase zwalnia jedynie z pamiętania nazw metod klasy bazowej. Imports System.Data Imports System.Data.SqlClient Public Class CRaporty Inherits CForStorageSub ' dziedziczenie po klasie bazowej Private mtable As DataTable Private mkomunikat As String = "" Public Sub New(ByVal StrConn As String, ByVal idr As Integer, _ ByVal idw As Integer, ByVal ktoryraport As Integer) ' konstruktor dostarcza źródło danych dla raportu ' określonego przez zmienną ktoryraport Dim conn As New SqlConnection(StrConn) Try conn.open() Select Case ktoryraport Case 1 ' zakupy wartościowo wg lat i wydawnictw mtable = MyBase.DajRekordset(conn, _ "p_zakupylatawydawnictwa", _ "@idr", idr, jgtyp.jginteger, 0, _ "@idw", idw, jgtyp.jginteger, 0) Case 2 ' zakupy ilościowo i wartościowo wg 'wydawnictw w latach, także wg kategorii mtable = MyBase.DajRekordset(conn, _ "p_zbiorczezakupy", _ 15
16 idr, jgtyp.jginteger, 0) Case 3 ' rezerwa na przyszłość End Select Catch ex As Exception mkomunikat = "Błąd pobrania danych" Finally conn.close() conn = Nothing End Try End Sub ReadOnly Property DajTabele() As DataTable Get Return mtable End Get End Property ReadOnly Property Komunikat() As String Get Return mkomunikat End Get End Property End Class W książkach, których jestem autorem lub współautorem przedstawiono wiele klas potomnych klasy CForStorageSub związanych z obsługą formularzy czy raportów. W większości z tych klas stosowne były przeciążone konstruktory oraz definiowane interfejsy klas różnicujące dostęp do ich metod publicznych. Prześledzenie ich kodu jak i sposobu wykorzystania klas w kodzie procedur obsługujących formularze powinno pozwolić na poznanie możliwości i zalet klas w programowaniu. 16
17 1.5 Interfejs klasy W wielu przypadkach w klasie definiujemy więcej niż jeden konstruktor, przy czym z każdym z nich mogą być związane unikalne właściwości. W takich sytuacjach można w klasie zadeklarować interfejsy klasy, które będą ograniczać dostęp do wybranej części właściwości. Dla prześledzenia tego problemu skupimy się na wspomnianej wcześniej klasie CStudent, w której utworzymy dwa konstruktory i dwa interfejsy klasy. Imports System.Data Imports System.Data.SqlClient Public Interface IDaneStudenta Function FullName() As String Function ShortName() As String End Interface Public Interface IDaneRejestrowe Function Rejestr() As DataTable Function Oceny() As DataTable Function SredniaOcen() As Decimal End Interface Public Class CStudent Implements IDaneStudenta Implements IDaneRejestrowe ' deklaracja zmiennych prywatnych klasy Private mnazwisko As String Private mimie As String Private mnumeralbumu As String Private msredniaocen As Decimal Private mtablerejestr As DataTable Private mtableoceny As DataTable Private mkomunikat As String = "" Public Function FullName() As String Implements _ IDaneStudenta.FullName Return mnazwisko & " " & mimie & " nr alb. " & _ mnumeralbumu.tostring End Function Public Function ShortName() As String Implements _ IDaneStudenta.ShortName Return mimie.substring(0, 1) & ". " & mnazwisko End Function 17
18 Public Function Rejestr() As System.Data.DataTable Implements _ IDaneRejestrowe.Rejestr Return mtablerejestr End Function Public Function Oceny() As System.Data.DataTable Implements _ IDaneRejestrowe.Oceny Return mtableoceny End Function Public Function SredniaOcen() As Decimal Implements _ IDaneRejestrowe.SredniaOcen Return msredniaocen End Function Public Sub New(ByVal anazwisko As String, _ ByVal aimie As String, ByVal anumeralbumu As Integer) mnazwisko = anazwisko mimie = aimie mnumeralbumu = anumeralbumu End Sub Public Sub New(ByVal astrconn As String, _ ByVal anumeralbumu As Integer) ' utworzenie obiektu SqlConnection w oparciu o przekazany ' łańcuch połączenia Dim conn As New SqlConnection(aStrConn) Try 'otwarcie połączenia do bazy danych conn.open() ' przypisanie do zmiennej mtablerejestr rekordsetu ' zwróconego przez odpowiednią procedurę przechowywaną ' po przekazaniu do niej numeru albumu mtablerejestr = DajRekordSet(...) ' przypisanie do zmiennej mtableoceny rekordsetu ' zwróconego przez odpowiednią procedurę przechowywaną ' po przekazaniu do niej numeru albumu mtableoceny = DajRekordSet(...) ' pobranie z bazy danych średniej ocen dla danego ' studenta msrednia = DajWartosc(...) Catch ex As Exception mkomunikat = "Błąd pobrania danych" Finally conn.close() 18
19 conn = Nothing End Try End Sub ' procedura Property zwraca wartość zmiennej mkomunikat ReadOnly Property Komunikat() As String Get Return mkomunikat End Get End Property End Class Warto zwrócić uwagę, że zmienna prywatna mkomunikat, która jest udostępniana przez procedurę typu Property o nazwie Komunikat nie będzie dostępna w żadnym zdefiniowanym interfejsie klasy (ale będzie dostępna w domyślnym interfejsie). Gdybyśmy chcieli udostępnić tę zmienną w interfejsach, to konieczne byłoby zadeklarowanie oraz implementacja odpowiednich funkcji w tych interfejsach. 1.6 Polimorfizm Polimorfizm to jedna z ważniejszych cech OOP, jej sens polega na tym, że możemy mieć wiele klas implementujących ten sam interfejs. Możliwa jest realizacja polimorfizmu dwoma drogami: poprzez dziedziczenie oraz poprzez interfejs. Rozważmy taką sytuację, w której chcemy mieć klasy realizujące obliczenie pozycji Do wypłaty na podstawie kwoty wynagrodzenia brutto w kosztach firmy dla dwóch kategorii pracowników: zatrudnionych na umowę o pracę oraz na zlecenie, Projekt TestPolimorfizmu zawiera pełne rozwiązanie tego problemu. W skład tego projektu wchodzi (między innymi) pokazany niżej formularz frmpolimorfizm. 19
20 Na jego powierzchni umieszczono sześć formantów typu TextBox, są to formanty o nazwach i przeznaczeniu: txtbruttopraca tu wpiszemy kwotę wynagrodzenia brutto przy umowie o pracę; txtbruttozlecenie tu wpiszemy kwotę wynagrodznia brutto przy zleceniu; txtdowyplatypd tu zostanie zwrócona wyliczona kwota wynagrodzenia do wypłaty w przypadku umowy o pracę z wykorzystaniem dziedziczenia; txtdowyplatyzd tu zostanie zwrócona wyliczona kwota wynagrodzenia do wypłaty w przypadku umowy zlecenia z wykorzystaniem dziedziczenia; txtdowyplatypi tu zostanie zwrócona wyliczona kwota wynagrodzenia do wypłaty w przypadku umowy o pracę z wykorzystaniem interfejsu; txtdowyplatyzi tu zostanie zwrócona wyliczona kwota wynagrodzenia do wypłaty w przypadku umowy zlecenia z wykorzystaniem interfejsu; Dwa przyciski poleceń uruchamiają procedury wyliczające kwoty wynagrodzenia do wypłaty z wykorzystaniem odpowiedniej formy polimorfizmu: btnwgdziedziczenia btnwginterfejsu Formularz uzupełniają jeszcze etykiety opisujące przeznaczenie poszczególnych pól tekstowych Polimorfizm wg dziedziczenia Utworzymy klasę CPodatekPodstawowy, poza zmiennymi i stałymi zdefiniowano w niej publiczną funkcję DoWyplaty, jej zadaniem jest wyliczenie pozycji do wypłaty w przypadku zatrudnienia na podstawie umowy o pracę. W definicji tej metody użyto słowa kluczowego Overridable po to, aby w klasie potomnej mieć możliwość innego zaimplementowania tej samej metody. Imports System.Math Public Class CPodatekPodstawowy Protected mbruttof As Decimal Protected mbruttop As Decimal Protected mskladkizus As Decimal Protected mskladkiuz As Decimal Protected mpodstawaskladki As Decimal 20
21 Protected mkosztuzysku As Decimal Protected mpodstawapodatku As Decimal Protected mpodatekus As Decimal Protected Const KosztFirmy As Double = 0.15 Protected Const SkladkiZUS As Double = Protected Const SkladkiUZ As Double = 0.09 ' deklaracja publicznej funkcji DoWyplaty, jej zadaniem jest ' ustalenie kwoty do wypłaty. Jako argument dostaje kwotę wypłaty w ' kosztach firmy, pozycja do wypłaty obliczana jest tak, jak dla ' pracownika zatrudnionego na umowę o pracę ' Specyfikator Overridable pozwala na inną definicję tej funkcji w ' klasie potomnej Public Overridable Function DoWyplaty(ByVal kwota As Decimal) As _ Decimal mbruttop = Round(kwota * (1 - KosztFirmy), 2) mskladkizus = Round(mBruttoP * SkladkiZUS, 2) mpodstawaskladki = mbruttop - mskladkizus mskladkiuz = Round(mPodstawaSkladki * SkladkiUZ, 2) mkosztuzysku = Round(mPodstawaSkladki * 0.5, 2) mpodstawapodatku = mpodstawaskladki - mkosztuzysku mpodatekus = Round(mPodstawaPodatku * _ mpodstawaskladki * , 0) Return mbruttop - mskladkizus - mskladkiuz - mpodatekus End Function End Class Tworzymy teraz klasę potomną na bazie klasy CPodatekPodstawowy, będziemy ją wykorzystywać przy obliczaniu pozycji do wypłaty w przypadku zatrudnienia na zlecenie. Public Class CPodatekZlecenie ' klasa dziedziczy po klasie CPodatekPodstawowy, co oznacza, że ma 'co najmniej wszystkie właściwości i metody klasy bazowej Inherits CPodatekPodstawowy ' nadpisanie funkcji DoWyplaty, słowo Overrides jest oznaczeniem ' Nadpisania. Inaczej mówiąc chodzi o inną implementację tej funkcji ' niż w klasie bazowej. Warunkiem sine qua non nadpisania jest ' oznaczenie takiej funkcji w klasie bazowej słowem Overridable Public Overrides Function DoWyplaty(ByVal kwota As Decimal) As _ Decimal mbruttop = kwota mskladkizus = 0 mpodstawaskladki = mbruttop - mskladkizus mskladkiuz = 0 mkosztuzysku = Round(mPodstawaSkladki * 0.5, 2) 21
22 mpodstawapodatku = mpodstawaskladki - mkosztuzysku mpodatekus = Round(mPodstawaPodatku * _ mpodstawaskladki * , 0) Return mbruttop - mskladkizus - mskladkiuz - mpodatekus End Function End Class W kodzie formularza frmpolimorfizm musimy utworzyć dwie procedury realizujące obliczenie kwoty do wypłaty wg dziedziczenia. Pomocnicza procedura ObliczWyplate otrzymuje jako pierwszy argument egzemplarz klasy CPodatekPodstawowy, ale może też otrzymać egzemplarz klasy CPodatekZlecenie. Private Sub ObliczWyplate(ByVal Item As CPodatekPodstawowy, _ ByVal kwota As Decimal, ByVal txttext As TextBox) txttext.text = Format(Item.DoWyplaty(kwota), "# ##0.00 zł") End Sub Kolejna procedura wykonywana jest w reakcji na klik przycisku btnwgdziedziczenia. Private Sub btnwgdziedziczenia_click(byval sender As System.Object, _ ByVal e As System.EventArgs) Handles btnwgdziedziczenia.click If IsNumeric(Me.txtBruttoPraca.Text) AndAlso _ IsNumeric(Me.txtBruttoZlecenie.Text) Then Dim Item1 As New CPodatekPodstawowy Dim item2 As New CPodatekZlecenie ObliczWyplate(Item1, CDec(Me.txtBruttoPraca.Text), _ Me.txtDoWyplatyPd) ObliczWyplate(item2, CDec(Me.txtBruttoZlecenie.Text), _ Me.txtDoWyplatyZd) Else MsgBox("Co najmniej jedna z pozycji 'brutto' jest źle podana", _ MsgBoxStyle.Critical, _ "Testowanie poliformizu wg dziedziczenia") End Sub Efekt działania pokazany jest niżej. 22
23 1.6.2 Polimorfizm wg interfejsu Przy tej metodzie musimy utworzyć w ogólnym module interfejs, który inaczej zaimplementujemy w klasach realizujących obliczenia wg umowy o pracę i wg zlecenia. W tym projekcie interfejs ten został utworzony w pliku typu Module. Module ModulKlasJG Public Interface IObliczWyplate Function ObliczDoWyplaty(ByVal KwotaBrutto As Decimal) As Decimal End Interface End Module Powyższy kod zawiera definicję interfejsu IObliczWyplate zawierającego deklarację funkcji ObliczWyplate. Tworzymy teraz dwie klasy, każda z nich będzie inaczej implementować podany wyżej interfejs. Public Class CPraca Implements IObliczWyplate Private mbruttof, mbruttop As Decimal Private mskladkizus, mskladkiuz As Decimal Private mpodstawaskladki, mkosztuzysku As Decimal Private mpodstawapodatku, mpodatekus As Decimal Private Const KosztFirmy As Double = 0.15 Private Const SkladkiZUS As Double = Private Const SkladkiUZ As Double = 0.09 Public Function ObliczDoWyplaty(ByVal KwotaBrutto As Decimal) As _ Decimal Implements ModulKlasJG.IObliczWyplate.ObliczDoWyplaty mbruttop = Round(KwotaBrutto * (1 - KosztFirmy), 2) mskladkizus = Round(mBruttoP * SkladkiZUS, 2) mpodstawaskladki = mbruttop - mskladkizus 23
24 mskladkiuz = Round(mPodstawaSkladki * SkladkiUZ, 2) mkosztuzysku = Round(mPodstawaSkladki * 0.5, 2) mpodstawapodatku = mpodstawaskladki - mkosztuzysku mpodatekus = Round(mPodstawaPodatku * _ mpodstawaskladki * , 0) Return mbruttop - mskladkizus - mskladkiuz - mpodatekus End Function End Class Public Class CZlecenie Implements IObliczWyplate Private mbruttof, mbruttop As Decimal Private mskladkizus, mskladkiuz As Decimal Private mpodstawaskladki, mkosztuzysku As Decimal Private mpodstawapodatku, mpodatekus As Decimal Private Const KosztFirmy As Double = 0.15 Private Const SkladkiZUS As Double = Private Const SkladkiUZ As Double = 0.09 Public Function ObliczDoWyplaty(ByVal KwotaBrutto As Decimal) As _ Decimal Implements ModulKlasJG.IObliczWyplate.ObliczDoWyplaty mbruttop = KwotaBrutto mskladkizus = 0 mpodstawaskladki = mbruttop - mskladkizus mskladkiuz = 0 mkosztuzysku = Round(mPodstawaSkladki * 0.5, 2) mpodstawapodatku = mpodstawaskladki - mkosztuzysku mpodatekus = Round(mPodstawaPodatku * _ mpodstawaskladki * , 0) Return mbruttop - mskladkizus - mskladkiuz - mpodatekus End Function End Class Podobnie jak poprzednio w module klasy formularza frmpolimorfizm musimy dodać potrzebne procedury. Private Sub WyliczWyplate(ByVal IPodatek As IObliczWyplate, _ ByVal kwotabrutto As Decimal, ByVal txttext As TextBox) txttext.text = Format(IPodatek.ObliczDoWyplaty(kwotaBrutto), _ "# ##0.00 zł") End Sub Private Sub btnwginterfejsu_click(byval sender As System.Object, _ ByVal e As System.EventArgs) Handles btnwginterfejsu.click If IsNumeric(Me.txtBruttoPraca.Text) AndAlso _ IsNumeric(Me.txtBruttoZlecenie.Text) Then 24
25 Dim item1 As New CPraca Dim item2 As New CZlecenie WyliczWyplate(item1, CDec(Me.txtBruttoPraca.Text), _ Me.txtDoWyplatyPi) WyliczWyplate(item2, CDec(Me.txtBruttoZlecenie.Text), _ Me.txtDoWyplatyZi) Else MsgBox("Co najmniej jedna z pozycji 'brutto' jest źle podana", _ MsgBoxStyle.Critical, "Testowanie poliformizu wg interfejsu") End Sub I efekt działania tego kodu. 25
26 1.7 Diagram klas UML UML (ang. Unified Modeling Language) jest standardowym narzędziem wykorzystywanym do specyfikacji, wizualizacji, konstruowania i dokumentowania składników programu. Zwyczajowo diagram klasy przedstawiany jest jako prostokąt podzielony na kilka części. Na samej górze jest nazwa klasy, dalej mogą wystąpić takie grupy elementów jak: Fields zmienne prywatne czy formanty w przypadku formularza; Properties właściwości; Methods metody; Events zdarzenia. Poza wymienionymi elementami diagram może zawierać informacje o klasie bazowej czy o interfejsach. Poniżej przykład diagramu klas utworzonych w projekcie TestPolimorfizmu. 26
27 I jeszcze jeden przykład diagramów klas projektu 27
28 2 Przykłady klas 2.1 CKwotaSlownie W projekcie TestCKwotaSlownie utworzono klasę CKwotaSlownie, której zadaniem jest zamiana kwoty na jej odpowiednik słowny. Poniżej pełny kod tej klasy, zawiera on deklaracje zmiennych prywatnych klasy, definicję struktury o nazwie Slowny, definicję konstruktora inicjującego zmienne prywatne zadeklarowane ze słowem Shared, prywatne funkcje PartOfSlownie i Ustal oraz publiczną funkcję KwotaSlownie, która występuje w dwóch wersjach różniących się zestawem argumentów (przeciążenie). Public Class CKwotaSlownie ' deklaracja tablicy z specyfikatorem dostępu Shared ' konsekwencja będzie taka, że będzie istnieć tylko jedna kopia ' tej tablicy Private Shared txtt(10, 10) As String Private bmilion, btysiac As Boolean ' deklaracja struktury, która będzie zwracana przez PartOfSlownie Private Structure Slownie Dim x As Decimal ' deklaracja Dim xd As Integer Dim tp As String End Structure Shared Sub New() ' deklaracja z użyciem słowa Shared, tym samym metoda ta będzie ' wykonana tylko raz. ' każda nowa instancja tej klasy będzie korzystać z wcześniej ' utworzonej zmiennej txtt() Dim i As Integer Dim x1() As String = {"", "sto", "dwieście", "trzysta", _ "czterysta", "pięćset", "sześćset", _ "siedemset", "osiemset", "dziewięćset"} For i = 0 To 9 txtt(i, 1) = x1(i) Next i Dim x2() As String = {"", "dziesięć", "dwadzieścia", _ "trzydzieści", "czterdzieści", _ "pięćdziesiąt", "sześćdziesiąt", "siedemdziesiąt", _ "osiemdziesiąt", "dziewięćdziesią"} For i = 0 To 9 txtt(i, 2) = x2(i) 28
29 Next i Dim x3() As String = {"", "jedenaście", "dwanaście", _ "trzynaście", "czternaście", "piętnaście", "szesnaście", _ "siedemnaście", "osiemnaście", "dziewiętnaście"} For i = 0 To 9 txtt(i, 3) = x3(i) Next i Dim x4() As String = {"", "jeden", "dwa", "trzy", "cztery", _ "pięć", "sześć", "siedem", "osiem", "dziewięć"} For i = 0 To 9 txtt(i, 4) = x4(i) Next i Dim x5() As String = {"", "tysięcy", "tysiące", "tysiące", _ "tysiące", "tysięcy", "tysięcy", "tysięcy", "tysięcy", _ "tysięcy"} For i = 0 To 9 txtt(i, 5) = x5(i) Next i Dim x6() As String = {"", "tysiąc", "tysiące", "tysiące", _ "tysiące", "tysięcy", "tysięcy", "tysięcy", "tysięcy", _ "tysięcy"} For i = 0 To 9 txtt(i, 6) = x6(i) Next i Dim x7() As String = {"złotych", "złoty", "złote", "złote", _ "złote", "złotych", "złotych", "złotych", "złotych", _ "złotych"} For i = 0 To 9 txtt(i, 7) = x7(i) Next i Dim x8() As String = {"", "grosz", "grosze", "grosze", "grosze", _ "groszy", "groszy", "groszy", "groszy", "groszy"} For i = 0 To 9 txtt(i, 8) = x8(i) Next i Dim x9() As String = {"", "milion", "miliony", "miliony", _ "miliony", "milionów", "milionów", "milionów", _ "milionów", "milionów"} For i = 0 To 9 txtt(i, 9) = x9(i) Next i ' MsgBox("wykonałem txtt") End Sub 29
30 Private Function PartOfSlownie(ByVal xp As Decimal, _ ByVal d As Integer, ByVal i As Integer, _ ByRef tp As String) As Slownie Dim xd As Integer, CzyKilkanascie As Boolean = False If d = 7 Or d = 4 Or d = 1 Then CzyKilkanascie = True xd = Int(xp / (10 ^ d)) With PartOfSlownie If CzyKilkanascie AndAlso xd = 1 Then xd = Int(xp * 10 / (10 ^ d)).x = xp - xd * (10 ^ d) / 10.xd = xd.tp = txtt(xd - 10, i + 1) If d = 7 Then bmilion = True ElseIf d = 4 Then btysiac = True Else.x = xp - xd * (10 ^ d).xd = xd.tp = txtt(xd, i) If d = 6 Then bmilion = True ElseIf d = 3 Then btysiac = True tp &=.tp If d = 6 And tp <> "" Then If bmilion AndAlso xd > 0 Then tp &= " " & txtt(xd, 9) Else tp &= " milionów" If d = 3 AndAlso tp <> "" Then If btysiac And xd > 0 Then tp &= " " & txtt(xd, 6) '" tysięcy" Else tp &= " tysięcy" If tp <> "" Then tp &= " " 30
31 End With End Function Public Function KwotaSlownie(ByVal xp As Decimal) As String Return Ustal(xp) End Function Public Function KwotaSlownie(ByVal t As String) As String Dim xp As Decimal ' deklaracja pomocniczej zmiennej ' w bloku Tray-Catch próbujemy przekształcić tekst na liczbę dziesiętną Try xp = CDec(t) ' konwersja tekstu na liczbę Return Ustal(xp) 'konwersja udana, wywołujemy pomocniczą funkcję Catch ex As Exception ' ten fragment wykonywany jest wtedy, gdy w bloku Tray coś poszło nie tak Return "Argument nie reprezentuje kwoty" End Try End Function Private Function Ustal(ByVal xp As Decimal) As String ' funkcja zaczyna swoją pracę od sprawdzenia, czy kwota jest z ' założonego przedziału If xp > 0 And xp < Then ' tak, zaczynamy obliczenia Dim y As Slownie, Tp As String bmilion = False ' wartość True ma identyfikować kwotę rzędu ' pojedynczego miliona btysiac = False ' wartość True ma identyfikować fragment kwoty ' odpowiadajacy pojedynczem tysiącom Tp = "" Dim P() As Integer = {4, 2, 1, 4, 2, 1, 4, 2, 1} y.x = xp ' w pętli (malejącej) badamy, ile jest setek milionów, ' kilkudziesięciu (kilkunastu) milionów, kilku milionów, dalej ' setek tysięcy itd., aż do złotych For i = 8 To 0 Step -1 y = PartOfSlownie(y.x, i, P(i), Tp) Next i If Tp = "" Then Tp = "zero" Tp &= txtt(y.xd, 7) 31
32 If y.x > 0 Then y.x = y.x * 100 Tp &= " i " For i = 1 To 0 Step -1 y = PartOfSlownie(y.x, i, P(i), Tp) Next If y.xd = 0 Then Tp &= " groszy" Else Tp &= txtt(y.xd, 8) Else Tp &= " i zero groszy" Return LTrim(Tp) Else ' nie, zwracamy stosowny komunikat Return "Podana kwota jest mniejsza od 0 lub większa od " & _ " " End Function End Class W projekcie TestCKwotaSlownie jest formularz frmkwota, którego projekt pokazany jest niżej. Umieszczono w nim pole tekstowe txtkwota, przycisk polecenia btnustal oraz etykiety Label1 i Label2. Ta ostatnia zostanie wykorzystana do zwrócenia kwoty słownie. W kodzie klasy tego formularza utworzono jedną procedurę zdarzeniową obsługującą klik przycisku btnustal. Public Class frmkwota Private Sub btnustal_click(byval sender As Object, _ ByVal e As System.EventArgs) Handles btnustal.click Dim w As New CKwotaSlownie Me.Label2.Text = w.kwotaslownie(cdec(me.txtkwota.text)) End Sub End Class 32
33 A tak wygląda funkcjonowanie tego formularza. 2.2 CValidacja Projekt TestCValidacjiJG demonstruje klasę CValidacja i sposób wykorzystania jej metod w procesie walidacji wprowadzonych informacji. Poniżej pełny kod klasy CValidacja, zaczyna on się do zaimportowania potrzebnej przestrzeni nazw. Imports System.Windows.Forms Public Class CValidacja Private mtext As String Private mtextbox As TextBox Private merrpro As ErrorProvider Private mkomunikat As String = "" Private mfokus As Boolean Private mcombo As ComboBox 33
34 Private Sub Pomoc(ByVal txtbox As TextBox, ByVal errpro As _ ErrorProvider, ByVal txtkom As String, _ Optional ByVal fokus As Boolean = False) mtextbox = txtbox merrpro = errpro mkomunikat = txtkom mfokus = fokus ' usunięcie wszystkich spacji z lewej i prawej strony mtext = Trim(mTextBox.Text) End Sub Public Function CzyTextBoxDobry(ByVal Validowac As Boolean, _ ByVal txtbox As TextBox, ByVal errpro As ErrorProvider, _ ByVal txtkom As String, Optional ByVal lenmin As Integer = 0, _ Optional ByVal lenmax As Integer = 0, _ Optional ByVal fokus As Boolean = False) As Boolean If Not Validowac Then Return True Pomoc(txtBox, errpro, txtkom, fokus) ' badanie, czy to nie jest pusty ciąg znaków? If mtext.length = 0 AndAlso mfokus = False Then Return False If mtext.length = 0 Then Return ObslugaBledu() ' nie jest to pusty ciąg znaków, czy mamy sprawdzać długość? ' jeżeli lenmax <> 0, to sprawdzamy, czy długość jest między ' lenmin i lenmax If lenmax > 0 Then If mtext.length < lenmin Then mkomunikat = "Długość tekstu nie może być mniejsza niż " & _ lenmin.tostring & " znaków" Return ObslugaBledu() If mtext.length > lenmax Then mkomunikat = "Długość tekstu nie może być większa niż " & _ lenmax.tostring & " znaków" Return ObslugaBledu() ' zlikwidowanie stanu błędu (jeżeli był) errpro.seterror(mtextbox, "") 34
35 Return True End Function Public Function CzyTextBoxToData(ByVal Validowac As Boolean, _ ByVal txtbox As TextBox, ByVal errpro As ErrorProvider, _ ByVal txtkom As String, Optional ByVal MinRok As Decimal = 0, _ Optional ByVal MaxRok As Decimal = 0, _ Optional ByVal fokus As Boolean = False) As Boolean If Not Validowac Then Return True ' deklaracja pomocniczych zmiennych lokalnych Dim introk, intmc, intday As Integer Pomoc(txtBox, errpro, txtkom, fokus) If mtext.length = 0 AndAlso mfokus = False Then Return False ' data w formacie rrrr-mm-dd musi mieć 10 znaków, sprawdzamy, czy ma? If mtext.length <> 10 Then Return ObslugaBledu() ' 5 i 8 znak to -, sprawdzamy, czy tak jest? Metoda substring indeksuje znaki od zera, stąd zmniejszamy punkt startowy o 1 If mtext.substring(4, 1) <> "-" OrElse _ mtext.substring(7, 1) <> "-" Then mkomunikat = "format daty niezgiodny z 'yyyy-mm-dd'" Return ObslugaBledu() ' pytanie, czy pierwsze cztery znaki to cyfry? If Not IsNumeric(mText.Substring(0, 4)) Then mkomunikat = "pierwsze cztery znaki nie reprezentują roku!" Return ObslugaBledu() Else introk = CInt(mText.Substring(0, 4)) ' czy znaki miesiąca reprezentują liczbę? If Not IsNumeric(mText.Substring(5, 2)) Then mkomunikat = _ "dwa środkowe znaki nie reprezentują numeru miesiąca!" Return ObslugaBledu() Else intmc = CInt(mText.Substring(5, 2)) 35
36 ' czy ostatnie dwa znaki to numer dnia? If Not IsNumeric(mText.Substring(8, 2)) Then mkomunikat = "dwa ostatnie znaki nie reprezentują numeru dnia!" Return ObslugaBledu() Else intday = CInt(txtBox.Text.Substring(8, 2)) ' czy rok jest z dobrego zakresu? If MinRok > 0 AndAlso introk < MinRok Then mkomunikat = "Rok mniejszy od wymaganego (od " & _ MinRok.ToString & ")!" Return ObslugaBledu() If MaxRok > 0 AndAlso introk > MaxRok Then mkomunikat = "Rok większy od wymaganego (od " & _ MaxRok.ToString & ")!" Return ObslugaBledu() ' czy miesiąc jest dobry? If intmc < 1 OrElse intmc > 12 Then mkomunikat = "Źle określony miesiąc!" Return ObslugaBledu() ' a co jest z numerem dnia?? If intday < 0 Then mkomunikat = "Numer dnia nie może być mniejszy od 1!" Return ObslugaBledu() Select Case intmc Case 2 ' badamy, czy rok jest przestępny If introk Mod 4 = 0 Then ' tak, czyli może być 29 dni If intday > 29 Then mkomunikat = "Numer dnia nie może być większy od 29!" Return ObslugaBledu() Else If intday > 28 Then mkomunikat = "Numer dnia nie może być większy od 28!" Return ObslugaBledu() Case 1, 3, 5, 7, 8, 10, 12 36
37 If intday > 31 Then mkomunikat = "Numer dnia nie może być większy od 31!" Return ObslugaBledu() Case Else If intday > 30 Then mkomunikat = "Numer dnia nie może być większy od 30!" Return ObslugaBledu() End Select ' kasujemy znacznik błędu errpro.seterror(txtbox, "") Return True End Function Public Function CzyTextBoxToLiczba(ByVal Validowac As Boolean, _ ByVal txtbox As TextBox, ByVal errpro As ErrorProvider, _ ByVal txtkom As String, _ Optional ByVal MinValue As Decimal = 0, _ Optional ByVal MaxValue As Decimal = 0, _ Optional ByVal fokus As Boolean = False) As Boolean If Not Validowac Then Return True Pomoc(txtBox, errpro, txtkom, fokus) If mtext.length = 0 AndAlso mfokus = False Then Return False If mtext.length = 0 Then Return ObslugaBledu() ' nie jest to pusty ciąg znaków, sprawdzamy, czy jest liczbą? If Not IsNumeric(mText) Then mkomunikat = "Wprowadzony ciąg znaków nie jest liczbą" Return ObslugaBledu() ' sprawdzamy, czy to liczba z danego zakresu If MinValue <> MaxValue Then Dim xp As Decimal = CDec(mText) If MinValue < MaxValue Then If xp < MinValue Then mkomunikat = _ "Wprowadzona liczba nie może być mniejsza od " & _ MinValue.ToString 37
38 Return ObslugaBledu() ElseIf xp > MaxValue Then mkomunikat = _ "Wprowadzona liczba nie może być większa od " & _ MaxValue.ToString Return ObslugaBledu() errpro.seterror(txtbox, "") Return True End Function Public Function CzyWybranoPozycjeCombo(ByVal Validowac As Boolean, _ ByVal cbo As ComboBox, ByRef errpro As ErrorProvider, _ ByVal txtkom As String, _ Optional ByVal fokus As Boolean = False) As Boolean If Not Validowac Then Return False mcombo = cbo If mcombo.selectedvalue = Nothing Then Return ObslugaBleduCombo() Else errpro.seterror(mcombo, "") Return True End Function Private Function ObslugaBledu() As Boolean Beep() merrpro.seterror(mtextbox, mkomunikat) If mfokus Then mtextbox.focus() Return False End Function Private Function ObslugaBleduCombo() As Boolean Beep() merrpro.seterror(mcombo, mkomunikat) If mfokus Then mcombo.focus() Return False 38
39 End Function End Class 2.3 Klasa CDataGridPrint Prezentowana klasa rozwiązuje jeden z istotnych problemów każdej aplikacji napisanej w środowisku.net i wykorzystujących obiekty typu DataGridView. Klasa zawiera procedury i funkcje umożliwiające proste drukowanie informacji prezentowanych w gridach. Przedstawione rozwiązanie bazuje na podobnej klasie napisanej w języku C# 1. Imports System Imports System.Text Imports System.Collections Imports System.Collections.Generic Imports System.Drawing Imports System.Drawing.Printing Imports System.Data Imports System.Windows.Forms Kod klasy CDataGridPrint zaczyna się deklaracjami szeregu zmiennych prywatnych klasy, w komentarzach zawarto ich przeznaczenie. Public Class CDataGridPrint Private mdatagridview As DataGridView 'DataGridView Control ' który będzie drukowany Private mprintdocument As PrintDocument 'obiekt PrintDocument ' który będzie uzyty do druku Private miscenteronpage As Boolean ' zmienna determinująca ' wycentrowanie raportu Private miswithtitle As Boolean 'zmienna detreminująca tytuł ' strony Private mtitletext As String ' tytuł, który ma być drukowany ' na każdej stronie Private mtitlefont As Font ' font, którym ma być drukowany ' tytuł Private mtitlecolor As Color ' kolor, którym ma być drukowany ' tytuł Private miswithpaging As Boolean ' determinuje użycie paginacji
40 Private Shared mcurrentrow As Integer = 0 ' statyczny parametr ' wskazujący wiersz gridu, który powinien być wydrukowany Private Shared mpagenumber As Integer Private mpagewidth As Integer Private mpageheight As Integer Private mleftmargin As Integer Private mtopmargin As Integer Private mrightmargin As Integer Private mbottommargin As Integer Private mcurrenty As Decimal ' zmienna utrzymująca koordynatę ' y-kową, kolejny drukowany obiekt będzie drukowany od niej Private mrowheaderheight As Decimal Private mrowsheight As List(Of Decimal) Private mcolumnswidth As List(Of Decimal) Private mdatagridviewwidth As Decimal ' deklaracja list. które będą przechowywać początkowe i końcowe ' punkty drukowanych kolumn, będą używane w tych sytuacjach, ' gdy drukowany grid będzie zajmował więcej niż jedną stronę Private mcolumnpoints As List(Of Integer()) Private mcolumnpointswidth As List(Of Decimal) Private mcolumnpoint As Integer ' kod konstruktora i innych procedur klasy End Class Poniżej kod konstruktora klasy, przekazujemy do niego drukowany grid, obiekt typu PrintDocument i kilka innych parametrów definiujących sposób wydruku gridu. Public Sub New(ByVal adatagridview As DataGridView, ByVal _ aprintdocument As PrintDocument, ByVal CenterOnPage As _ Boolean, ByVal awithtitle As Boolean, ByVal atitletext As _ String, ByVal atitlefont As Font, ByVal atitlecolor As _ Color, ByVal awithpaging As Boolean) mdatagridview = adatagridview mprintdocument = aprintdocument miscenteronpage = CenterOnPage miswithtitle = awithtitle mtitletext = atitletext mtitlefont = atitlefont mtitlecolor = atitlecolor miswithpaging = awithpaging mpagenumber = 0 mrowsheight = New List(Of Decimal) mcolumnswidth = New List(Of Decimal) mcolumnpoints = New List(Of Integer()) 40
41 mcolumnpointswidth = New List(Of Decimal) ' ustalenie wysokości i szerokości strony With mprintdocument.defaultpagesettings If.Landscape Then mpageheight =.PaperSize.Width mpagewidth =.PaperSize.Height Else mpageheight =.PaperSize.Height mpagewidth =.PaperSize.Width ' ustalenie marginesów mleftmargin =.Margins.Left mtopmargin =.Margins.Top mrightmargin =.Margins.Right mbottommargin =.Margins.Bottom End With mcurrentrow = 0 ' ustawienie pierwszego wiersza gridu do druku End Sub Procedura pcalculate olicza oblicza wysokość każdego wiersza gridu (włącznie z wierszem nagłówkowym), szerokość każdej z kolumn (zależnie od długości tekstu, włącznie z komórką nagłówka) oraz szerokość całego gridu. Private Sub pcalculate(byval g As Graphics) If mpagenumber = 0 Then ' obliczenie prowadzone tylko raz Dim tmpsize As SizeF = New SizeF() Dim tmpfont As Font, tmpwidth As Decimal mdatagridviewwidth = 0 Dim i, j As Integer With mdatagridview For i = 0 To.Columns.Count - 1 tmpfont =.ColumnHeadersDefaultCellStyle.Font If tmpfont Is Nothing Then tmpfont =.DefaultCellStyle.Font tmpsize = g.measurestring(.columns(i).headertext, _ tmpfont) tmpwidth = tmpsize.width mrowheaderheight = tmpsize.height For j = 0 To.Rows.Count - 1 tmpfont =.Rows(j).DefaultCellStyle.Font If tmpfont Is Nothing Then tmpfont =.DefaultCellStyle.Font 41
42 tmpsize = g.measurestring("anything", tmpfont) mrowsheight.add(tmpsize.height) tmpsize = g.measurestring(.rows(j).cells(i). _ EditedFormattedValue.ToString(), tmpfont) If (tmpsize.width > tmpwidth) Then tmpwidth = tmpsize.width Next j If.Columns(i).Visible Then mdatagridviewwidth += tmpwidth mcolumnswidth.add(tmpwidth) Next i End With ' określenie początkowego i końcowego punktu kolumny w ' oparciu o szerokość strony i gridu ' punkty te będą wykorzystane do ustalenia kolumn, które będą ' drukowane na każdej stronie oraz jak ma być obsługiwane ' zawijanie, domyślnie zawijanie będzie tak ustawiane, aby ' liczba kolumn na sronie była maksymalna Dim k As Integer, mstartpoint As Integer = 0 With mdatagridview For k = 0 To.Columns.Count - 1 If.Columns(k).Visible Then mstartpoint = k Exit For Next k Dim mendpoint As Integer =.Columns.Count For k =.Columns.Count - 1 To 0 Step -1 If.Columns(k).Visible Then mendpoint = k + 1 Exit For Next k Dim mtempwidth As Decimal = mdatagridviewwidth Dim mtempprintarea As Decimal = _ mpagewidth - mleftmargin - mrightmargin ' musimy obsłużyć zdarzenie, gdy szerokość gridu ' jest większa od szerokości obszaru druku If mdatagridviewwidth > mtempprintarea Then mtempwidth = 0.0 For k = 0 To.Columns.Count - 1 If.Columns(k).Visible Then 42
43 mtempwidth += mcolumnswidth(k) ' jeżeli szerokość gridu jest większa ' definiujemy nowy obszar druku kolumn If mtempwidth > mtempprintarea Then mtempwidth -= mcolumnswidth(k) mcolumnpoints.add(new Integer() _ {mstartpoint, mendpoint}) mcolumnpointswidth.add(mtempwidth) mstartpoint = k mtempwidth = mcolumnswidth(k) ' nasz punkt końcowy jest aktualnie jeden ' indeks nad bieżącym indeksem mendpoint = k + 1 Next k ' dodanie ostatniego zestawu kolumn mcolumnpoints.add(new Integer() {mstartpoint, mendpoint}) mcolumnpointswidth.add(mtempwidth) mcolumnpoint = 0 End With End Sub Prywatna procedura pdrawheader odpowiada za wydrukowanie tytułu raportu, numeru strony oraz wiersza nagłówkowego. Private Sub pdrawheader(byval g As Graphics) mcurrenty = mtopmargin ' druk numeru strony (jeżeli miswithpaging jest prawdą) If miswithpaging Then mpagenumber += 1 Dim PageString As String = "Strona " + mpagenumber.tostring() Dim PageStringFormat As StringFormat = New StringFormat() PageStringFormat.Trimming = StringTrimming.Word PageStringFormat.FormatFlags = StringFormatFlags.NoWrap Or _ StringFormatFlags.LineLimit Or StringFormatFlags.NoClip PageStringFormat.Alignment = StringAlignment.Far Dim PageStringFont As Font = New Font("Times New Roman", 10, _ FontStyle.Regular, GraphicsUnit.Point) Dim PageStringRectangle As RectangleF = _ New RectangleF(mLeftMargin, _ mcurrenty, mpagewidth - mrightmargin - mleftmargin, _ 43
44 g.measurestring(pagestring, PageStringFont).Height) g.drawstring(pagestring, PageStringFont, _ New SolidBrush(Color.Black), PageStringRectangle, _ PageStringFormat) PageStringFormat = New StringFormat() PageStringFormat.Trimming = StringTrimming.Word PageStringFormat.FormatFlags = StringFormatFlags.NoWrap Or _ StringFormatFlags.LineLimit Or StringFormatFlags.NoClip PageStringFormat.Alignment = StringAlignment.Far PageStringFont = New Font("Times New Roman", 10, _ FontStyle.Regular, GraphicsUnit.Point) PageStringRectangle = New RectangleF(mLeftMargin, mcurrenty, _ mpagewidth - mrightmargin - mleftmargin, _ g.measurestring(pagestring, PageStringFont).Height) g.drawstring(pagestring, PageStringFont, _ New SolidBrush(Color.Black), PageStringRectangle, _ PageStringFormat) mcurrenty += g.measurestring(pagestring, _ PageStringFont).Height ' druk tytułu raportu (jeżeli miswithtitle jest prawdą) If miswithtitle Then Dim TitleFormat As StringFormat = New StringFormat() TitleFormat.Trimming = StringTrimming.Word TitleFormat.FormatFlags = StringFormatFlags.NoWrap Or _ StringFormatFlags.LineLimit Or StringFormatFlags.NoClip If miscenteronpage Then TitleFormat.Alignment = StringAlignment.Center Else TitleFormat.Alignment = StringAlignment.Near Dim TitleRectangle As RectangleF = _ New RectangleF(mLeftMargin, mcurrenty, mpagewidth - _ mrightmargin - mleftmargin, _ g.measurestring(mtitletext, mtitlefont).height) g.drawstring(mtitletext, mtitlefont, _ New SolidBrush(mTitleColor), TitleRectangle, TitleFormat) mcurrenty += g.measurestring(mtitletext, mtitlefont).height ' ustalenie koordynaty x-owej, od niej zacznie się druk Dim CurrentX As Decimal = mleftmargin If miscenteronpage Then CurrentX += ((mpagewidth - mrightmargin - mleftmargin) - _ mcolumnpointswidth(mcolumnpoint)) / 2 44
45 With mdatagridview ' ustawienie stylu nagłówka Dim HeaderForeColor As Color = _.ColumnHeadersDefaultCellStyle.ForeColor If HeaderForeColor.IsEmpty Then HeaderForeColor =.DefaultCellStyle.ForeColor Dim HeaderForeBrush As SolidBrush = _ New SolidBrush(HeaderForeColor) ' ustawienie tła nagłówka Dim HeaderBackColor As Color = _.ColumnHeadersDefaultCellStyle.BackColor If HeaderBackColor.IsEmpty Then HeaderBackColor =.DefaultCellStyle.BackColor Dim HeaderBackBrush As SolidBrush = _ New SolidBrush(HeaderBackColor) ' utworzenie obiektu LinePen, który będzie użyty do ' rysowania linii i prostokątów ' wykorzystana została właściwość GridColor drukowanego gridu Dim TheLinePen As Pen = New Pen(.GridColor, 1) ' ustawienie fontu nagłówka Dim HeaderFont As Font =.ColumnHeadersDefaultCellStyle.Font If HeaderFont Is Nothing Then HeaderFont =.DefaultCellStyle.Font ' oblicznie i wydruk granic nagłówka Dim HeaderBounds As RectangleF = _ New RectangleF(CurrentX, mcurrenty, _ mcolumnpointswidth(mcolumnpoint), mrowheaderheight) g.fillrectangle(headerbackbrush, HeaderBounds) ' utworzenie formatu, który będzie użyty do wydrukowania ' każdej komórki wiersza nagłówkowego Dim CellFormat As StringFormat = New StringFormat() CellFormat.Trimming = StringTrimming.Word CellFormat.FormatFlags = StringFormatFlags.NoWrap Or _ StringFormatFlags.LineLimit Or StringFormatFlags.NoClip ' wydruk każdej widocznej celi wiersza nagłówka Dim CellBounds As RectangleF, ColumnWidth As Decimal, _ i As Integer For i = mcolumnpoints(mcolumnpoint).getvalue(0) To _ mcolumnpoints(mcolumnpoint).getvalue(1) - 1 If.Columns(i).Visible = True Then 45
46 ColumnWidth = mcolumnswidth(i) ' sprawdzenie wyrównania bieżącej komórki i przypisanie ' go do obiektu CellFormat If.ColumnHeadersDefaultCellStyle.Alignment. _ ToString().Contains("Right") Then CellFormat.Alignment = StringAlignment.Far ElseIf (.ColumnHeadersDefaultCellStyle.Alignment. _ ToString().Contains("Center")) Then CellFormat.Alignment = StringAlignment.Center Else CellFormat.Alignment = StringAlignment.Near CellBounds = New RectangleF(CurrentX, mcurrenty, _ ColumnWidth, mrowheaderheight) ' wydruk zawartości komórki gridu g.drawstring(mdatagridview.columns(i).headertext, _ HeaderFont, HeaderForeBrush, CellBounds, CellFormat) ' wydruk granic komórki If.RowHeadersBorderStyle <> _ DataGridViewHeaderBorderStyle.None Then ' drukowanie granic komórki, ale tylko wtedy gdy ' HeaderBorderStyle jest zdefiniowany g.drawrectangle(thelinepen, CurrentX, mcurrenty, _ ColumnWidth, mrowheaderheight) CurrentX += ColumnWidth Next End With mcurrenty += mrowheaderheight End Sub Prywatna funkcja fdrawrows odpowiada za wydrukowanie zestawu (wiązki) wierszy, które wypełniają jedną stronę. Funkcja zwraca wartość TRUE wtedy, gdy nie wszystkie wiersze zostały wydrukowane i akcja drukowania strony musi być ponowiona. W sytuacji, gdy wszystkie wiersze zostały wydrukowane funkcja zwraca wartość FALSE, która sygnalizuje zakończenie akcji drukowania strony. 46
47 Private Function fdrawrows(byval g As Graphics) As Boolean ' utworzenie obiektu LinePen, będzie używany do rysowania linii ' i prostokątów Dim TheLinePen As Pen = New Pen(mDataGridView.GridColor, 1) ' deklaracje parametrów stylu, będą używane do druku każdej z ' komórek Dim RowFont As Font, RowForeColor, RowBackColor As Color Dim RowForeBrush, RowBackBrush, RowAlternatingBackBrush As _ SolidBrush ' utworzenie formatu, który będzie wykorzystany do druku każdej ' komórki gridu Dim CellFormat As StringFormat = New StringFormat() CellFormat.Trimming = StringTrimming.Word CellFormat.FormatFlags = StringFormatFlags.NoWrap Or _ StringFormatFlags.LineLimit ' druk każdej widocznej komórki Dim RowBounds As RectangleF, CurrentX, ColumnWidth As Decimal With mdatagridview While mcurrentrow <.Rows.Count If.Rows(mCurrentRow).Visible Then ' ustawienie fontu dla drukowanego wiersza RowFont =.Rows(mCurrentRow).DefaultCellStyle.Font If RowFont Is Nothing Then RowFont =.DefaultCellStyle.Font ' ustawienie stylu RowFore RowForeColor = _.Rows(mCurrentRow).DefaultCellStyle.ForeColor If RowForeColor.IsEmpty Then RowForeColor =.DefaultCellStyle.ForeColor RowForeBrush = New SolidBrush(RowForeColor) ' ustawienie stylu RowBack RowBackColor = _.Rows(mCurrentRow).DefaultCellStyle.BackColor If RowBackColor.IsEmpty Then RowBackBrush = _ New SolidBrush(.DefaultCellStyle.BackColor) RowAlternatingBackBrush = _ New SolidBrush( _.AlternatingRowsDefaultCellStyle.BackColor) Else RowBackBrush = New SolidBrush(RowBackColor) RowAlternatingBackBrush = _ 47
48 New SolidBrush(RowBackColor) ' wyliczenie koordynaty x, od niej zacznie się proces ' druku CurrentX = mleftmargin If miscenteronpage Then CurrentX += ((mpagewidth - mrightmargin - _ mleftmargin) - _ mcolumnpointswidth(mcolumnpoint)) / 2 ' obliczenie granic bieżącego wiersza RowBounds = New RectangleF(CurrentX, mcurrenty, _ mcolumnpointswidth(mcolumnpoint), _ mrowsheight(mcurrentrow)) ' wypełnienie tła bieżącego wiersza If mcurrentrow Mod 2 = 0 Then g.fillrectangle(rowbackbrush, RowBounds) Else g.fillrectangle(rowalternatingbackbrush, RowBounds) Dim CurrentCell As Integer For CurrentCell = _ mcolumnpoints(mcolumnpoint).getvalue(0) To _ mcolumnpoints(mcolumnpoint).getvalue(1) - 1 If.Columns(CurrentCell).Visible = True Then ' sprawdzenie wyrównania bieżącej komórki i ' przypisanie go do obiektu CellFormat If (.Columns(CurrentCell).DefaultCellStyle. _ Alignment.ToString().Contains("Right")) Then CellFormat.Alignment = StringAlignment.Far ElseIf (.Columns(CurrentCell).DefaultCellStyle. _ Alignment.ToString().Contains("Center")) Then CellFormat.Alignment = StringAlignment.Center Else CellFormat.Alignment = StringAlignment.Near ColumnWidth = mcolumnswidth(currentcell) Dim CellBounds As RectangleF = _ New RectangleF(CurrentX, mcurrenty, ColumnWidth, _ mrowsheight(mcurrentrow)) ' wydruk tekstu komórki g.drawstring(.rows(mcurrentrow).cells(currentcell). _ EditedFormattedValue.ToString(), _ RowFont, RowForeBrush, CellBounds, CellFormat) 48
49 ' wydruk granic komórki If (.CellBorderStyle <> _ DataGridViewCellBorderStyle.None) Then ' granice komórki drukowane wtedy, gdy styl ' CellBorderStyle jest okreslony g.drawrectangle(thelinepen, CurrentX, mcurrenty, _ ColumnWidth, mrowsheight(mcurrentrow)) CurrentX += ColumnWidth Next mcurrenty += mrowsheight(mcurrentrow) ' sprawdzenie, czy zmienna mcurrency osiągneła granice ' strony, jeżeli tak, to zwracamy TRUE, co oznacza ' konieczność ponownego wywołania akcji PagePrint If mcurrenty > mpageheight - mtopmargin - _ mbottommargin Then mcurrentrow += 1 Return True mcurrentrow += 1 End While End With mcurrentrow = 0 mcolumnpoint += 1 ' kontynuacja dla druku kolejnej grupy kolumn If (mcolumnpoint = mcolumnpoints.count) Then ' wszystkie kolumny zostały już wydrukowane mcolumnpoint = 0 Return False Else ' konieczny jest dalszy wydruk Return True End Function Publiczna funkcja DrawDataGridView (metoda klasy) wywołuje w strukturalnym bloku obsługi wyjątków istotne dla funkcjonowania klasy jej prywatne funkcje i procedury. Public Function DrawDataGridView(ByVal g As Graphics) As Boolean Dim ex As New Exception, Cont As Boolean Try pcalculate(g) pdrawheader(g) 49
50 Cont = fdrawrows(g) Return Cont Catch MessageBox.Show("Operacja druku nieudana: " & _ ex.message.tostring(), _ conmsg & " - Error", MessageBoxButtons.OK, _ MessageBoxIcon.Error) Return False End Try End Function 50
51 3 Utworzenie własnej biblioteki DLL Jednym z ważnych argumentów przemawiających za stosowaniem klas jako elementu programowania obiektowego jest możliwość ich łatwego wykorzystywania w innych aplikacjach, niż ta, w której powstały. Można to zrobić poprzez skompilowanie kodu klasy (oczywiście porządnie przetestowanej) do postaci pliku biblioteki dynamicznie dołączanej (DDL Dynamic Link Library). Prześledzimy ten problem na przykładzie klasy CValidacja, którą przedstawiłem wcześniej omawiając projekt TestCValidacja. 3.1 Kompilacja klasy CValidacja Punktem wyjścia będzie klasa CValidacja utworzona w projekcie TestCValidacja, ponieważ musimy dysponować klasą poprawnie zbudowaną i dobrze przetestowaną. Po otwarciu tego projektu w VisualStudio przechodzimy do klasy CStudent i cały jej kod kopiujemy do schowka Windows. Możemy teraz zamknąć ten projekt, a następnie wywołać opcję utworzenia nowego projektu. W oknie dostępnych szablonów wybieramy projekt Class Library zmieniając jednocześnie nazwę projektu (z domyślnej) na np. CValidacja, tak jak pokazano to niżej. Po akceptacji przycisku OK zostaje utworzony nowy projekt, a w oknie kodu zostaje wyświetlony szkielet nowo tworzonej klasy, tak jak pokazano to niżej. 51
52 Pamiętamy o tym, że w schowku Windows mamy kompletny kod naszej docelowej klasy CValidacja, przed jego wklejeniem musimy zaznaczyć i skasować widoczny powyżej kod. Po jego skasowaniu możemy już wkleić zawartość schowka, prawdopodobnie zobaczymy taki widok, jak niżej pokazany. Widzimy, że coś jest nie tak, środowisko VS.NET sygnalizuje nam błędy w pierwszym wierszu kodu importującym przestrzeń nazw System.Windows.Forms. Jego konsekwencją są dalsze błędy związane z deklaracją formantów typu TextBox, ErrProvider czy ComboBox. 52
53 Dzieje się tak dlatego, że w referencjach projektu nie ma dodanej referencji do tej biblioteki. Korzystając z przycisku Add otwieramy okno Add Reference, przechodzimy do zakładki.net i odszukujemy pozycję System.Windows.Forms. Klik przycisku Ok likwiduje pokazane wcześniej błędy w oknie tworzonej klasy. 53
54 Musimy teraz zmienić nazwę tworzonej klasy w oknie Solution Explorer z domyślnej Class1.vb na docelową CValidacja.vb. Robimy to korzystając z prawego przycisku myszy i polecenia Rename w menu kontekstowym. klasy. Poniżej widok po zmianie nazwy pliku, w którym przechowywany będzie kod naszej W oknie właściwości projektu w zakładce Application możemy jeszcze zmienić domyślną nazwę przestrzeni nazw z CValidacja na jakąś inną (najlepiej inną niż nazwa projektu). Ja w polu Root namespace wpisałem jgwszim, tak jak to pokazano niżej. 54
55 Pozostała jeszcze jedna ważna czynność przed kompilacją projektu, a mianowicie jego zapisanie na dysku w określonym folderze. Ja w tym celu (własnych bibliotek DLL) utworzyłem folder MojeDll na dysku E i tam zapiszę tworzony projekt. Pozostała ostania rzecz, kompilacja kodu. Z menu Build wywołujemy polecenie Build CValidacja i po chwili zobaczymy komunikat o pomyślnym zakończeniu kompilacji. Kompilacja klasy CValidacja została zakończona, możemy teraz zamknąć projekt tej klasy i utworzyć nowy projekt, w którym przetestujemy utworzoną przed chwilą bibliotekę DLL. 55
56 3.2 Testowanie biblioteki CValidacja.dll Tworzymy nowy projekt typu Windows Forms Application nadając mu nazwę np. TestCValidacjaDLL. Musimy teraz dodać referencję do utworzonej biblioteki CValidacja.dll, otwieramy okno właściwości projektu, przechodzimy do pozycji Referenses, przyciskiem Add otwieramy okno Add Reference, przechodzimy do zakładki Browse i w polu kombo Szukaj w: wskazujemy plik CValidacja.dll (w moim przypadku pełna ścieżka wiodąca do tego pliku to E:/MojeDll/CValidacja/CValidacja/bin/Release). Po wskazaniu pliku klik przycisku OK dodaje potrzebną referencję. 56
57 W polu Name wpisujemy nazwę projektu, ustawiamy jego ścieżkę w polu Location (można wykorzystać przycisk Browse do wskazania folderu) i przyciskiem OK tworzymy nowy projekt klasy. Po zatwierdzeniu nazwy projektu i jego lokalizacji Visual Studio otwiera okno projektu ze szkieletem tworzonej klasy obejmującym dwie instrukcje: Public Class Class1 End Class Musimy teraz kod klasy wypełnić instrukcjami, a najlepszą metodą będzie skopiowanie odpowiednich fragmentów kodu z projektu, w którym dana klasa była utworzona i przetestowana. W naszym przypadku jest to plik CDataGridPrint.vb, po jego otwarciu np. w Notatniku zaznaczamy i kopiujemy do schowka instrukcje importu przestrzeni nazw. 57
58 Sytuacja po skopiowaniu i wklejeniu instrukcji importu przestrzeni nazw pokazana jest poniżej. Jak widzimy środowisko programowania podkreśla falką kilka zaimportowanych przestrzeni nazw (i zgłasza błędy w Error List), co w naszym przypadku spowodowane jest tym, że domyślnie nie jest ustawiona referencja do komponentów System.Drawing, System.Drawing.Printing oraz System.Windows.Forms. Można to łatwo sprawdzić wywołując z menu Project polecenie CDataGridView Properties, a następnie przejść do zakładki Reference i spojrzeć do listy zaimportowanych 58
59 przestrzeni nazw Imported namespaces. W liście tej w tym momencie nie możemy zaznaczyć potrzebnych przestrzeni nazw, bo ich po prostu nie ma. Poprzez wywołanie z menu Project polecenia Add Reference lub klik przycisku Add widocznego nad listą Imported namespaces otwieramy okno dodawania referencji, a następnie w zakładce.net odszukujemy i zaznaczamy komponent System.Drawing. 59
60 Klik przycisku OK dodaje komponent do właściwości naszego projektu, jednocześnie znikają zastrzeżenia środowiska do importu przestrzeni nazw System.Drawing oraz System.Drawing.Printing. W analogiczny sposób dodajemy komponent System.Windows.Forms. Możemy teraz wrócić do naszego źródła (CDataGridPrint.vb otwartego np. w Notatniku) i skopiować cały kod zawarty między instrukcjami otwarcia i zamknięcia klasy (czyli między Public Class CDataGridPrint oraz End Class). Po przejściu do VisualStudio.Net ustawiamy kursor między instrukcjami Public Class Class1 a End Class i wklejamy zawartość schowka. Po tej operacji nasz projekt powinien wyglądać tak, jak na pokazanym niżej zrzucie ekranowym. Mamy już kompletny kod klasy, ale jej nazwa wymaga zmiany. W pokazanej sytuacji w otwartym oknie Solution Explorer został zaznaczony plik klasy po to, aby z menu kontekstowego wywołać polecenie Rename i nadać temu plikowi nazwę CDataGridView.vb 60
61 Po zatwierdzeniu zmiany nazwy pliku środowisko programistyczne zmienia także nazwę klasy na CDataGridView. W zasadzie można już skompilować klasę do postaci pliku DLL, ale możemy jeszcze wprowadzić jakąś swoją przestrzeń nazw dla tworzonego komponentu (domyślnie VisualStudio tworzy przestrzeń nazw taką samą, jak nazwa projektu). Po wywołaniu okna właściwości projektu w zakładce Application możemy zmienić domyślną nazwę przestrzeni nazw CDataGridView na swoją nazwę. W pokazanej niżej sytuacji została użyta nazwa JanGor.GridView, w ten sposób jeden z autorów tej pracy sygnuje swoje biblioteki DLL. Biblioteka DLL zawierająca klasę CForStorageSub będzie w tej sytuacji umieszczona w przestrzeni nazw JanGor.ForStorageSub. 61
62 Możemy już utworzyć bibliotekę DLL poprzez wywołanie z menu Build polecenia Build CDataGirdView. Po chwili środowiska potwierdza pomyśle wykonanie zadania, a plik DLL znajdziemy w podfolderze Bin\Debug folderu aplikacji. Jak można teraz korzystać z utworzonej biblioteki? Bardzo prosto, wystaczy w projekcie, w którym chcemy z tej biblioteki korzystać dodać stosowną referencję. 62
63 Dla prześledzenia tego problemu możemy otworzyć nowy projekt o nazwie np. TestMojegoDll, po jego utworzeniu z menu Project wywołujemy polecenie Add Reference, a następnie korzystając z zakładki Browse wskazujemy plik biblioteki DLL. Sytuacja taka pokazana jest niżej. Po dodaniu referencji w liście Imported namespaces możemy jeszcze odszukać i zaznaczyć przestrzeń nazw JanGor.GridView. Po wykonaniu tych czynności możemy już korzystać z klasy CDataGridView, w pokazanej niżej sytuacji w kodzie przykładowego formularza zaimportowano nazwę JanGor.GridView, co pozwala w kodzie korzystać z obiektu tej klasy. 63
64 64
Podstawy programowania w Visual Basic.Net
Wykłady z informa t yki Janusz Górczyński Podstawy programowania w Visual Basic.Net Wyższa Szkoła Zarządzania i Marketingu Sochaczew 20012 Zeszyt ten jest ósmą pozycją w serii materiałów dydaktycznych
Klasa bazowa i klasy potomne - doskonalenie umiejtnoci projektowania i wykorzystania klas (45 min)
Zadanie5_28 Klasa bazowa i klasy potomne - doskonalenie umiejtnoci projektowania i wykorzystania klas (45 min) Opis zadania Wykorzystaj gotowy projekt Nowe auto, a nastpnie zaprojektuj klas bazow NoweAuto
3 Delegacje. 3.1 Tworzenie delegacji. 3.2 Skojarzenie delegacji z procedurą czy funkcją
3 Delegacje Delegacja to specjalny typ danych, który przechowuje referencję (adres) do procedury lub funkcji. W środowisku.net delegacja jest odpowiednikiem wskaźnika (pointer) do funkcji znanego z języka
Aplikacje geodezyjne
Aplikacje geodezyjne 1. Azymut ze współrzędnych Utwórz nowy projekt o nazwie Azymut. W oknie rozmieść kontrolki mniej więcej zgodnie z rysunkiem. Obiekty mają zmienione następujące wartości cech: cecha
Programowanie obiektowe. Obiekt Klasa Składnia klasy: Interfejsy Składnia interfejsu: Metody Składnia instrukcji Sub: Składnia instrukcji function:
Programowanie obiektowe. Obiekt Obiekt to dowolny element, który możemy wydzielić i którym możemy manipulować. W terminologii informatycznej obiekt to samodzielna jednostka zawierająca zarówno dane, jak
Tablice, DataGridView
Tablice, DataGridView Gdy rośnie liczba danych do przechowywania w programie, a następnie ich obrobienia - pojawiają się nowe struktury danych (moŝna by powiedzieć pojemniki na dane) zwane tablicami. Tablica
Projekt Hurtownia, realizacja rejestracji dostaw produktów
Projekt Hurtownia, realizacja rejestracji dostaw produktów Ćwiczenie to będzie poświęcone zaprojektowaniu formularza pozwalającego na rejestrację dostaw produktów dla naszej hurtowni. Dane identyfikujące
Projekt Hurtownia, realizacja rejestracji dostaw produktów
Projekt Hurtownia, realizacja rejestracji dostaw produktów Ćwiczenie to będzie poświęcone zaprojektowaniu formularza pozwalającego na rejestrację dostaw produktów dla naszej hurtowni. Dane identyfikujące
Projekt Hurtownia, realizacja skojarzeń dostawców i produktów
niżej. Projekt Hurtownia, realizacja skojarzeń dostawców i produktów W bazie danych HurtowniaSP istnieją tabele Dostawcy oraz Produkty, ich definicje przypomniane są W bazie zdefiniowano także tabelę DostawcyProdukty,
Wykład 12. Programowanie serwera MS SQL 2005 w C#
Wykład 12 Programowanie serwera MS SQL 2005 w C# Budowa procedur składowanych w C# Budowa funkcji składowanych w C# Wykorzystanie funkcji składowanych w C# po stronie klienta Tworzenie typów definiowanych
Platforma.NET laboratorium 4 Aktualizacja: 15/11/2013. Visual Basic.NET dostęp do bazy danych. Baza Microsoft SQL Server Compact
Platforma.NET laboratorium 4 Aktualizacja: 15/11/2013 Prowadzący: mgr inż. Tomasz Jaworski Strona WWW: http://tjaworski.kis.p.lodz.pl/ Visual Basic.NET dostęp do bazy danych Baza Microsoft SQL Server Compact
LibreOffice Calc VBA
LibreOffice Calc VBA LibreOffice Calc umożliwia tworzenie własnych funkcji i procedur przy użyciu składni języka VBA. Dostęp do edytora makr: Narzędzia->Makra->Zarządaj makrami->libreoffice Calc Aby rozpocząć
Ten odcinek Akademii PC Kuriera poświęcony zostanie tworzeniu i wykorzystaniu funkcji i procedur w języku Visual Basic.NET.
Ten odcinek Akademii PC Kuriera poświęcony zostanie tworzeniu i wykorzystaniu funkcji i procedur w języku Visual Basic.NET. Czym są procedury? Efektywne tworzenie często polegać będzie na ponownym wykorzystywaniu
Uwagi dotyczące notacji kodu! Moduły. Struktura modułu. Procedury. Opcje modułu (niektóre)
Uwagi dotyczące notacji kodu! Wyrazy drukiem prostym -- słowami języka VBA. Wyrazy drukiem pochyłym -- inne fragmenty kodu. Wyrazy w [nawiasach kwadratowych] opcjonalne fragmenty kodu (mogą być, ale nie
Kurs WWW. Paweł Rajba. pawel@ii.uni.wroc.pl http://pawel.ii.uni.wroc.pl/
Paweł Rajba pawel@ii.uni.wroc.pl http://pawel.ii.uni.wroc.pl/ Spis treści Wprowadzenie Automatyczne ładowanie klas Składowe klasy, widoczność składowych Konstruktory i tworzenie obiektów Destruktory i
Paweł Górczyński, Janusz Górczyński. Aplikacja MS SQL Server i MS VB.NET do zarządzania studiami podyplomowymi
W ykłady z infor matyki Paweł Górczyński, Janusz Górczyński Aplikacja MS SQL Server i MS VB.NET do zarządzania studiami podyplomowymi Wyższa Szkoła Zarządzania i Marketingu Sochaczew 2010 Książka ta jest
Programowanie obiektowe
Laboratorium z przedmiotu Programowanie obiektowe - zestaw 02 Cel zajęć. Celem zajęć jest zapoznanie z praktycznymi aspektami projektowania oraz implementacji klas i obiektów z wykorzystaniem dziedziczenia.
TEMAT : KLASY DZIEDZICZENIE
TEMAT : KLASY DZIEDZICZENIE Wprowadzenie do dziedziczenia w języku C++ Język C++ możliwa tworzenie nowej klasy (nazywanej klasą pochodną) w oparciu o pewną wcześniej zdefiniowaną klasę (nazywaną klasą
Programowanie obiektowe
Laboratorium z przedmiotu - zestaw 02 Cel zajęć. Celem zajęć jest zapoznanie z praktycznymi aspektami projektowania oraz implementacji klas i obiektów z wykorzystaniem dziedziczenia. Wprowadzenie teoretyczne.
Materiały do laboratorium MS ACCESS BASIC
Materiały do laboratorium MS ACCESS BASIC Opracowała: Katarzyna Harężlak Access Basic jest językiem programowania wykorzystywanym w celu powiązania obiektów aplikacji w jeden spójny system. PROCEDURY I
Technologie i usługi internetowe cz. 2
Technologie i usługi internetowe cz. 2 Katedra Analizy Nieliniowej, WMiI UŁ Łódź, 15 luty 2014 r. 1 Programowanie obiektowe Programowanie obiektowe (z ang. object-oriented programming), to paradygmat programowania,
Programowanie obiektowe w VB cz 2
Programowanie obiektowe w VB cz 2 Interfejsy Interfejsy są listą metod, właściwości, zdarzeń i indeksowników. Jeśli jakaś klasa implementuje jakiś interfejs, znaczy to, że użytkownik tej klasy może skorzystać
Rejestracja sprzedaży
Rejestracja sprzedaży Powoli zbliżamy się do zakończenia prac nad projektem Hurtownia. Zajęcia 5 zjazdu szkoleniowego zostaną poświęcone na zabezpieczenie procesu rejestracji sprzedaży. Problem będzie
Wykład 5 Okna MDI i SDI, dziedziczenie
Wykład 5 Okna MDI i SDI, dziedziczenie Autor: Zofia Kruczkiewicz Zagadnienia 1. Aplikacja wielookienkowa. Zakładanie projektu typu CLR Windows Forms 1.1. Aplikacja typu MDI 1.2. Aplikacja typu SDI 2. Dziedziczenie
Programowanie w Javie 1 Wykład i Ćwiczenia 3 Programowanie obiektowe w Javie cd. Płock, 16 października 2013 r.
Programowanie w Javie 1 Wykład i Ćwiczenia 3 Programowanie obiektowe w Javie cd. Płock, 16 października 2013 r. Programowanie obiektowe Programowanie obiektowe (z ang. object-oriented programming), to
1. Które składowe klasa posiada zawsze, niezależnie od tego czy je zdefiniujemy, czy nie?
1. Które składowe klasa posiada zawsze, niezależnie od tego czy je zdefiniujemy, czy nie? a) konstruktor b) referencje c) destruktor d) typy 2. Które z poniższych wyrażeń są poprawne dla klasy o nazwie
Rozdział 4 KLASY, OBIEKTY, METODY
Rozdział 4 KLASY, OBIEKTY, METODY Java jest językiem w pełni zorientowanym obiektowo. Wszystkie elementy opisujące dane, za wyjątkiem zmiennych prostych są obiektami. Sam program też jest obiektem pewnej
PHP 5 język obiektowy
PHP 5 język obiektowy Wprowadzenie Klasa w PHP jest traktowana jak zbiór, rodzaj różnych typów danych. Stanowi przepis jak stworzyć konkretne obiekty (instancje klasy), jest definicją obiektów. Klasa reprezentuje
DataGridView. Aby dodawać kolumny wybieramy z listy zadań Add Column..., co wywoła okno dodawania kolumn, rys. 2. Rysunek 1
DataGridView Często potrzebujemy obiektu, który wyświetliłby tabelę zawierającą kilka kolumn i kilka wierszy. Dobrze do tego celu nadaje się obiekt DataGridView. Po przeniesieniu obiektu na formularz jest
KLASA UCZEN Uczen imię, nazwisko, średnia konstruktor konstruktor Ustaw Wyswietl Lepszy Promowany
KLASA UCZEN Napisz deklarację klasy Uczen, w której przechowujemy następujące informacje o uczniu: imię, nazwisko, średnia (pola prywatne), poza tym klasa zawiera metody: konstruktor bezparametrowy (nie
Janusz Górczyński. Projekt WynajemSal realizowany w trakcie drugiego semestru studiów podyplomowych
Janusz Górczyński Projekt WynajemSal realizowany w trakcie drugiego semestru studiów podyplomowych WSZiM w Sochaczewie, 2011 Spis treści 1 WSTĘP...3 2 BAZA DANYCH...4 2.1 TABELE...4 2.2 PROCEDURY PRZECHOWYWANE...11
KLASA UCZEN Uczen imię, nazwisko, średnia konstruktor konstruktor Ustaw Wyswietl Lepszy Promowany
KLASA UCZEN Napisz deklarację klasy Uczen, w której przechowujemy następujące informacje o uczniu: imię, nazwisko, średnia (pola prywatne), poza tym klasa zawiera metody: konstruktor bezparametrowy (nie
Programowanie obiektowe, wykład nr 6. Klasy i obiekty
Dr hab. inż. Lucyna Leniowska, prof. UR, Zakład Mechatroniki, Automatyki i Optoelektroniki, IT Programowanie obiektowe, wykład nr 6 Klasy i obiekty W programowaniu strukturalnym rozwój oprogramowania oparto
.NET Klasy, obiekty. ciąg dalszy
.NET Klasy, obiekty ciąg dalszy Przeciążanie operatorów 1 W języku C# istnieje możliwość zdefiniowania funkcjonalności dużej części operatorów dla typów stworzonych przez użytkownika. Dzięki takiemu zabiegowi,
UML a kod w C++ i Javie. Przypadki użycia. Diagramy klas. Klasy użytkowników i wykorzystywane funkcje. Związki pomiędzy przypadkami.
UML a kod w C++ i Javie Projektowanie oprogramowania Dokumentowanie oprogramowania Diagramy przypadków użycia Przewoznik Zarzadzanie pojazdami Optymalizacja Uzytkownik Wydawanie opinii Zarzadzanie uzytkownikami
Diagram klas UML jest statycznym diagramem, przedstawiającym strukturę aplikacji bądź systemu w paradygmacie programowania obiektowego.
Umiejętność czytania oraz tworzenia diagramów klas UML jest podstawą w przypadku zawodu programisty. Z takimi diagramami będziesz spotykał się w przeciągu całej swojej kariery. Diagramy klas UML są zawsze
Materiały do zajęć VII
Spis treści I. Klasy Materiały do zajęć VII II. III. Konstruktor Właściwości i indeksatory Klasy Programowanie obiektowe wiadomości wstępne Paradygmat programowania obiektowego Abstrakcja Hermetyzacja
Właściwości i metody obiektu Comment Właściwości
Właściwości i metody obiektu Comment Właściwości Właściwość Czy można zmieniać Opis Application nie Zwraca nazwę aplikacji, która utworzyła komentarz Author nie Zwraca nazwę osoby, która utworzyła komentarz
Janusz Górczyński. Opis projektu WynajemSal
Janusz Górczyński Opis projektu WynajemSal WSZiM w Sochaczewie, 2011 Spis treści 1 WSTĘP...3 2 BAZA DANYCH...4 2.1 TABELE...4 2.2 PROCEDURY PRZECHOWYWANE...11 3 APLIKACJA WINDOWSOWA...15 3.1 UTWORZENIE
Obiektowy PHP. Czym jest obiekt? Definicja klasy. Składowe klasy pola i metody
Obiektowy PHP Czym jest obiekt? W programowaniu obiektem można nazwać każdy abstrakcyjny byt, który programista utworzy w pamięci komputera. Jeszcze bardziej upraszczając to zagadnienie, można powiedzieć,
Dokumentacja do API Javy.
Dokumentacja do API Javy http://java.sun.com/j2se/1.5.0/docs/api/ Klasy i obiekty Klasa jest to struktura zawierająca dane (pola), oraz funkcje operujące na tych danych (metody). Klasa jest rodzajem szablonu
Podstawy Języka Java
Podstawy Języka Java Programowanie obiektowe Programowanie obiektowe (z ang. object-oriented programming), to paradygmat programowania, w którym programy definiuje się za pomocą obiektów elementów łączących
01 grid tablica grid. Copyright 2017, mgr inż. Janusz Bonarowski 1
01 grid tablica grid Zadanie Wykonajmy aplikację posiadającą dwa obiekty DataGridView. Jeden o nazwie DataGridView1, będzie formularzem wejściowym, drugi o nazwie DataGridView2 będziemy używać jako element
Wydział Zarządzania AGH. Katedra Informatyki Stosowanej. Podstawy VBA cz. 1. Programowanie komputerowe
Wydział Zarządzania AGH Katedra Informatyki Stosowanej Podstawy VBA cz. 1 Programowanie 1 Program wykładu Struktura programu Instrukcja przypisania Wprowadzanie danych Wyprowadzanie wyników Instrukcja
Programowanie 3 - Funkcje, pliki i klasy
Instytut Informatyki Uniwersytetu Śląskiego Laborki funkcja; parametry funkcji; typ zwracany; typ void; funkcje bez parametrów; napis.length() - jako przykład funkcji. Zadania funkcja dodająca dwie liczby;
Typy zmiennych proste i złożone. Programowanie komputerów. Tablica. Złożone typy zmiennych. Klasa. Struktura
Programowanie komputerów Programowanie obiektowe. Typy zmiennych proste i złożone Typy zmiennych "wbudowane", tj. identyfikowane przez słowa kluczowe, są określane jako proste: int short long float double
Class1.vb. _Dlugosc_stopnia = value End Set End Property Public Property Faza As Single Get Return _Faza End Get
Tematy: Xml Zapis i odczyt stopnia przy pomocy serializacji. Zapis i odczyt całego wału przy pomocy własnych procedur. Zamierzamy dodać do aplikacji nowe funkcjonalności: 1. Zapis i odczyt pojedynczego
Dziedziczenie. Tomasz Borzyszkowski
Dziedziczenie Tomasz Borzyszkowski Podstawy Zobacz: Dziedzictwo1.java Dziedzictwo2.java Dziedziczenie jest jedną z podstawowych cech OOP ponieważ umożliwia łatwe implementowanie klasyfikacji hierarchicznych.
- Narzędzie Windows Forms. - Przykładowe aplikacje. Wyższa Metody Szkoła programowania Techniczno Ekonomiczna 1 w Świdnicy
Wyższa Metody Szkoła programowania Techniczno Ekonomiczna 1 w Świdnicy - Narzędzie Windows Forms - Przykładowe aplikacje 1 Narzędzia Windows Form Windows Form jest narzędziem do tworzenia aplikacji dla
Algorytmika i Programowanie VBA 1 - podstawy
Algorytmika i Programowanie VBA 1 - podstawy Tomasz Sokół ZZI, IL, PW Czas START uruchamianie środowiska VBA w Excelu Alt-F11 lub Narzędzia / Makra / Edytor Visual Basic konfiguracja środowiska VBA przy
Aplikacje w środowisku Java
Aplikacje w środowisku Java Materiały do zajęć laboratoryjnych Klasy i obiekty - dziedziczenie mgr inż. Kamil Zieliński Katolicki Uniwersytet Lubelski Jana Pawła II 2018/2019 W ramach poprzedniego laboratorium
Programowanie obiektowe
Programowanie obiektowe Język programowania Ruby Marcin Młotkowski 12 kwietnia 2018 Plan wykładu 1 Wstęp 2 Typy numeryczne Łańcuchy znaków (klasa String) Przedziały Tablice i tablice asocjacyjne Nazwy
Klasy abstrakcyjne i interfejsy
Klasy abstrakcyjne i interfejsy Streszczenie Celem wykładu jest omówienie klas abstrakcyjnych i interfejsów w Javie. Czas wykładu 45 minut. Rozwiązanie w miarę standardowego zadania matematycznego (i nie
Wykład 8: klasy cz. 4
Programowanie obiektowe Wykład 8: klasy cz. 4 Dynamiczne tworzenie obiektów klas Składniki statyczne klas Konstruktor i destruktory c.d. 1 dr Artur Bartoszewski - Programowanie obiektowe, sem. 1I- WYKŁAD
Programowanie obiektowe
Programowanie obiektowe IV. Interfejsy i klasy wewnętrzne Małgorzata Prolejko OBI JA16Z03 Plan Właściwości interfejsów. Interfejsy a klasy abstrakcyjne. Klonowanie obiektów. Klasy wewnętrzne. Dostęp do
Podstawy Programowania Obiektowego
Podstawy Programowania Obiektowego Wprowadzenie do programowania obiektowego. Pojęcie struktury i klasy. Spotkanie 03 Dr inż. Dariusz JĘDRZEJCZYK Tematyka wykładu Idea programowania obiektowego Definicja
Informatyka I. Klasy i obiekty. Podstawy programowania obiektowego. dr inż. Andrzej Czerepicki. Politechnika Warszawska Wydział Transportu 2018
Informatyka I Klasy i obiekty. Podstawy programowania obiektowego dr inż. Andrzej Czerepicki Politechnika Warszawska Wydział Transportu 2018 Plan wykładu Pojęcie klasy Deklaracja klasy Pola i metody klasy
Dziedziczenie. Streszczenie Celem wykładu jest omówienie tematyki dziedziczenia klas. Czas wykładu 45 minut.
Dziedziczenie Streszczenie Celem wykładu jest omówienie tematyki dziedziczenia klas. Czas wykładu 45 minut. Rozpatrzmy przykład przedstawiający klasy Student oraz Pracownik: class Student class Pracownik
Wprowadzenie do programowania w języku Visual Basic. Podstawowe instrukcje języka
Wprowadzenie do programowania w języku Visual Basic. Podstawowe instrukcje języka 1. Kompilacja aplikacji konsolowych w środowisku programistycznym Microsoft Visual Basic. Odszukaj w menu startowym systemu
Kurs programowania. Wykład 1. Wojciech Macyna. 3 marca 2016
Wykład 1 3 marca 2016 Słowa kluczowe języka Java abstract, break, case, catch, class, const, continue, default, do, else, enum, extends, final, finally, for, goto, if, implements, import, instanceof, interface,
Programowanie współbieżne Wykład 8 Podstawy programowania obiektowego. Iwona Kochaoska
Programowanie współbieżne Wykład 8 Podstawy programowania obiektowego Iwona Kochaoska Programowanie Obiektowe Programowanie obiektowe (ang. object-oriented programming) - metodyka tworzenia programów komputerowych,
Java: kilka brakujących szczegółów i uniwersalna nadklasa Object
Java: kilka brakujących szczegółów i uniwersalna nadklasa Object Programowanie w językach wysokiego poziomu mgr inż. Anna Wawszczak PLAN WYKŁADU Konstrukcja obiektów Niszczenie obiektów i zwalnianie zasobów
Programowanie strukturalne. Opis ogólny programu w Turbo Pascalu
Programowanie strukturalne Opis ogólny programu w Turbo Pascalu STRUKTURA PROGRAMU W TURBO PASCALU Program nazwa; } nagłówek programu uses nazwy modułów; } blok deklaracji modułów const } blok deklaracji
Podstawy programowania. Wykład Funkcje. Krzysztof Banaś Podstawy programowania 1
Podstawy programowania. Wykład Funkcje Krzysztof Banaś Podstawy programowania 1 Programowanie proceduralne Pojęcie procedury (funkcji) programowanie proceduralne realizacja określonego zadania specyfikacja
Platforma.NET laboratorium 1. Visual Basic.NET podstawowe elementy języka. Wykonanie warunkowe If End If
Platforma.NET laboratorium 1 Prowadzący: mgr inż. Tomasz Jaworski Strona WWW: http://tjaworski.kis.p.lodz.pl/ Visual Basic.NET podstawowe elementy języka Poniżej przedstawiono podstawowe instrukcje sterujące
2. Kliknij Insert->Userform. Jeżeli Toolbox nie pojawi się automatycznie, kliknij View -> Toolbox. Otrzymany widok powinien być jak poniżej.
Formularze VBA Przykład1 INTERAKTYWNY FORMULARZ Program tworzący interaktywny formularz. Objaśnienie: w dowolnym momencie można wprowadzić wartość w polu tekstowym ID, Excel VBA wczytuje odpowiedni rekord.
Technologie obiektowe
WYKŁAD dr inż. Paweł Jarosz Instytut Informatyki Politechnika Krakowska mail: pjarosz@pk.edu.pl LABORATORIUM dr inż. Paweł Jarosz (3 grupy) mgr inż. Piotr Szuster (3 grupy) warunki zaliczenia Obecność
Oracle PL/SQL. Paweł Rajba.
Paweł Rajba pawel@ii.uni.wroc.pl http://www.kursy24.eu/ Zawartość modułu 8 Wprowadzenie Definiowanie typu obiektowego Porównywanie obiektów Tabele z obiektami Operacje DML na obiektach Dziedziczenie -
Interfejsy. Programowanie obiektowe. Paweł Rogaliński Instytut Informatyki, Automatyki i Robotyki Politechniki Wrocławskiej
Programowanie obiektowe Interfejsy Paweł Rogaliński Instytut Informatyki, Automatyki i Robotyki Politechniki Wrocławskiej pawel.rogalinski pwr.wroc.pl Interfejsy Autor: Paweł Rogaliński Instytut Informatyki,
Materiały pomocnicze do zajęć z przedmiotu Projekt ADP
Dr Janusz Górczyński Materiały pomocnicze do zajęć z przedmiotu Projekt ADP Czym jest projekt ADP? Projekt Microsoft Access (.adp) jest typem pliku programu Access, który zapewnia skuteczny dostęp w trybie
Wprowadzenie do programowania w VBA
Wprowadzenie do programowania w VBA Spis treści Struktura programu... 1 Typy danych... 2 Deklaracja zmiennych i stałych... 2 Deklaracja tablic... 3 Instrukcja przypisania... 3 Wprowadzanie danych... 3
Klasy i obiekty cz II
Materiał pomocniczy do kursu Podstawy programowania Autor: Grzegorz Góralski ggoralski.com Klasy i obiekty cz II Hermetyzacja, mutatory, akcesory, ArrayList Rozwijamy aplikację Chcemy, aby obiekty klasy
Programowanie obiektowe - 1.
Programowanie obiektowe - 1 Mariusz.Masewicz@cs.put.poznan.pl Programowanie obiektowe Programowanie obiektowe (ang. object-oriented programming) to metodologia tworzenia programów komputerowych, która
PHP: bloki kodu, tablice, obiekty i formularze
1 PHP: bloki kodu, tablice, obiekty i formularze SYSTEMY SIECIOWE Michał Simiński 2 Bloki kodu Blok if-else Switch Pętle Funkcje Blok if-else 3 W PHP blok if i blok if-else wyglądają tak samo i funkcjonują
DIAGRAMY SYNTAKTYCZNE JĘZYKA TURBO PASCAL 6.0
Uwaga: DIAGRAMY SYNTAKTYCZNE JĘZYKA TURBO PASCAL 6.0 1. Zostały pominięte diagramy: CYFRA, CYFRA SZESNASTKOWA, ZNAK i LITERA. Nie została uwzględniona możliwość posługiwania się komentarzami. 2. Brakuje
Programowanie obiektowe
Programowanie obiektowe Wykład 2: Wstęp do języka Java 3/4/2013 S.Deniziak: Programowanie obiektowe - Java 1 Cechy języka Java Wszystko jest obiektem Nie ma zmiennych globalnych Nie ma funkcji globalnych
Klasy cd. Struktury Interfejsy Wyjątki
Klasy cd. Struktury Interfejsy Wyjątki Struktury Struktura pozwala na zdefiniowanie typu danych, który nie charakteryzuje się zbyt złożoną funkcjonalnością (np. punkt, kolor, etc). Do definiowania struktury
Typy klasowe (klasy) 1. Programowanie obiektowe. 2. Założenia paradygmatu obiektowego:
Typy klasowe (klasy) 1. Programowanie obiektowe Programowanie obiektowe (ang. object-oriented programming) to metodologia tworzenia programów komputerowych, która definiuje programy za pomocą obiektów
Ćwiczenie laboratoryjne. Oprogramowanie i badanie stosu lub kolejki w środowisku Visual Basic 2005
Ćwiczenie laboratoryjne Oprogramowanie i badanie stosu lub kolejki w środowisku Visual Basic 2005 Tematy ćwiczenia realizacja stosu lub kolejki dla tablicowej lub listowej reprezentacji. operacje na stosie
Enkapsulacja, dziedziczenie, polimorfizm
17 grudnia 2008 Spis treści I Enkapsulacja 1 Enkapsulacja 2 Spis treści II Enkapsulacja 3 Czym jest interfejs Jak definuje się interfejs? Rozszerzanie interfejsu Implementacja interfejsu Częściowa implementacja
Informacje ogólne. Karol Trybulec p-programowanie.pl 1. 2 // cialo klasy. class osoba { string imie; string nazwisko; int wiek; int wzrost;
Klasy w C++ są bardzo ważnym narzędziem w rękach programisty. Klasy są fundamentem programowania obiektowego. Z pomocą klas będziesz mógł tworzyć lepszy kod, a co najważniejsze będzie on bardzo dobrze
Obiekt klasy jest definiowany poprzez jej składniki. Składnikami są różne zmienne oraz funkcje. Składniki opisują rzeczywisty stan obiektu.
Zrozumienie funkcji danych statycznych jest podstawą programowania obiektowego. W niniejszym artykule opiszę zasadę tworzenia klas statycznych w C#. Oprócz tego dowiesz się czym są statyczne pola i metody
Techniki programowania INP001002Wl rok akademicki 2018/19 semestr letni. Wykład 3. Karol Tarnowski A-1 p.
Techniki programowania INP001002Wl rok akademicki 2018/19 semestr letni Wykład 3 Karol Tarnowski karol.tarnowski@pwr.edu.pl A-1 p. 411B Plan prezentacji Abstrakcja funkcyjna Struktury Klasy hermetyzacja
C++ - przeciążanie operatorów. C++ - przeciążanie operatorów. C++ - przeciążanie operatorów. C++ - przeciążanie operatorów
Operatory są elementami języka C++. Istnieje zasada, że z elementami języka, takimi jak np. słowa kluczowe, nie można dokonywać żadnych zmian, przeciążeń, itp. PRZECIĄŻANIE OPERATORÓW Ale dla operatorów
Ćwiczenie VB3.4 Struktura Try...Catch, obiekt Err, metoda Err.Raise (Strukturalna obsługa wyjątków)
Ćwiczenie VB3.4 Struktura..., obiekt Err, metoda Err.Raise (Strukturalna obsługa wyjątków) Jeśli wpiszemy do okna tekstowego zamiast cyfr litery (np. abc), a następnie spróbujemy ten ciąg znaków przekonwertować
Informatyka I. Typy danych. Operacje arytmetyczne. Konwersje typów. Zmienne. Wczytywanie danych z klawiatury. dr hab. inż. Andrzej Czerepicki
Informatyka I Typy danych. Operacje arytmetyczne. Konwersje typów. Zmienne. Wczytywanie danych z klawiatury. dr hab. inż. Andrzej Czerepicki Politechnika Warszawska Wydział Transportu 2019 1 Plan wykładu
Przykład powyżej pokazuje, że w zapytaniu można umieszczać funkcje zarówno zdefiniowane w ramach środowiska, jak również własne.
LINQ w Microsoft Visual Basic 'zapytanie pobierające wszystkie liczby z kolekcji 'zmienna zapytanie jest typu: System.Collections.Generic.IEnumerable(Of Integer) Dim zapytanie = From wiersz In liczby 'lub
Przychodnia 0. Stwórz projekt aplikacja konsolowa lub WPF (przemyśl wybór, bo zmiana może być czasochłonna). 1. Stwórz abstrakcyjną klasę Osoba.
Przychodnia 0. Stwórz projekt aplikacja konsolowa lub WPF (przemyśl wybór, bo zmiana może być czasochłonna). 1. Stwórz abstrakcyjną klasę Osoba. W tej klasie wykonaj następujące czynności: a) dodaj pole
Język JAVA podstawy. Wykład 4, część 1. Jacek Rumiński. Politechnika Gdańska, Inżynieria Biomedyczna
Język JAVA podstawy Wykład 4, część 1 1 Język JAVA podstawy Plan wykładu: 1. Podstawy modelowania obiektowego 2. Konstruktory 3. Dziedziczenie, związki pomiędzy klasami, UML 4. Polimorfizm 5. Klasy abstrakcyjne
Podstawy programowania. Ćwiczenie. Pojęcia bazowe. Języki programowania. Środowisko programowania Visual Studio
Podstawy programowania Ćwiczenie Pojęcia bazowe. Języki programowania. Środowisko programowania Visual Studio Tematy ćwiczenia algorytm, opis języka programowania praca ze środowiskiem, formularz, obiekty
Język programowania. Andrzej Bobyk http://www.alfabeta.lublin.pl. www.alfabeta.lublin.pl/jp/
Język programowania Andrzej Bobyk http://www.alfabeta.lublin.pl www.alfabeta.lublin.pl/jp/ Literatura K. Reisdorph: Delphi 6 dla każdego. Helion, Gliwice 2001 A. Grażyński, Z. Zarzycki: Delphi 7 dla każdego.
Instrukcja laboratoryjna nr.4
Języki programowania na platformie.net cz.2 2016/17 Instrukcja laboratoryjna nr.4 Język Visual Basic for.net Prowadzący: Tomasz Goluch Wersja: 3.1 I. Współpraca Visual Basic z C# Cel: Wykorzystanie w kodzie
JAVA W SUPER EXPRESOWEJ PIGUŁCE
JAVA W SUPER EXPRESOWEJ PIGUŁCE Obiekt Obiekty programowe to zbiór własności i zachowań (zmiennych i metod). Podobnie jak w świecie rzeczywistym obiekty posiadają swój stan i zachowanie. Komunikat Wszystkie
Obszar statyczny dane dostępne w dowolnym momencie podczas pracy programu (wprowadzone słowem kluczowym static),
Tworzenie obiektów Dostęp do obiektów jest realizowany przez referencje. Obiekty w języku Java są tworzone poprzez użycie słowa kluczowego new. String lan = new String( Lancuch ); Obszary pamięci w których
Programowanie obiektowe
Programowanie obiektowe Wykład 2 Marcin Młotkowski 4 marca 2015 Plan wykładu 1 2 3 4 5 Marcin Młotkowski Programowanie obiektowe 2 / 47 Krótki opis C Obiektowy, z kontrolą typów; automatyczne odśmiecanie;
Zadanie. Menu Plik niech posiada dwie pozycje: Tekstowy i Excel, a każda z nich niech posiada dwie pozycje Otwórz i Zapisz, patrz rys. 2.
Zadanie Wykonać aplikację posiadającą możliwość komunikowania się (zapis/odczyt) pomiędzy obiektem DataGridView, a plikiem tekstowym i plikiem MS Excel. Niech formularz ma postać jak na rys. 1. Rysunek
Multimedia JAVA. Historia
Multimedia JAVA mgr inż. Piotr Odya piotrod@sound.eti.pg.gda.pl Historia 1990 rozpoczęcie prac nad nowym systemem operacyjnym w firmie SUN, do jego tworzenia postanowiono wykorzystać nowy język programowania
Programowanie w Sieci Internet Blok 2 - PHP. Kraków, 09 listopada 2012 mgr Piotr Rytko Wydział Matematyki i Informatyki
Programowanie w Sieci Internet Blok 2 - PHP Kraków, 09 listopada 2012 mgr Piotr Rytko Wydział Matematyki i Informatyki Co dziś będziemy robić Podstawy podstaw, czyli małe wprowadzenie do PHP, Podstawy
UML a kod. C++, Java i C#
UML a kod C++, Java i C# UML a kod w C++ i Javie Projektowanie oprogramowania! Dokumentowanie oprogramowania Diagramy przypadków użycia Klasy użytkowników i wykorzystywane funkcje Mogą sugerować podział
Podstawy programowania w języku Visual Basic dla Aplikacji (VBA)
Podstawy programowania w języku Visual Basic dla Aplikacji (VBA) Instrukcje Język Basic został stworzony w 1964 roku przez J.G. Kemeny ego i T.F. Kurtza z Uniwersytetu w Darthmouth (USA). Nazwa Basic jest