W serii kilkunastu kroków przedstawione jest projektowanie klasy Ulamek od deklaracji jej pól i metod, aż do omówienia podstaw dziedziczenia. Klasa służąca jako przykład to implementacja ułamka zwykłego.
Uwaga! (C++)
Kod klasy ulamek pisany jest w czystym C++ i jest w pełni przenaszalny (można
zastosować inne kompilatory np. gcc, także pod Linuxem). Przykłady
ilustrujące wykorzystanie opisywanej tu klasy korzystają z funkcji WinAPI
ShowMessage() i są napisane w C++ Builder 6. Funkcję tą można z powodzeniem zastąpić przekazywaniem tekstu do stanardowego strumienia wyjścia. Tzn. wszędzie tam, gdzie znajduje się jej wywołanie, np.:
ShowMessage((AnsiString)"a: "+licznik+"/"+mianownik);
należy umieścić:
srd::cout << "a: " << licznik << "/" << mianownik << "\n";
W tym przypadku należy pamiętać o uwzględnieniu odpowiedniej biblioteki: #include <iostream>
Wyjątkiem jest ostatnia klasa, która korzysta z AnsiString, który nie jest elementem standardowym C++.
Uwaga! (Delphi)
Kod klasy Ulamek wykorzystuje elementy Object Pascala, które zostały wprowadzone od wersji 6 (m.in przeciążanie metod). W przykładach zostały podane metody związane ze zdarzeniem Button1.OnClick. Mimot to bez większych kłopotów, po usunięciu niektórych elementów kod klasy powinien się kompilować także w Turbo Pascalu.
Uwaga! (Java)
javac klasy\*.javaAplikację można teraz uruchomić wpisując:
java klasy.Application1Można się posunąć o krok dalej i stworzyć pojedynczy plik wykonywalny jar. Należy przygotować prosty plik (np. "klasyManifest") zawierający nazwę wykonywalnej klasy w jednej linii zakończonej znakiem końca linii (w naszym przypadku linia ta powinna zawierać: Main-Class: klasy.Application1). Teraz można spakować skompilowane klasy poleceniem:
jar cmf klasyManifest klasy.jar klasy\*.classi uruchomić je klikając w Windows Explorerze dwukrotnie myszką na plik klasy.jar lub wpisując:
java -jar klasy.jar
Uwaga!
W przypadku wszystkich przykładów najlepiej na formie umieścić przycisk i
wkleić kod do ich metod zdarzeniowych związanych z jego przyciśnięciem.
C++
class ulamek { private: int licznik, mianownik; }; |
Java (plik Ulamek.java)
public class Ulamek { private int licznik,mianownik; } |
Delphi
interface type ulamek = class private licznik,mianownik :Integer; end; |
C#
public class Ulamek { private int licznik,mianownik; } |
Przykład kodu:
ulamek a; ulamek* b=new ulamek(); delete b; |
Przykład kodu:
Ulamek a=new Ulamek(); |
Przykład kodu:
procedure TForm1.Button1Click(Sender: TObject); var a :Ulamek; begin a:=Ulamek.Create; a.Free; end; |
Przykład kodu:
Ulamek a=new Ulamek(); |
Uwagi!
C++
class ulamek { private: int licznik, mianownik; public: bool set(int alicznik,int amianownik) { if (amianownik==0) return false; licznik=alicznik; mianownik=amianownik; return true; } void get(int& rlicznik,int& rmianownik) const { rlicznik=licznik; rmianownik=mianownik; } void get(int* plicznik,int* pmianownik) const { *plicznik=licznik; *pmianownik=mianownik; } }; |
Java package klasy; /** * <p>Title: Ulamek</p> * <p>Description: Przykladowa klasa Ulamek</p> * <p>Copyright: Copyright (c) Jacek Matulewski 2003</p> * <p>Company: </p> * @author unascribed * @version 1.0 */ public class Ulamek { private int licznik,mianownik; public boolean set(int alicznik,int amianownik) { if (amianownik==0) return false; licznik=alicznik; mianownik=amianownik; return true; } public void get(int[] arg) { arg[0]=licznik; arg[1]=mianownik; } public int[] get() { int[] wynik=new int[2]; wynik[0]=licznik; wynik[1]=mianownik; return wynik; } } |
Delphi
unit _ulamek; interface type Ulamek = class private licznik :Integer; mianownik :Integer; public function SetValues(const alicznik, amianownik :Integer) :Boolean; procedure GetValues(var rlicznik :Integer; var rmianownik :Integer); overload; procedure GetValues(plicznik, pmianownik :PInteger); overload; end; implementation function Ulamek.SetValues(const alicznik, amianownik :Integer) :Boolean; begin if amianownik=0 then begin SetValues:=False; Exit; end; licznik:=alicznik; mianownik:=amianownik; SetValues:=True; end; procedure Ulamek.GetValues(var rlicznik :Integer; var rmianownik :Integer); begin rlicznik:=licznik; rmianownik:=mianownik; end; procedure Ulamek.GetValues(plicznik :PInteger; pmianownik :PInteger); begin plicznik^:=licznik; pmianownik^:=mianownik; end; end. |
C#
public class Ulamek { private int licznik,mianownik; public bool set(int alicznik,int amianownik) { if (amianownik==0) return false; licznik=alicznik; mianownik=amianownik; return true; } public void get(out int rlicznik,out int rmianownik) { rlicznik=licznik; rmianownik=mianownik; } public void get(int[] arg) { arg[0]=licznik; arg[1]=mianownik; } public int[] get() { int[] wynik=new int[2]; wynik[0]=licznik; wynik[1]=mianownik; return wynik; } } |
Przykład kodu:
ulamek a; if (a.set(1,2)) ShowMessage("a,1: OK"); else ShowMessage("a,1: Blad"); if (a.set(1,0)) ShowMessage("a,2: OK"); else ShowMessage("a,2: Blad"); ulamek* b=new ulamek(); if (b->set(3,4)) ShowMessage("b: OK"); else ShowMessage("b: Blad"); int licznik,mianownik; a.get(licznik,mianownik); ShowMessage((AnsiString)"a: "+licznik+"/"+mianownik); (*b).get(&licznik,&mianownik); //b->get() == (*b).get() ShowMessage((AnsiString)"b: "+licznik+"/"+mianownik); delete b; |
Przykład kodu: Ulamek a=new Ulamek(); if (a.set(1,2)) list1.add("a,1: OK"); else list1.add("a,1: Blad"); if (a.set(1,0)) list1.add("a,2: OK"); else list1.add("a,2: Blad"); int[] licznik_mianownik=new int[2]; a.get(licznik_mianownik); list1.add("a: "+String.valueOf(licznik_mianownik[0])+"/"+ String.valueOf(licznik_mianownik[1])); licznik_mianownik=a.get(); list1.add("a: "+String.valueOf(licznik_mianownik[0])+"/"+ String.valueOf(licznik_mianownik[1])); |
Przykład kodu:
procedure TForm1.Button1Click(Sender: TObject); var a,b :Ulamek; licznik,mianownik :Integer; begin a:=Ulamek.Create; if a.SetValues(1,2) then ShowMessage('a,1: OK') else ShowMessage('a,1: Blad'); if a.SetValues(1,0) then ShowMessage('a,2: OK') else ShowMessage('a,2: Blad'); b:=Ulamek.Create; if b.SetValues(3,4) then ShowMessage('b: OK') else ShowMessage('b: Blad'); a.GetValues(licznik,mianownik); ShowMessage('a: '+IntToStr(licznik)+'/'+IntToStr(mianownik)); b.GetValues(@licznik,@mianownik); ShowMessage('b: '+IntToStr(licznik)+'/'+IntToStr(mianownik)); a.Free; b.Free; end; |
Przykład kodu:
Ulamek a=new Ulamek(); if (a.set(1,2)) MessageBox.Show("a,1: OK"); else MessageBox.Show("a,1: Blad"); if (a.set(1,0)) MessageBox.Show("a,2: OK"); else MessageBox.Show("a,2: Blad"); int licznik=0,mianownik=0; a.get(out licznik,out mianownik); MessageBox.Show("a: "+licznik+"/"+mianownik); int[] licznik_mianownik=new int[2]; licznik_mianownik=a.get(); MessageBox.Show("a: "+licznik_mianownik[0]+"/"+licznik_mianownik[1]); |
unsafe public void get(int* plicznik,int* pmianownik) { *plicznik=licznik; *pmianownik=mianownik; }
Najbardziej konsekwętnie obsługa wyjątków przeprowadzona została w Javie, gdzie metoda przesyłająca wyjątek musi deklarować taką możliwość w nagłówku, za nazwą i argumentami, a kompilator pozwala na wywołanie takiej metody tylko po otoczeniu przez polecenia przechwytujące wyjątki.
Uwaga!
Po przesłaniu wyjątku i wykonaniu bloku instrukcji zawartych w catch program nie wraca do linii następującej po wystopięniu wyjątku.
C++
void set(int alicznik,int amianownik) { if (amianownik==0) throw "Ulamek: Blad #1"; licznik=alicznik; mianownik=amianownik; } |
Java public void set(int alicznik,int amianownik) throws Exception { if (amianownik==0) throw new Exception("Ulamek: Blad #1"); licznik=alicznik; mianownik=amianownik; } |
Pascal
procedure Ulamek.SetValues(const alicznik, amianownik :Integer); begin if amianownik=0 then raise Exception.Create('Ulamek: Blad #1'); licznik:=alicznik; mianownik:=amianownik; end; |
C# public void set(int alicznik,int amianownik) { if (amianownik==0) throw new Exception("Ulamek: Blad #1"); licznik=alicznik; mianownik=amianownik; } |
Przykład kodu:
ulamek* c=new ulamek(); try { c->set(1,0); ShowMessage("c: OK"); } catch(char* E) {ShowMessage(E);} int licznik,mianownik; c->get(licznik,mianownik); ShowMessage((AnsiString)"c: "+licznik+"/"+mianownik); delete c; |
Przykład kodu: Ulamek c=new Ulamek(); try { c.set(1,0); list1.add("c: OK"); } catch(Exception E) { list1.add(E.getMessage()); } int[] licznik_mianownik=new int[2]; c.get(licznik_mianownik); list1.add("c: "+String.valueOf(licznik_mianownik[0])+"/"+ String.valueOf(licznik_mianownik[1])); |
Przykład kodu:
procedure TForm1.Button1Click(Sender: TObject); var c :Ulamek; licznik,mianownik :Integer; begin c:=Ulamek.Create; try c.SetValues(1,0); ShowMessage('c: OK'); except on E: Exception do ShowMessage(E.Message); end; c.GetValues(licznik,mianownik); ShowMessage('c: '+IntToStr(licznik)+'/'+IntToStr(mianownik)); c.Free; end; |
Przykład kodu: Ulamek c=new Ulamek(); try //Obsluga wyjatkow w C# nie jest obowiazkowa { MessageBox.Show("Pojawi się wyjątek, bo mianownik ustalam na 0"); c.set(1,0); MessageBox.Show("c: OK"); } catch(Exception exc) { MessageBox.Show(exc.Message); } int licznik,mianownik; c.get(out licznik,out mianownik); MessageBox.Show("c: "+licznik+"/"+mianownik); |
C++
class ulamek { private: int licznik, mianownik; public: ulamek(int alicznik,int amianownik) { set(alicznik,amianownik); } void set(int alicznik,int amianownik) { if (amianownik==0) throw "Ulamek: Blad #1"; licznik=alicznik; mianownik=amianownik; } void get(int& rlicznik,int& rmianownik) const { rlicznik=licznik; rmianownik=mianownik; } void get(int* plicznik,int* pmianownik) const { *plicznik=licznik; *pmianownik=mianownik; } }; |
Java package klasy; public class Ulamek { private int licznik,mianownik; public Ulamek(int alicznik,int amianownik) throws Exception { try { set(alicznik,amianownik); } catch(Exception E) { throw E; } } public void set(int alicznik,int amianownik) throws Exception { if (amianownik==0) throw new Exception("Ulamek: Blad #1"); licznik=alicznik; mianownik=amianownik; } public void get(int[] arg) { arg[0]=licznik; arg[1]=mianownik; } public int[] get() { int[] wynik=new int[2]; wynik[0]=licznik; wynik[1]=mianownik; return wynik; } } |
Pascal
unit _ulamek; interface uses SysUtils; type Ulamek = class private licznik :Integer; mianownik :Integer; public constructor Create(const alicznik, amianownik :Integer); procedure SetValues(const alicznik, amianownik :Integer); procedure GetValues(var rlicznik :Integer; var rmianownik :Integer); overload; procedure GetValues(plicznik, pmianownik :PInteger); overload; end; implementation constructor Ulamek.Create(const alicznik, amianownik :Integer); begin inherited Create; //TObject.Create() SetValues(alicznik,amianownik); end; procedure Ulamek.SetValues(const alicznik, amianownik :Integer); begin if amianownik=0 then raise Exception.Create('Ulamek: Blad #1'); licznik:=alicznik; mianownik:=amianownik; end; procedure Ulamek.GetValues(var rlicznik :Integer; var rmianownik :Integer); begin rlicznik:=licznik; rmianownik:=mianownik; end; procedure Ulamek.GetValues(plicznik :PInteger; pmianownik :PInteger); begin plicznik^:=licznik; pmianownik^:=mianownik; end; end. |
C# public class Ulamek { private int licznik,mianownik; public Ulamek(int alicznik,int amianownik) { set(alicznik,amianownik); } public void set(int alicznik,int amianownik) { if (amianownik==0) throw new Exception("Ulamek: Blad #1"); licznik=alicznik; mianownik=amianownik; } public void get(out int rlicznik,out int rmianownik) { rlicznik=licznik; rmianownik=mianownik; } public void get(int[] arg) { arg[0]=licznik; arg[1]=mianownik; } public int[] get() { int[] wynik=new int[2]; wynik[0]=licznik; wynik[1]=mianownik; return wynik; } } |
Przykład kodu:
ulamek a(1,2); ulamek* b=new ulamek(3,4); delete b; |
Przykład kodu: Ulamek a=null,b=null,c=null; try { a=new Ulamek(1,2); b=new Ulamek(3,4); c=new Ulamek(1,0); } catch(Exception E) { list1.add(E.getMessage()); } int[] licznik_mianownik=new int[2]; a.get(licznik_mianownik); list1.add("a: "+String.valueOf(licznik_mianownik[0])+"/"+ String.valueOf(licznik_mianownik[1])); b.get(licznik_mianownik); list1.add("b: "+String.valueOf(licznik_mianownik[0])+"/"+ String.valueOf(licznik_mianownik[1])); c.get(licznik_mianownik); list1.add("c: "+String.valueOf(licznik_mianownik[0])+"/"+ String.valueOf(licznik_mianownik[1])); |
Przykład kodu:
procedure TForm1.Button1Click(Sender: TObject); var a :Ulamek; licznik,mianownik :Integer; begin a:=Ulamek.Create(1,2); a.Free; end; |
Przykład kodu: Ulamek a=new Ulamek(1,2); int licznik,mianownik; a.get(out licznik,out mianownik); MessageBox.Show("a: "+licznik+"/"+mianownik); |
Uwaga!
public Ulamek() throws Exception { this(0,1); }
procedure IntToUlamek(const liczba :Integer; var RUlamek :Ulamek); begin if Assigned(RUlamek) then RUlamek.SetValues(liczba,1); end;lub alternatywnie
function IntToUlamek(const liczba :Integer) :Ulamek; begin IntToUlamek:=Ulamek.Create(liczba,1); end;
C++
class ulamek_exception { private: char* message; public: ulamek_exception(char* amessage) {message=amessage;}; char* what() const {return message;}; }; class ulamek { private: int licznik, mianownik; public: ulamek(int alicznik=0,int amianownik=1) { set(alicznik,amianownik); } void set(int alicznik,int amianownik) { if (amianownik==0) throw ulamek_exception("Ulamek: Blad #1"); licznik=alicznik; mianownik=amianownik; } void get(int& rlicznik,int& rmianownik) const { rlicznik=licznik; rmianownik=mianownik; } void get(int* plicznik,int* pmianownik) const { *plicznik=licznik; *pmianownik=mianownik; } }; |
Java package klasy; class Ulamek_Exception extends Exception { private String message; public Ulamek_Exception(String amessage) {message=amessage;} public String what() {return message;} } public class Ulamek { private int licznik,mianownik; public Ulamek(int alicznik,int amianownik) throws Ulamek_Exception { try { set(alicznik,amianownik); } catch(Ulamek_Exception E) { throw E; } } public void set(int alicznik,int amianownik) throws Ulamek_Exception { if (amianownik==0) throw new Ulamek_Exception("Ulamek: Blad #1"); licznik=alicznik; mianownik=amianownik; } public void int[] arg) { arg[0]=licznik; arg[1]=mianownik; } public int[] get() { int[] wynik=new int[2]; wynik[0]=licznik; wynik[1]=mianownik; return wynik; } } |
Pascal
unit _ulamek; interface uses SysUtils; type Ulamek_Exception = class(Exception) private Message :String; public constructor Create(const AMessage :String); function What :String; end; Ulamek = class private licznik :Integer; mianownik :Integer; public constructor Create(const alicznik :Integer =0; const amianownik :Integer =1); procedure SetValues(const alicznik, amianownik :Integer); procedure GetValues(var rlicznik :Integer; var rmianownik :Integer); overload; procedure GetValues(plicznik, pmianownik :PInteger); overload; end; function IntToUlamek(const liczba :Integer) :Ulamek; implementation constructor Ulamek_Exception.Create(const AMessage :String); begin Message:=AMessage; end; function Ulamek_Exception.What :String; begin What:=Message; end; constructor Ulamek.Create(const alicznik :Integer =0; const amianownik :Integer =1); begin inherited Create; SetValues(alicznik,amianownik); end; procedure Ulamek.SetValues(const alicznik, amianownik :Integer); begin if amianownik=0 then raise Ulamek_Exception.Create('Ulamek: Blad #1'); licznik:=alicznik; mianownik:=amianownik; end; procedure Ulamek.GetValues(var rlicznik :Integer; var rmianownik :Integer); begin rlicznik:=licznik; rmianownik:=mianownik; end; procedure Ulamek.GetValues(plicznik :PInteger; pmianownik :PInteger); begin plicznik^:=licznik; pmianownik^:=mianownik; end; //FUNKCJA KONWERTUJACA function IntToUlamek(const liczba :Integer) :Ulamek; begin IntToUlamek:=Ulamek.Create(liczba,1); end; end. |
C# class Ulamek_Exception : Exception { private String message; public Ulamek_Exception(String amessage) {message=amessage;} public String what() {return message;} } public class Ulamek { private int licznik,mianownik; public Ulamek(int alicznik,int amianownik) { set(alicznik,amianownik); } public void set(int alicznik,int amianownik) { if (amianownik==0) throw new Ulamek_Exception("Ulamek: Blad #1"); licznik=alicznik; mianownik=amianownik; } public void get(out int rlicznik,out int rmianownik) { rlicznik=licznik; rmianownik=mianownik; } public void get(int[] arg) { arg[0]=licznik; arg[1]=mianownik; } public int[] get() { int[] wynik=new int[2]; wynik[0]=licznik; wynik[1]=mianownik; return wynik; } } |
Przykład kodu:
ulamek* c=NULL; try { c=new ulamek(1,0); } catch(ulamek_exception& E) { ShowMessage(E.what()); c=NULL; } if (c!=NULL) { c->get(licznik,mianownik); ShowMessage((AnsiString)"c: "+licznik+"/"+mianownik); delete c; } |
Przykład kodu: Ulamek a=null,b=null,c=null; try { a=new Ulamek(1,2); b=new Ulamek(3,4); c=new Ulamek(1,0); } catch(Ulamek_Exception E) { list1.add(E.what()); } int[] licznik_mianownik=new int[2]; a.get(licznik_mianownik); list1.add("a: "+String.valueOf(licznik_mianownik[0])+"/"+ String.valueOf(licznik_mianownik[1])); b.get(licznik_mianownik); list1.add("b: "+String.valueOf(licznik_mianownik[0])+"/"+ String.valueOf(licznik_mianownik[1])); c.get(licznik_mianownik); list1.add("c: "+String.valueOf(licznik_mianownik[0])+"/"+ String.valueOf(licznik_mianownik[1])); |
Przykład kodu:
procedure TForm1.Button1Click(Sender: TObject); var c :Ulamek; begin try c:=Ulamek.Create(1,0); except on E :Ulamek_Exception do ShowMessage(E.What); end; end; |
Przykład kodu: Ulamek a=null,b=null,c=null; try { a=new Ulamek(1,2); b=new Ulamek(3,4); c=new Ulamek(1,0); } catch(Ulamek_Exception E) { MessageBox.Show(E.what()); } int licznik,mianownik; a.get(out licznik,out mianownik); MessageBox.Show("a: "+licznik+"/"+mianownik); b.get(out licznik,out mianownik); MessageBox.Show("b: "+licznik+"/"+mianownik); c.get(out licznik,out mianownik); MessageBox.Show("c: "+licznik+"/"+mianownik); |
Uwaga!
Po przesłaniu wyjątku program nie wraca do dalszych linii następujących po
throw.
W Javie zastąpiłem przykład konstruktora kopiującego, który w tym języku nie występuje, przykładem wykorzystania metody clone(), który przejmuje niektóre jego funkcje. Podobnie w C#, w której zdefiniowana została metoda Clone().
C++
class ulamek { private: int licznik, mianownik; public: ulamek(int alicznik=0,int amianownik=1) { set(alicznik,amianownik); } ulamek(const ulamek& aulamek) { aulamek.get(licznik,mianownik); } void set(int alicznik,int amianownik) { if (amianownik==0) throw "Ulamek: Blad #1"; licznik=alicznik; mianownik=amianownik; } void get(int& rlicznik,int& rmianownik) const { rlicznik=licznik; rmianownik=mianownik; } void get(int* plicznik,int* pmianownik) const { *plicznik=licznik; *pmianownik=mianownik; } }; |
Java package klasy; public class Ulamek implements Cloneable { private int licznik,mianownik; public Ulamek(int alicznik,int amianownik) throws Exception { try { set(alicznik,amianownik); } catch(Exception E) { throw E; } } public Object clone() throws CloneNotSupportedException { Object wynik=null; try { wynik=super.clone(); } catch(CloneNotSupportedException E) { throw E; } return wynik; } public void set(int alicznik,int amianownik) throws Exception { if (amianownik==0) throw new Exception("Ulamek: Blad #1"); licznik=alicznik; mianownik=amianownik; } public void get(int[] arg) { arg[0]=licznik; arg[1]=mianownik; } public int[] get() { int[] wynik=new int[2]; wynik[0]=licznik; wynik[1]=mianownik; return wynik; } } |
Pascal
|
C# public class Ulamek { private int licznik,mianownik; public Ulamek(int alicznik,int amianownik) { set(alicznik,amianownik); } //cos podobnego do konstruktora copy w C++ public Ulamek(Ulamek aulamek) { int olicznik,omianownik; aulamek.get(out olicznik,out omianownik); set(olicznik,omianownik); } //analog funkcji clone() w Javie public Ulamek Clone() { return new Ulamek(licznik,mianownik); } public void set(int alicznik,int amianownik) { if (amianownik==0) throw new Ulamek_Exception("Ulamek: Blad #1"); licznik=alicznik; mianownik=amianownik; } public void get(out int rlicznik,out int rmianownik) { rlicznik=licznik; rmianownik=mianownik; } public void get(int[] arg) { arg[0]=licznik; arg[1]=mianownik; } public int[] get() { int[] wynik=new int[2]; wynik[0]=licznik; wynik[1]=mianownik; return wynik; } } |
Przykład kodu
ulamek a(1,2); //konstruktor ulamek c(a); //konstruktor copy ulamek b=a; //konstruktor copy a.set(3,4); //zmiana stanu pierwotnego obiektu c=b; //operator przypisania = |
Przykład kodu: Ulamek a=null,b=null,c=null; try { a=new Ulamek(1,2); b=new Ulamek(3,4); c=(Ulamek)a.clone(); a.set(3,4); } catch(CloneNotSupportedException CloneE) { list1.add(CloneE.getMessage()); } catch(Exception E) { list1.add(E.getMessage()); } int[] licznik_mianownik=new int[2]; a.get(licznik_mianownik); list1.add("a: "+String.valueOf(licznik_mianownik[0])+"/"+ String.valueOf(licznik_mianownik[1])); b.get(licznik_mianownik); list1.add("b: "+String.valueOf(licznik_mianownik[0])+"/"+ String.valueOf(licznik_mianownik[1])); c.get(licznik_mianownik); list1.add("c: "+String.valueOf(licznik_mianownik[0])+"/"+ String.valueOf(licznik_mianownik[1])); |
Pascal
|
Przykład kodu: Ulamek a=null,b=null,c=null; try { a=new Ulamek(1,2); c=new Ulamek(a); b=a; a.set(3,4); //c=b; } catch(Ulamek_Exception E) { MessageBox.Show(E.what()); } int licznik,mianownik; a.get(out licznik,out mianownik); MessageBox.Show("a: "+licznik+"/"+mianownik); b.get(out licznik,out mianownik); MessageBox.Show("b: "+licznik+"/"+mianownik); c.get(out licznik,out mianownik); MessageBox.Show("c: "+licznik+"/"+mianownik); |
Uwaga!
Ulamek* a=new Ulamek(1,2); Ulamek* b=new Ulamek(3,4); b=a; a.set(0,1); //odczytanie b pokaze 0/1W tym przypadku wskaźniki a i b wskazują na ten sam obszar w pamięci zajmowany przez obiekt poczatkowo przypisany tylko do wskażnika a. Wszelkie zmiany na *a będą widoczne w *b i odwrotnie.
C++
const ulamek ulamek_zero(0,1); const ulamek ulamek_jeden(1,1); const ulamek ulamek_polowa(1,2); const ulamek ulamek_cwierc(1,4); |
Przykład kodu
ulamek a=ulamek_polowa; ulamek b(ulamek_cwierc); |
Uwaga!
#define ulamek_zero ulamek(0,1) #define ulamek_jeden ulamek(1,1) #define ulamek_polowa ulamek(1,2) #define ulamek_cwierc ulamek(1,4)
constructor Ulamek.Polowa; begin SetValues(1,2); end;
public class Ulamek implements Cloneable { private int licznik,mianownik; public boolean error=false; public static final Ulamek Zero=new Ulamek(0,1); public static final Ulamek Jeden=new Ulamek(1,1); public static final Ulamek Polowa=new Ulamek(1,2); public static final Ulamek Cwierc=new Ulamek(1,4); public Ulamek(int alicznik,int amianownik) //throws Exception { try { set(alicznik,amianownik); } catch(Exception E) { //throw E; error=true; } } //reszta klasyUwaga! Należy jednak być ostrożnym, bo nic nie przeszkadza wykorzystać metody set na takim statycznym polu, żeby zmienić jego stan!
Istnieją dwie możliwości tworzenia operatorów: pierwsza to operator będący elementem klasy (daje to pewne korzyści przy ewentualnym dziedziczeniu), druga to niezależny operator zdefiniowany dla jednego lub dwóch argumentów odpowiedniej klasy. Korzyścią drugiego sposobu jest rozciągnięcie niejawnej konwersji również na pierwszy argument, który w pierwszym przypadku musi być jawnie typu odpowiednij klasy.
W Pascalu i Javie o definiowaniu operatorów nie ma co śnić (jedyny przeciążony operator to + dla klasy String) - wzamian zdefiniujemy funkcje. W Javie funkcje mogą być wyłącznie metodami, tj. muszą być związane z jakąś klasą, ale mogą być metodami statycznymi tj. nie wymagającymi do ich uruchomienia stworzenia obiektu.
C++
ulamek operator *(const ulamek& aulamek1,const ulamek& aulamek2) { int alicznik1=0,amianownik1=1;aulamek1.get(alicznik1,amianownik1); int alicznik2=0,amianownik2=1;aulamek2.get(alicznik2,amianownik2); return ulamek(alicznik1*alicznik2,amianownik1*amianownik2); }; ulamek operator /(const ulamek& aulamek1,const ulamek& aulamek2) { int alicznik1=0,amianownik1=1;aulamek1.get(alicznik1,amianownik1); int alicznik2=0,amianownik2=1;aulamek2.get(alicznik2,amianownik2); return ulamek(alicznik1*amianownik2,amianownik1*alicznik2); }; ulamek operator +(const ulamek& aulamek1,const ulamek& aulamek2) { int alicznik1=0,amianownik1=1;aulamek1.get(alicznik1,amianownik1); int alicznik2=0,amianownik2=1;aulamek2.get(alicznik2,amianownik2); return ulamek(alicznik1*amianownik2+alicznik2*amianownik1,amianownik1*amianownik2); }; ulamek operator -(const ulamek& aulamek1) { int alicznik1=0,amianownik1=1;aulamek1.get(alicznik1,amianownik1); return ulamek(-alicznik1,amianownik1); }; ulamek operator -(const ulamek& aulamek1,const ulamek& aulamek2) { int alicznik1=0,amianownik1=1;aulamek1.get(alicznik1,amianownik1); int alicznik2=0,amianownik2=1;aulamek2.get(alicznik2,amianownik2); return ulamek(alicznik1*amianownik2-alicznik2*amianownik1,amianownik1*amianownik2); }; bool operator <(const ulamek& aulamek1,const ulamek& aulamek2) { int alicznik1=0,amianownik1=1;aulamek1.get(alicznik1,amianownik1); int alicznik2=0,amianownik2=1;aulamek2.get(alicznik2,amianownik2); return (alicznik1/(double)amianownik1)<(alicznik2/(double)amianownik2); }; bool operator >(const ulamek& aulamek1,const ulamek& aulamek2) { int alicznik1=0,amianownik1=1;aulamek1.get(alicznik1,amianownik1); int alicznik2=0,amianownik2=1;aulamek2.get(alicznik2,amianownik2); return (alicznik1/(double)amianownik1)>(alicznik2/(double)amianownik2); }; bool operator ==(const ulamek& aulamek1,const ulamek& aulamek2) { int alicznik1=0,amianownik1=1;aulamek1.get(alicznik1,amianownik1); int alicznik2=0,amianownik2=1;aulamek2.get(alicznik2,amianownik2); return (alicznik1/(double)amianownik1)==(alicznik2/(double)amianownik2); }; |
Java public static Ulamek Prod(Ulamek aulamek1,Ulamek aulamek2) throws Exception { int[] alicznik1_amianownik1=aulamek1.get(); int[] alicznik2_amianownik2=aulamek2.get(); Ulamek wynik=null; try { wynik=new Ulamek(alicznik1_amianownik1[0]*alicznik2_amianownik2[0], alicznik1_amianownik1[1]*alicznik2_amianownik2[1]); } catch(Exception E) {throw E;} return wynik; } public static Ulamek Quot(Ulamek aulamek1,Ulamek aulamek2) throws Exception { int[] alicznik1_amianownik1=aulamek1.get(); int[] alicznik2_amianownik2=aulamek2.get(); Ulamek wynik=null; try { wynik=new Ulamek(alicznik1_amianownik1[0]*alicznik2_amianownik2[1], alicznik1_amianownik1[1]*alicznik2_amianownik2[0]); } catch(Exception E) {throw E;} return wynik; } public static Ulamek Sum(Ulamek aulamek1,Ulamek aulamek2) throws Exception { int[] alicznik1_amianownik1=aulamek1.get(); int[] alicznik2_amianownik2=aulamek2.get(); Ulamek wynik=null; try { wynik=new Ulamek(alicznik1_amianownik1[0]*alicznik2_amianownik2[1] +alicznik1_amianownik1[1]*alicznik2_amianownik2[0], alicznik1_amianownik1[1]*alicznik2_amianownik2[1]); } catch(Exception E) {throw E;} return wynik; } public static Ulamek Revr(Ulamek aulamek1) throws Exception { int[] alicznik1_amianownik1=aulamek1.get(); Ulamek wynik=null; try { wynik=new Ulamek(-alicznik1_amianownik1[0],alicznik1_amianownik1[1]); } catch(Exception E) {throw E;} return wynik; } public static Ulamek Diff(Ulamek aulamek1,Ulamek aulamek2) throws Exception { int[] alicznik1_amianownik1=aulamek1.get(); int[] alicznik2_amianownik2=aulamek2.get(); Ulamek wynik=null; try { wynik=new Ulamek(alicznik1_amianownik1[0]*alicznik2_amianownik2[1] -alicznik1_amianownik1[1]*alicznik2_amianownik2[0], alicznik1_amianownik1[1]*alicznik2_amianownik2[1]); } catch(Exception E) {throw E;} return wynik; } /* porownanie <, >, = */ public static int Cmp(Ulamek aulamek1,Ulamek aulamek2) { int[] alicznik1_amianownik1=aulamek1.get(); int[] alicznik2_amianownik2=aulamek2.get(); double wynik=(alicznik1_amianownik1[0]/(double)alicznik1_amianownik1[1]) -(alicznik2_amianownik2[0]/(double)alicznik2_amianownik2[1]); byte int_wynik; if (wynik==0) int_wynik=(byte)(wynik); else int_wynik=(byte)(wynik/Math.abs(wynik)); return int_wynik; } |
Pascal
{iloczyn} function UlamekProd(const AUlamek1, AUlamek2 :Ulamek) :Ulamek; var alicznik1,amianownik1,alicznik2,amianownik2 :Integer; begin AUlamek1.GetValues(alicznik1,amianownik1); AUlamek2.GetValues(alicznik2,amianownik2); UlamekProd:=Ulamek.Create(alicznik1*alicznik2,amianownik1*amianownik2); end; {iloraz} function UlamekQuot(const AUlamek1, AUlamek2 :Ulamek) :Ulamek; var alicznik1,amianownik1,alicznik2,amianownik2 :Integer; begin AUlamek1.GetValues(alicznik1,amianownik1); AUlamek2.GetValues(alicznik2,amianownik2); UlamekQuot:=Ulamek.Create(alicznik1*amianownik2,amianownik1*alicznik2); end; {suma} function UlamekSum(const AUlamek1, AUlamek2 :Ulamek) :Ulamek; var alicznik1,amianownik1,alicznik2,amianownik2 :Integer; begin AUlamek1.GetValues(alicznik1,amianownik1); AUlamek2.GetValues(alicznik2,amianownik2); UlamekSum:=Ulamek.Create(alicznik1*amianownik2+alicznik2*amianownik1,amianownik1*amianownik2); end; {zmiana znaku} function UlamekRevr(const AUlamek1 :Ulamek) :Ulamek; var alicznik1,amianownik1 :Integer; begin AUlamek1.GetValues(alicznik1,amianownik1); UlamekRevr:=Ulamek.Create(-alicznik1,amianownik1); end; {roznica} function UlamekDiff(const AUlamek1, AUlamek2 :Ulamek) :Ulamek; var alicznik1,amianownik1,alicznik2,amianownik2 :Integer; begin AUlamek1.GetValues(alicznik1,amianownik1); AUlamek2.GetValues(alicznik2,amianownik2); UlamekDiff:=Ulamek.Create(alicznik1*amianownik2-alicznik2*amianownik1,amianownik1*amianownik2); end; {porownanie <, >, =} function UlamekCmp(const AUlamek1, AUlamek2 :Ulamek) :Integer; var alicznik1,amianownik1,alicznik2,amianownik2 :Integer; wynik :Double; int_wynik :Integer; begin AUlamek1.GetValues(alicznik1,amianownik1); AUlamek2.GetValues(alicznik2,amianownik2); wynik:=(alicznik1/amianownik1)-(alicznik1/amianownik2); if wynik=0 then int_wynik:=Round(wynik) else int_wynik:=Round(wynik/abs(wynik)); UlamekCmp:=int_wynik; end; |
C# public static Ulamek operator *(Ulamek aulamek1,Ulamek aulamek2) { int alicznik1,amianownik1;aulamek1.get(out alicznik1,out amianownik1); int alicznik2,amianownik2;aulamek2.get(out alicznik2,out amianownik2); return new Ulamek(alicznik1*alicznik2,amianownik1*amianownik2); } public static Ulamek operator /(Ulamek aulamek1,Ulamek aulamek2) { int alicznik1,amianownik1;aulamek1.get(out alicznik1,out amianownik1); int alicznik2,amianownik2;aulamek2.get(out alicznik2,out amianownik2); return new Ulamek(alicznik1*amianownik2,amianownik1*alicznik2); } public static Ulamek operator +(Ulamek aulamek1,Ulamek aulamek2) { int alicznik1,amianownik1;aulamek1.get(out alicznik1,out amianownik1); int alicznik2,amianownik2;aulamek2.get(out alicznik2,out amianownik2); return new Ulamek(alicznik1*amianownik2+alicznik2*amianownik1,amianownik1*amianownik2); } public static Ulamek operator -(Ulamek aulamek1) { int alicznik1,amianownik1;aulamek1.get(out alicznik1,out amianownik1); return new Ulamek(-alicznik1,amianownik1); } public static Ulamek operator -(Ulamek aulamek1,Ulamek aulamek2) { int alicznik1,amianownik1;aulamek1.get(out alicznik1,out amianownik1); int alicznik2,amianownik2;aulamek2.get(out alicznik2,out amianownik2); return new Ulamek(alicznik1*amianownik2-alicznik2*amianownik1,amianownik1*amianownik2); } public static bool operator <(Ulamek aulamek1,Ulamek aulamek2) { int alicznik1,amianownik1;aulamek1.get(out alicznik1,out amianownik1); int alicznik2,amianownik2;aulamek2.get(out alicznik2,out amianownik2); return (alicznik1/(double)amianownik1)<(alicznik2/(double)amianownik2); } public static bool operator >(Ulamek aulamek1,Ulamek aulamek2) { int alicznik1,amianownik1;aulamek1.get(out alicznik1,out amianownik1); int alicznik2,amianownik2;aulamek2.get(out alicznik2,out amianownik2); return (alicznik1/(double)amianownik1)>(alicznik2/(double)amianownik2); } public override bool Equals(object obj) { if (obj==null) return false; Ulamek aulamek2=(Ulamek)obj; int alicznik2,amianownik2;aulamek2.get(out alicznik2,out amianownik2); return (licznik/(double)mianownik)==(alicznik2/(double)amianownik2); } public override int GetHashCode() { return licznik^mianownik; } public static bool operator ==(Ulamek aulamek1,Ulamek aulamek2) { return aulamek1.Equals((Object)aulamek2); } public static bool operator !=(Ulamek aulamek1,Ulamek aulamek2) { return !(aulamek1.Equals((Object)aulamek2)); } |
Przykład kodu
ulamek a=ulamek_polowa; ulamek b(ulamek_cwierc); ulamek c=a*b; ulamek d(2*c); c=a/b/2; d=2/a; c=a+b-2; d=2-(-a); try {c=a/ulamek_zero;} catch(char* E) {ShowMessage(E);} try {d=a/0;} catch(char* E) {ShowMessage(E);} if (a<b) ShowMessage("a < b"); else ShowMessage("a >= b"); if (a<1) ShowMessage("a < 1"); else ShowMessage("a >= 1"); if (0<a) ShowMessage("a > 0"); else ShowMessage("a <= 0"); if (b>a) ShowMessage("a < b"); else ShowMessage("a >= b"); if (1>a) ShowMessage("a < 1"); else ShowMessage("a >= 1"); if (a>0) ShowMessage("a > 0"); else ShowMessage("a <= 0"); if (a==b) ShowMessage("a = b"); else ShowMessage("a != b"); if (a==1) ShowMessage("a = 1"); else ShowMessage("a != 1"); if (a==0) ShowMessage("a = 0"); else ShowMessage("a != 0"); |
Przykład kodu: Ulamek a=null,b=null,c=null,d=null; try { a=new Ulamek(1,2); b=new Ulamek(3,4); c=Ulamek.Prod(a,b); d=Ulamek.Prod(a,new Ulamek(2,1)); c=Ulamek.Quot(a,b); d=Ulamek.Quot(new Ulamek(2,1),a); c=Ulamek.Sum(Ulamek.Sum(a,b),new Ulamek(2,1)); d=Ulamek.Diff(new Ulamek(2,1),Ulamek.Revr(a)); } catch(Exception E) { list1.add(E.getMessage()); } int[] licznik_mianownik=new int[2]; a.get(licznik_mianownik); list1.add("a: "+String.valueOf(licznik_mianownik[0])+"/"+ String.valueOf(licznik_mianownik[1])); b.get(licznik_mianownik); list1.add("b: "+String.valueOf(licznik_mianownik[0])+"/"+ String.valueOf(licznik_mianownik[1])); c.get(licznik_mianownik); list1.add("c: "+String.valueOf(licznik_mianownik[0])+"/"+ String.valueOf(licznik_mianownik[1])); d.get(licznik_mianownik); list1.add("d: "+String.valueOf(licznik_mianownik[0])+"/"+ String.valueOf(licznik_mianownik[1])); switch (Ulamek.Cmp(a,b)) { case -1: list1.add("a < b"); break; case 0: list1.add("a = b"); break; case 1: list1.add("a > b"); break; default: list1.add("Blad"); } |
Pascal
procedure TForm1.Button1Click(Sender: TObject); var a,b,c,d :Ulamek; licznik,mianownik :Integer; begin a:=Ulamek.Create(1,2); b:=Ulamek.Create(1,4); c:=UlamekProd(a,b); d:=UlamekProd(IntToUlamek(2),c); c:=UlamekQuot(UlamekQuot(a,b),IntToUlamek(2)); d:=UlamekQuot(IntToUlamek(2),c); c:=UlamekDiff(UlamekSum(a,b),IntToUlamek(2)); d:=UlamekDiff(IntToUlamek(2),UlamekRevr(a)); try c:=UlamekQuot(a,IntToUlamek(0)); except on E: Exception do ShowMessage(E.Message); end; c.GetValues(licznik,mianownik); ShowMessage('c: '+IntToStr(licznik)+'/'+IntToStr(mianownik)); d.GetValues(licznik,mianownik); ShowMessage('d: '+IntToStr(licznik)+'/'+IntToStr(mianownik)); case UlamekCmp(a,b) of -1: ShowMessage('a < b'); 0: ShowMessage('a = b'); 1: ShowMessage('a > b'); else ShowMessage('Blad'); end; end; |
Przykład kodu:
Ulamek a=Ulamek.Polowa; Ulamek b=new Ulamek(Ulamek.Cwierc); Ulamek c=a*b; int licznik,mianownik; c.get(out licznik,out mianownik); MessageBox.Show("c: "+licznik+"/"+mianownik); MessageBox.Show(a=b"); MessageBox.Show(a==b?"a=b":"a!=b"); |
Uwaga!
Delphi, Java: W Object Pascalu i Javie zasady konwersji dla typów wbudowanych są ściśle określone (np. możliwe jest int->double, ale nie odwrotne). Wiele konwersji musi być jawna poprzez funkcje (np. round() dla zmiany double na int). Można rzutować także obiekty na jego typ bazowy (zawężanie) i odwrotnie (rozszerzanie). Tylko to drugie jest zawsze bezpieczne. Obiekty mogą oczywiście równiez posiadać zdefinowane przez programistę metody pozwalające na dokonanie konwersji.
C++
class ulamek { private: int licznik, mianownik; double to_double() { return licznik/(double)mianownik; } char* to_string() { char str_licznik[ulamek_maxstr]; itoa(licznik,str_licznik,10); char str_mianownik[ulamek_maxstr]; itoa(mianownik,str_mianownik,10); char* str=str_licznik; strcat(str,"/"); strcat(str,str_mianownik); return str; } public: ulamek(int alicznik=0,int amianownik=1) { set(alicznik,amianownik); } ulamek(const ulamek& aulamek) { aulamek.get(licznik,mianownik); } void set(int alicznik,int amianownik) { if (amianownik==0) throw "Ulamek: Blad #1"; licznik=alicznik; mianownik=amianownik; } void get(int& rlicznik,int& rmianownik) const { rlicznik=licznik; rmianownik=mianownik; } void get(int* plicznik,int* pmianownik) const { *plicznik=licznik; *pmianownik=mianownik; } operator double() const { return to_double(); } operator char*() const { return to_string(); } }; |
Java package klasy; public class Ulamek implements Cloneable { private int licznik,mianownik; public Ulamek(int alicznik,int amianownik) throws Exception { try { set(alicznik,amianownik); } catch(Exception E) { throw E; } } public Object clone() throws CloneNotSupportedException { Object wynik=null; try { wynik=super.clone(); } catch(CloneNotSupportedException E) { throw E; } return wynik; } public void set(int alicznik,int amianownik) throws Exception { if (amianownik==0) throw new Exception("Ulamek: Blad #1"); licznik=alicznik; mianownik=amianownik; } public void get(int[] arg) { arg[0]=licznik; arg[1]=mianownik; } public int[] get() { int[] wynik=new int[2]; wynik[0]=licznik; wynik[1]=mianownik; return wynik; } /* POMINIĘTE FUNKCJE DZIAŁAŃ ARYTMETYCZNYCH I PORÓWNANIA WARTOŚCI */ public double toDouble() { return licznik/(double)mianownik; } //nadpisana na Object.toString() public String toString() { return String.valueOf(licznik)+"/"+String.valueOf(mianownik); } } |
Pascal
unit _ulamek; interface uses SysUtils; type Ulamek_Exception = class(Exception) private Message :String; public constructor Create(const AMessage :String); function What :String; end; Ulamek = class private licznik :Integer; mianownik :Integer; public constructor Create(const alicznik :Integer =0; const amianownik :Integer =1); procedure SetValues(const alicznik, amianownik :Integer); procedure GetValues(var rlicznik :Integer; var rmianownik :Integer); overload; procedure GetValues(plicznik, pmianownik :PInteger); overload; function ToFloat :Extended; function ToString :String; end; function IntToUlamek(const liczba :Integer) :Ulamek; function UlamekProd(const AUlamek1, AUlamek2 :Ulamek) :Ulamek; function UlamekQuot(const AUlamek1, AUlamek2 :Ulamek) :Ulamek; function UlamekSum(const AUlamek1, AUlamek2 :Ulamek) :Ulamek; function UlamekRevr(const AUlamek1 :Ulamek) :Ulamek; function UlamekDiff(const AUlamek1, AUlamek2 :Ulamek) :Ulamek; function UlamekCmp(const AUlamek1, AUlamek2 :Ulamek) :Integer; function UlamekToFloat(const AUlamek :Ulamek) :Extended; function UlamekToStr(const AUlamek :Ulamek) :String; implementation constructor Ulamek_Exception.Create(const AMessage :String); begin Message:=AMessage; end; function Ulamek_Exception.What :String; begin What:=Message; end; constructor Ulamek.Create(const alicznik :Integer =0; const amianownik :Integer =1); begin inherited Create; //TObject.Create() SetValues(alicznik,amianownik); end; procedure Ulamek.SetValues(const alicznik, amianownik :Integer); begin if amianownik=0 then raise Ulamek_Exception.Create('Ulamek: Blad #1'); licznik:=alicznik; mianownik:=amianownik; end; procedure Ulamek.GetValues(var rlicznik :Integer; var rmianownik :Integer); begin rlicznik:=licznik; rmianownik:=mianownik; end; procedure Ulamek.GetValues(plicznik :PInteger; pmianownik :PInteger); begin plicznik^:=licznik; pmianownik^:=mianownik; end; function Ulamek.ToFloat :Extended; begin ToFloat:=licznik/mianownik; end; function Ulamek.ToString :String; begin ToString:=IntToStr(licznik)+'/'+IntToStr(mianownik); end; { FUNKCJA KONWERTUJACA } function IntToUlamek(const liczba :Integer) :Ulamek; begin IntToUlamek:=Ulamek.Create(liczba,1); end; function UlamekToFloat(const AUlamek :Ulamek) :Extended; begin UlamekToFloat:=AUlamek.ToFloat; end; function UlamekToStr(const AUlamek :Ulamek) :String; begin UlamekToStr:=AUlamek.ToString; end; {OPERACJE NA ULAMKACH } {iloczyn} function UlamekProd(const AUlamek1, AUlamek2 :Ulamek) :Ulamek; var alicznik1,amianownik1,alicznik2,amianownik2 :Integer; begin AUlamek1.GetValues(alicznik1,amianownik1); AUlamek2.GetValues(alicznik2,amianownik2); UlamekProd:=Ulamek.Create(alicznik1*alicznik2,amianownik1*amianownik2); end; {iloraz} function UlamekQuot(const AUlamek1, AUlamek2 :Ulamek) :Ulamek; var alicznik1,amianownik1,alicznik2,amianownik2 :Integer; begin AUlamek1.GetValues(alicznik1,amianownik1); AUlamek2.GetValues(alicznik2,amianownik2); UlamekQuot:=Ulamek.Create(alicznik1*amianownik2,amianownik1*alicznik2); end; {suma} function UlamekSum(const AUlamek1, AUlamek2 :Ulamek) :Ulamek; var alicznik1,amianownik1,alicznik2,amianownik2 :Integer; begin AUlamek1.GetValues(alicznik1,amianownik1); AUlamek2.GetValues(alicznik2,amianownik2); UlamekSum:=Ulamek.Create(alicznik1*amianownik2+alicznik2*amianownik1,amianownik1*amianownik2); end; {zmiana znaku} function UlamekRevr(const AUlamek1 :Ulamek) :Ulamek; var alicznik1,amianownik1 :Integer; begin AUlamek1.GetValues(alicznik1,amianownik1); UlamekRevr:=Ulamek.Create(-alicznik1,amianownik1); end; {roznica} function UlamekDiff(const AUlamek1, AUlamek2 :Ulamek) :Ulamek; var alicznik1,amianownik1,alicznik2,amianownik2 :Integer; begin AUlamek1.GetValues(alicznik1,amianownik1); AUlamek2.GetValues(alicznik2,amianownik2); UlamekDiff:=Ulamek.Create(alicznik1*amianownik2-alicznik2*amianownik1,amianownik1*amianownik2); end; {porownanie <, >, =} function UlamekCmp(const AUlamek1, AUlamek2 :Ulamek) :Integer; var alicznik1,amianownik1,alicznik2,amianownik2 :Integer; wynik :Double; int_wynik :Integer; begin AUlamek1.GetValues(alicznik1,amianownik1); AUlamek2.GetValues(alicznik2,amianownik2); wynik:=(alicznik1/amianownik1)-(alicznik1/amianownik2); if wynik=0 then int_wynik:=Round(wynik) else int_wynik:=Round(wynik/abs(wynik)); UlamekCmp:=int_wynik; end; end. |
C#
public class Ulamek { private int licznik,mianownik; public static readonly Ulamek Zero=new Ulamek(0,1); public static readonly Ulamek Jeden=new Ulamek(1,1); public static readonly Ulamek Polowa=new Ulamek(1,2); public static readonly Ulamek Cwierc=new Ulamek(1,4); public Ulamek(int alicznik,int amianownik) { set(alicznik,amianownik); } public Ulamek(Ulamek aulamek) { int olicznik,omianownik; aulamek.get(out olicznik,out omianownik); set(olicznik,omianownik); } public Ulamek Clone() { return new Ulamek(licznik,mianownik); } public void set(int alicznik,int amianownik) { if (amianownik==0) throw new Ulamek_Exception("Ulamek: Blad #1"); licznik=alicznik; mianownik=amianownik; } public void get(out int rlicznik,out int rmianownik) { rlicznik=licznik; rmianownik=mianownik; } public void get(int[] arg) { arg[0]=licznik; arg[1]=mianownik; } public int[] get() { int[] wynik=new int[2]; wynik[0]=licznik; wynik[1]=mianownik; return wynik; } public override string ToString() { return ""+licznik+"/"+mianownik; } public double ToDouble() { return licznik/(double)mianownik; } //konwersja z Ulamek na double public static implicit operator double(Ulamek aulamek) { return aulamek.ToDouble(); } //konwersja z int na Ulamek public static implicit operator Ulamek(int aliczba_calkowita) { return new Ulamek(aliczba_calkowita,1); } } |
Przykład kodu
ShowMessage((double)ulamek(1,2)); ShowMessage((double)ulamek(1,3)); ShowMessage((char*)ulamek(1,2)); ShowMessage((char*)ulamek(1,3)); |
Przykład kodu: Ulamek a=null,b=null; try { a=new Ulamek(1,2); b=new Ulamek(1,3); } catch(Exception E) { list1.add(E.getMessage()); } list1.add("a: "+String.valueOf(a.toDouble())); list1.add("b: "+String.valueOf(b.toDouble())); list1.add("a: "+a.toString()); //jawna konwersja na String list1.add("b: "+b.toString()); list1.add("a: "+String.valueOf(a)); //jawna konwersja na String list1.add("b: "+String.valueOf(b)); //korzysta z toString list1.add("a: "+a); //niejawna konwersja na String list1.add("b: "+b); //korzysta z toString |
Pascal
procedure TForm1.Button1Click(Sender: TObject); var a,b :Ulamek; begin a:=Ulamek.Create(1,2); b:=Ulamek.Create(1,3); ShowMessage('a: '+FloatToStr(a.ToFloat)+', b: '+FloatToStr(b.ToFloat)); ShowMessage('a: '+a.ToString+', b: '+b.ToString); ShowMessage('a: '+FloatToStr(UlamekToFloat(a))+', b: '+FloatToStr(UlamekToFloat(b))); ShowMessage('a: '+UlamekToStr(a)+', b: '+UlamekToStr(b)); end; |
Przykład kodu: MessageBox.Show(Ulamek.Polowa.ToString()); MessageBox.Show(""+Ulamek.Polowa); MessageBox.Show(""+Ulamek.Polowa.ToDouble()); MessageBox.Show(""+(1.0+Ulamek.Polowa)); //niejawna konwersja na double Ulamek a=2; MessageBox.Show(""+a); |
Uwaga!
C++
void simplify() { //NWD int mniejsza=(abs(licznik)<abs(mianownik)) ?abs(licznik):abs(mianownik); for(int i=mniejsza;i>0;i--) if ((licznik%i==0) && (mianownik%i==0)) { licznik/=i; mianownik/=i; } //znaki if (licznik*mianownik<0) { licznik=-abs(licznik); mianownik=abs(mianownik); } else { licznik=abs(licznik); mianownik=abs(mianownik); } } |
Java public void simplify() { //NWD int mniejsza=(Math.abs(licznik)<Math.abs(mianownik)) ?Math.abs(licznik):Math.abs(mianownik); for(int i=mniejsza;i>0;i--) if ((licznik%i==0) && (mianownik%i==0)) { licznik/=i; mianownik/=i; } //znaki if (licznik*mianownik<0) { licznik=-Math.abs(licznik); mianownik=Math.abs(mianownik); } else { licznik=Math.abs(licznik); mianownik=Math.abs(mianownik); } } |
Pascal
procedure Ulamek.Simplify; var mniejsza,i :Integer; begin //NWD mniejsza:=Min(abs(licznik),abs(mianownik)); for i:=mniejsza downto 1 do if (licznik mod i=0) and (mianownik mod i=0) then begin licznik:=licznik div i; mianownik:=mianownik div i; end; //znaki if licznik*mianownik<0 then begin licznik:=-abs(licznik); mianownik:=abs(mianownik); end else begin licznik:=abs(licznik); mianownik:=abs(mianownik); end; end; |
C# public void simplify() { //NWD int mniejsza=(Math.Abs(licznik) |
Przykład kodu
ulamek a(30,-75); int licznik,mianownik; a.get(licznik,mianownik); ShowMessage((AnsiString)"nieuproszczone a: "+licznik+"/"+mianownik); a.simplify(); a.get(licznik,mianownik); ShowMessage((AnsiString)"uproszczone a: "+licznik+"/"+mianownik); |
Przykład kodu Ulamek a=null,b=null; try { a=new Ulamek(30,-75); } catch(Exception E) { list1.add(E.getMessage()); } list1.add("a: "+a); a.simplify(); list1.add("b: "+a); |
Pascal
procedure TForm1.Button1Click(Sender: TObject); var a :Ulamek; begin a:=Ulamek.Create(30,-75); ShowMessage('nieuproszczone a: '+a.ToString()); a.Simplify(); ShowMessage('uproszczone a: '+a.ToString()); end; |
Przykład kodu Ulamek a=new Ulamek(128,-96); a.simplify(); MessageBox.Show(""+a); |
Uwaga!
Mozna uczynić simplify()
metodą prywatna, a za to wywolywac ja przy kazdym get().
Tutaj możliwość wykorzystania tej metody pozostawiona została użytkownikowi
klasy.
Delphi: W Delphi wewnątrz modułu rozdzielenie deklaracji i definicji jest obowiązkowe ze względu na gramatykę Pascala.
Java: W Javie definicja metod musi znajdować się w obrębie deklaracji klasy. Nie oznacza to wcale, że są metodami inline.
C++ Plik nagłówkowy (ulamek.h):
Plik źródłowy (ulamek.cpp):
|
Przykład kodu
//TABLICE ULAMKOW //ShowMessage("Zakres liczb pseudolosowych: "+(AnsiString)(double)RAND_MAX); const zakres=100; const ilosc=10; ulamek a[ilosc]; randomize(); for(int i=0;i<ilosc;i++) { ulamek b=ulamek(rand() % zakres,rand() % zakres); a[i]=b; a[i].simplify(); ShowMessage((AnsiString)(char*)b+" = "+(char*)a[i]); } //TYPOWE ZASTOSOWANIA ShowMessage((double)ulamek_polowa+0.1); ShowMessage(1/2); ulamek c=3/4; ShowMessage((char*)c); c=(ulamek)3/(ulamek)4; ShowMessage((char*)c); |
Uwaga!
C++: Używanie metod inline w przypadku bardziej złożonych
funkcji nie jest zalecane - utrudnia to kompilatorowi optymalizację kodu wynikowego.
C++ Plik nagłówkowy (ulamek.h):
Plik główny (ulamek.cpp):
|
Przykład kodu
typedef ulamek<long> long_ulamek; const long_ulamek long_ulamek_zero(0,1); const long_ulamek long_ulamek_jeden(1,1); const long_ulamek long_ulamek_polowa(1,2); const long_ulamek long_ulamek_cwierc(1,4); const zakres=100; const ilosc=10; try { long_ulamek a[ilosc]; randomize(); for(int i=0;i<ilosc;i++) { long_ulamek b=long_ulamek(rand() % zakres,rand() % zakres); a[i]=b; a[i].simplify(); ShowMessage((AnsiString)(char*)b+" = "+(char*)a[i]); } } catch(char* E) { ShowMessage(E); exit(EXIT_FAILURE); } |
Uwaga!
C++
template <class T> class ansistring_ulamek : public ulamek<T> { private: AnsiString to_AnsiString() const { return (AnsiString)licznik+'/'+(AnsiString)mianownik; } public: ansistring_ulamek(T alicznik=0,T amianownik=1):ulamek<T>(alicznik,amianownik) { } from_ulamek(ulamek<T> aulamek) { aulamek.get(licznik,mianownik); } operator AnsiString() { return to_AnsiString(); } }; //operatory zwracajace obiekt klasy potomnej template <class T> ansistring_ulamek<T> operator *(const ansistring_ulamek<T>& aulamek1, const ansistring_ulamek<T>& aulamek2) { ansistring_ulamek<T> as_ulamek; as_ulamek.from_ulamek((ulamek<T>)aulamek1*(ulamek<T>)aulamek2); return as_ulamek; }; template <class T> ansistring_ulamek<T> operator /(const ansistring_ulamek<T>& aulamek1, const ansistring_ulamek<T>& aulamek2) { ansistring_ulamek<T> as_ulamek; as_ulamek.from_ulamek((ulamek<T>)aulamek1/(ulamek<T>)aulamek2); return as_ulamek; }; template <class T> ansistring_ulamek<T> operator +(const ansistring_ulamek<T>& aulamek1, const ansistring_ulamek<T>& aulamek2) { ansistring_ulamek<T> as_ulamek; as_ulamek.from_ulamek((ulamek<T>)aulamek1+(ulamek<T>)aulamek2); return as_ulamek; }; template <class T> ansistring_ulamek<T> operator -(const ansistring_ulamek<T>& aulamek1) { ansistring_ulamek<T> as_ulamek; as_ulamek.from_ulamek(-(ulamek<T>)aulamek1); return as_ulamek; }; template <class T> ansistring_ulamek<T> operator -(const ansistring_ulamek<T>& aulamek1, const ansistring_ulamek<T>& aulamek2) { ansistring_ulamek<T> as_ulamek; as_ulamek.from_ulamek((ulamek<T>)aulamek1-(ulamek<T>)aulamek2); return as_ulamek; }; |
Java (plik CString_Ulamek.java)
package klasy; public class CString_Ulamek extends Ulamek implements Cloneable { public CString_Ulamek(int alicznik,int amianownik) throws Exception { super(alicznik,amianownik); } public char[] toCString() { String swynik=this.toString(); char[] cwynik = new char[swynik.length()]; swynik.getChars(0, swynik.length(), cwynik, 0); return cwynik; } } |
Pascal
unit _cstring_ulamek; interface uses _ulamek, SysUtils; type CString = array of Char; //tablica dynamiczna PCString = ^CString; CString_Ulamek = class(Ulamek) public constructor Create(const alicznik :Integer =0; const amianownik :Integer =1); procedure ToCString(const buffer_pointer :PCString;var buffer_length :Integer); procedure ToPChar(const buffer_pointer :PChar;const buffer_length :Integer); end; implementation constructor CString_Ulamek.Create(const alicznik :Integer =0; const amianownik :Integer =1); begin inherited; //Ulamek.Create(licznik,mianownik) end; procedure CString_Ulamek.ToCString(const buffer_pointer :PCString;var buffer_length :Integer); var s :String; i :Integer; begin s:=IntToStr(licznik)+'/'+IntToStr(mianownik); buffer_length:=Length(s); SetLength(buffer_pointer^,buffer_length); for i:=0 to buffer_length-1 do buffer_pointer^[i]:=s[i+1]; //s numerowane od 1 end; procedure CString_Ulamek.ToPChar(const buffer_pointer :PChar;const buffer_length :Integer); var s :String; i :Integer; begin s:=IntToStr(licznik)+'/'+IntToStr(mianownik); StrPLCopy(buffer_pointer,s,buffer_length); end; {Tu powinny byc operatory dla CString_Ulamek} end. |
C#
public class CString_Ulamek : Ulamek { public CString_Ulamek(int alicznik,int amianownik):base(alicznik,amianownik) { } public char[] ToCString() { return this.ToString().ToCharArray(); } public static explicit operator char[](CString_Ulamek acstring_ulamek) { return acstring_ulamek.ToCString(); } } |
Przykład kodu
ulamek |
Przykład kodu CString_Ulamek a=null; try{a=new CString_Ulamek(30,-75);}catch(Exception E){list1.add(E.getMessage());} a.simplify(); char[] c=a.toCString(); list1.add("a: "+String.valueOf(c)); |
Pascal
procedure TForm1.Button1Click(Sender: TObject); var a :CString_Ulamek; buffer :CString; buffer1 :array of Char; buffer_size :Integer; s :String; begin a:=CString_Ulamek.Create(1,2); a.ToCString(@buffer,buffer_size); ShowMessage('dlugosc bufora: '+IntToStr(buffer_size)); ShowMessage('zawartosc bufora: '+String(buffer)); a.ToCString(@s,buffer_size); ShowMessage('dlugosc bufora: '+IntToStr(buffer_size)); ShowMessage('zawartosc bufora: '+s); a.ToPChar(PChar(buffer),Length(buffer)); ShowMessage('dlugosc bufora: '+IntToStr(Length(buffer))); ShowMessage('zawartosc bufora: '+String(buffer)); end; |
Przykład kodu CString_Ulamek a=new CString_Ulamek(1,2); char[] ac=a.ToCString(); MessageBox.Show(""+ac[1]); MessageBox.Show(""+((char[])a)[1]); |
Uwaga!
class ansistring_int_ulamek : public ulamek{ private: AnsiString to_AnsiString() const { return (AnsiString)licznik+'/'+(AnsiString)mianownik; } public: ansistring_int_ulamek(int alicznik=0,int amianownik=1):ulamek (alicznik,amianownik) { } operator AnsiString() { return to_AnsiString(); } };
procedure CString_Ulamek.ToPChar(const buffer_pointer :PChar;const buffer_length :Integer); var s :String; i :Integer; begin s:=IntToStr(licznik)+'/'+IntToStr(mianownik); i:=0; while (i<buffer_length) and (i<Length(s)) do begin (buffer_pointer+i)^:=s[i+1]; //s numerowane od 1 Inc(i); end; (buffer_pointer+i)^:=#0; end;
(c) Jacek Matulewski 2003-2004 (jacek@phys.uni.torun.pl)
wersja z dnia: 22 VIII 2004