Prezentacja programu PowerPoint

Download Report

Transcript Prezentacja programu PowerPoint

Programowanie obiektowe
Wykład 4
Tworzenie własnych obiektów
Słowo kluczowe this
W JavaScript można tworzyć własne obiekty. Wykorzystuje się
tu zapis utworzonej funkcji o nazwie takiej samej jak klasa, dla
której definiujemy właściwości (zmienne proste lub
obiektowe) i metody (funkcje wewnętrzne).
Nadając i wykorzystując identyfikatory właściwości i metod
korzystamy ze słowa kluczowego this. Rozumiane jest ono jako
obiekt bieżący, właściciel metody lub właściwości. Poniżej
prosty przykład:
Przykład
<HTML>
<HEAD> </HEAD>
<BODY style="font-size:18px">
<P> AKAPIT</P>
<PRE>
<SCRIPT language="JavaScript">
function kolor1( ) {
this.document.bgColor = "red";
}
function kolor2(e) {
e.style.color = "yellow";
}
</SCRIPT>
</PRE>
<INPUT type="button" value="Kolor dla tła okna" onclick="kolor1( )">
<INPUT type="button" value="Kolor napisu przycisku" onclick="kolor2(this)">
</BODY>
</HTML>
W powyższym przykładzie mamy dwie własne funkcje.
W pierwszej o nazwie kolor1 ustalamy kolor tła dla
bieżącego obiektu (this) - którym jest domyślnie window.
Druga funkcja o nazwie kolor2 zmienia kolor czcionki
przekazanego do funkcji obiektu e - wywoływana jest
kliknięciem w przycisk z przekazaniem odniesienia do
tego właśnie przycisku (this), a więc zmienia się kolor
napisu na przycisku.
Najmniej uniwersalny sposób - tworzenie konkretnej
instancji (egzemplarza) bez definicji:
var piesek1 = {
imie: "Maja",
rasa: "kundel",
kolor: "zółty",
plec: "suczka",
glos:"haaaauuuu",
dajGlos: function ()
{
document.writeln(this.glos);
}
};
document.writeln(piesek1.imie);
piesek1.dajGlos ();
Definicja konstruktora obiektu - Metoda 1
Można utworzyć definicję – tzw. konstruktor obiektu (klasa) wykorzystując
własną funkcję:
function Nazwa(argument1,argument2, itd)
{
this. właściwość1 = argument1;
this. właściwość2 = argument2;
this.metoda= function( argumenty)
{opis metody}
//inne właściwości i inne metody
}
Teraz tworzymy egzemplarze (instancje) obiektu i przypisujemy do
zmiennych referencji p1 i p2:
var p1 = new Nazwa( argumenty aktualne);
var p2 = new Nazwa( inne argumenty aktualne);
Przykład
<PRE>
<SCRIPT language="JavaScript">
//funkcja konstruktor
function Pies(imie, rasa, kolor, plec) {
this. imie = imie;
this. rasa = rasa;
this. kolor = kolor;
właściwości
this. plec = plec;
this.glos ="HAUUUU"; //dla wszystkich psów ten sam
this.dajGlos = function () {
document.writeln (this.glos);
przykładowa
};
metoda
};
//tworzymy instancje
var piesek1 = new Pies( "Misia", "Labrador", "czekoladowa", "suka" );
var piesek2 = new Pies( "Misiek", "Seter", "rudy", "pies" );
//możemy mieć dostęp do właściwości i metod
document.writeln(piesek1.imie); // ->wypisze Misia
piesek1.dajGlos (); // -> wykonanie metody - metoda wypisze "HAUUUU"
//itd.
</SCRIPT>
</PRE>
Przykład – metoda typu "get"
<PRE>
<SCRIPT language="JavaScript">
//funkcja konstruktor
function Pies(imie, rasa, kolor, plec) {
this. imie = imie;
this. rasa = rasa;
this. kolor = kolor;
właściwości
this. plec = plec;
this.glos ="HAUUUU"; //dla wszystkich psów ten sam
this.dajGlos = function () {
return this.glos;
metoda "get" (pobierz)
};
};
//tworzymy instancje
var piesek1 = new Pies( "Misia", "Labrador", "czekoladowa", "suka" );
var piesek2 = new Pies( "Misiek", "Seter", "rudy", "pies" );
//możemy mieć dostęp do właściwości i metod
document.writeln(piesek1.imie); // -> Misia
document.writeln(piesek1.dajGlos ()); // -> instrukcja wypisuje wynik metody
//itd.
</SCRIPT>
</PRE>
Przykład – metoda typu "set"
<PRE>
<SCRIPT language="JavaScript">
//funkcja konstruktor
function Pies(imie, rasa, plec) {
this. imie = imie;
this. rasa = rasa;
this. kolor = "";//pusta wartość
właściwości
this. plec = plec;
this.glos ="HAUUUU"; //dla wszystkich psów ten sam
this.ustawKolor = function (k ) {
this.kolor = k;
metoda "set" (ustaw)
};
};
//tworzymy instancje
var piesek1 = new Pies( "Misia", "Labrador", "czekoladowa", "suka" );
var piesek2 = new Pies( "Misiek", "Seter", "rudy", "pies" );
//możemy mieć dostęp do właściwości i metod
document.writeln("Kolor pieska 1:",piesek1.kolor); // -> jeszcze nie ma
piesek1.ustawKolor("kremowa"); // -> instrukcja nadaje wartość właściwości
document.writeln("Kolor pieska 1:",piesek1.kolor); // -> teraz kremowy
</SCRIPT>
</PRE>
Metody typu "get" zwracają jakąś wartość. W opisie metody
jest zapis:
return co_zwraca_metoda
To co zwraca metoda można potem wypisać na ekranie:
document.write(obiekt.metoda(argumenty))
lub użyć w wyrażeniach zgodnie z typem zwracanej wartości
Metody typu get najczęściej zwracają właściwość obiektu jest to tzw. hermetyzacja – dostęp do właściwości
powinien być tylko przy użyciu metod
Metody typu "set" ustawiają wartość właściwości
obiektu lub ją zmieniają – nie maja return.
Wykorzystuje się je jako osobną instrukcję w postaci:
obiekt.metoda(argumenty)
Inny przykład konstruktora obiektów
function Auto (nr,nazwa)
{ //właściwości
this.nr=nr;
this.nazwa = nazwa;
this.predkosc=0;
//metody
this.podajNazwe = function(){
return this.nazwa; }
this.przyspiesz = function(dp){
this.predkosc=dp; }
wybór elementu
do wyświetlenia
this.zatrzymaj = function(){
wartości
this.predkosc=0; }
this.pokazPredkosc = function(){
return this.predkosc;
}
this.wyswietl = function(){
var d=document.getElementById('ed'+this.nr);
d.innerHTML=this.podajNazwe()+' ma prędkość:'+this.pokazPredkosc(); }
}
Sposób 2 –wykorzystuje tworzenie instancji
<PRE>
<SCRIPT language="JavaScript">
//funkcja konstruktor
Pies2 = function (imie, rasa, kolor, plec)
{
//definiowanie instancji obiektu – tu uwaga na "interpunkcję"!
var obiektPies = {
imie: imie,
rasa: rasa,
kolor: kolor,
plec: plec,
glos:"HAUUU",
dajGlos: function ( )
{
document.writeln(this.glos);
}
};
//funkcja zwraca zdefiniowany obiekt
return obiektPies;
};// KONIEC FUNKCJI
//tworzenie instancji klasy
var piesek3 = new Pies2( "Milka", "Spaniel", "czekoladowa", "suka" );
var piesek4 = new Pies2( "Reksio", "Dog", "czarny", "pies" );
//możemy mieć dostęp do właściwości i metod
document.writeln(piesek3.imie);
piesek3.dajGlos ();
//itd.
</SCRIPT>
</PRE>
W obu sposobach mamy ogólne definicje
konstruktorów obiektu.
Potem możemy tworzyć wiele egzemplarzy
różniących się wartościami właściwości i
wykonywać metody (akcje).
Ograniczenia dostępu do pól
<PRE>
<SCRIPT language=" JavaScript ">
JakisObiekt= function (n1,n2) {
w_pryw= n1; //właściwość prywatna (nie ma this)
this.w_pub=n2; //właściwość publiczna
this.podajNazwe1 = function () {return w_pryw;
};
this.podajNazwe2 = function () {return this.w_pub; };
};
t = new JakisObiekt("prywatna","publiczna");
document.writeln("met1:",t.podajNazwe1());//tylko metoda podaje właściwość prywatną
document.writeln("met2:",t.podajNazwe2());//metoda podaje też właściwość publiczną
document.writeln("w_pryw:",t.w_pryw);//nie ma dostępu do prywatnej - undefined
document.writeln("w_pub:",t.w_pub);// jest dostęp do właściwości publicznej
</SCRIPT>
</PRE>
Obiekty wewnętrzne
W przypadku konieczności uwzględnienia pewnej liczby
elementów o identycznym zestawie właściwości,
wchodzących w skład definiowanego obiektu, możemy jedną
z właściwości obiektu głównego zdefiniować jako pustą
tablicę, a następnie wykorzystać odpowiednią metodę do
wypełniania tablicy.
Elementami takiej tablicy mogą także być obiekty (mamy
wówczas możliwość zróżnicowania typów składowych
obiektu).
Tablica elementów może być dynamicznie wypełniana w
programie (dowolna liczba jej składowych)
<PRE><SCRIPT language="JavaScript">
var Mechanizm= function(nr, typ)
{
this.nrR=nr;
this.typR= typ;
//pusta tablica
właściwości
this.dzwignie=[ ];
this.tworzDzwignie=function(nrDz, dlDz)
{
//umieść obiekt wewnętrzny w podanej komórce tablicy
this.dzwignie[nrDz-1]={
metoda
nrD: nrDz,
dlD: dlDz,
}
}
} //koniec definicji konstruktora
//tworzymy egzemplarz obiektu
m1=new Mechanizm (1,'x25');
//tworzymy składowe obiektu
m1.tworzDzwignie (1, 500);
m1.tworzDzwignie (2,600);
m1.tworzDzwignie (3,400);
//wypisujemy nadane właściwości
document.writeln("Robot nr ",m1.nrR, " Typ:",m1.typR);
document.writeln("Ręce");
//elementy tablicy dzwignie
for (k=0;k<m1.dzwignie.length;k++)
{
document.writeln("Nr dzwigni:", m1.dzwignie[k].nrD," długość dźwigni:",m1.dzwignie[k].dlD);
}
</SCRIPT></PRE>
Oddziaływanie wzajemne obiektów
<HTML> <HEAD> </HEAD><BODY style="font-size:18px">
Oddzialywanie obiektów - gryzie ogon
<PRE>
<SCRIPT language="javascript">
var Kot=function(imie, ogon) {
this.imie=imie;
this.ogon=ogon;
this.ugryz=function(ob){//argumentem metody jest inny obiekt
ob.ogon-=5;
}
}
kot1= new Kot ("Maciuś",20);
kot2= new Kot ("Misiek", 20);
document.writeln(kot1.imie," ma ogon ",kot1.ogon);
document.writeln(kot2.imie," ma ogon ",kot2.ogon);
document.writeln(kot2.imie," gryzie ", kot1.imie);
kot2.ugryz(kot1); //kot2 gryzie kota1
document.writeln(kot1.imie," ma teraz ogon ",kot1.ogon);
document.writeln(kot1.imie," gryzie ", kot2.imie);
kot1.ugryz(kot2); //kot1 gryzie kota2
document.writeln(kot2.imie," ma teraz ogon ",kot2.ogon);
</SCRIPT>
</PRE>
</BODY></HTML>
Dziedziczenie obiektów
Prototyp (prototype) to specjalna właściwość obiektowa,
którą posiada każdy obiekt.
Prototyp można wykorzystać do nadania dowolnej wartości
(obiektowej). Prototyp oznacza obiekt, który niejawnie
udostępnia swoje właściwości innym obiektom. W języku
JavaScript prototyp jest tworzony oraz udostępniany każdej
powstającej instancji wybranej klasy.
Gdy użytkownik pragnie odczytać właściwość, która nie jest
obecna w danej instancji, jest ona wyszukiwana w jej
prototypie.
Wykorzystamy prototyp do przepisania całego obiektu
nadrzędnego do obiektu podrzędnego i utworzenia nowych
właściwości obiektu potomnego.
<PRE><SCRIPT language="JavaScript">
//konstruktor przodka
var Zwierze = function(wiek)
{
this.nazwaPrzodka ='zwierzę';
this.wiek = wiek;
}
//konstruktor potomka
var Kot = function(imie, siersc)
{
this.nazwaKlasy='Kot';
this.nazwa = imie;
this.nogi = 4;
this.siersc= siersc;
}
//przepisanie do prototypu właściwości obiektu Zwierze( )
Kot.prototype = new Zwierze(4)
//nowa właściwość prototypu
Kot.prototype.glos = 'Miauuu';
//tworzymy obiekt
k= new Kot("Maciek", "ruda");
//wyświetlamy jego właściwości
document.writeln("Utworzyliśmy obiekt typu:",k.nazwaKlasy) ;// wyświetli: Kot
document.writeln("Przodek:",k.nazwaPrzodka); // wyświetli: zwierzę
document.writeln("Nazwa:",k.nazwa) ;// wyświetli: Maciek
document.writeln("Nogi:",k.nogi) ;// wyświetli: 4
document.writeln("Głos:",k.glos) ;// wyszukane w prototypie - wyświetli: Miauuu
document.writeln("Wiek:",k.wiek) ;// wyświetli: 1
document.writeln("Sierść:",k.siersc) ;// wyświetli: ruda
</SCRIPT></PRE>
<PRE><SCRIPT language="JavaScript">
//konstruktor przodka
urzElektr = function(napiecie, producent)
{
this.nazwa ='Urządzenie elektryczne';
this.napiecie = napiecie;
this.producent = producent;
}
//konstruktor potomka
Lodowka = function(producent, temp_min)
{
this.nazwaKlasy='Lodówka';
this.temp_min=temp_min;
}
//przepisanie do prototypu właściwości obiektu urzElektr( )
Lodowka.prototype = new urzElektr(230, "Bosch")
//możemy dodać nową właściwość prototypu
Lodowka.prototype.podtyp= "AGD" ;
//tworzymy obiekt
k= new Lodowka( -10);
//wyświetlamy jego właściwości
document.writeln("Utworzyliśmy obiekt typu:", k.nazwaKlasy) ;// wyświetli: Lodówka
document.writeln("Przodek:", k.nazwa); // wyświetli: Urządzenie elektryczne
document.writeln("Producent", k.producent) ;// wyświetli: Bosch
document.writeln("Podtyp:",k.podtyp) ;// wyszukane w prototypie - wyświetli: AGD
</SCRIPT></PRE>
UWAGA: Przy tworzeniu hierarchii obiektów
należy uważnie i sensownie projektować
właściwości i metody.
W powyższym przykładzie producent i
napięcie są właściwościami urzElektr()
(każde urządzenie elektryczne producenta,
napięcie), zaś temperatura minimalna, podtyp
to już właściwości lodówki (nie każde
urządzenie ma podtyp czy temperaturę jako
ważną właściwość).
Polimorfizm (wielopostaciowość)
Przedefiniowanie metody obiektu
nadrzędnego w obiekcie potomnym nosi
nazwę polimorfizmu (wielopostaciowości).
<PRE><SCRIPT language="JavaScript">
// konstruktor obiektu Auto( )
function Auto (x) {
this.nazwa = x;
this.podajNazwe = function( ){
document.writeln("Auto:", this.nazwa);
}
}
// konstruktor obiektu AutoSuper
function AutoSuper(n) {
//przepisanie do prototypu cech obiektu Auto( )
this.prototype = new Auto(n);
//nowa właściwość
this.prototype.turbo=" Ma turbo";
//można nadpisać (przedefiniować) metodę podajNazwe
AutoSuper.prototype.podajNazwe = function ( ) {
document.writeln("Auto-super:",this.prototype.nazwa," turbo:", this.prototype.turbo);
};
}
//tworzymy instancję obiektu Auto( )
var a1 = new Auto("MacLaren");
//wywołujemy funkcje utworzonego obiektu
a1.podajNazwe( );
// sprawdzamy istnienie właściwości turbo
if (a1.turbo==undefined)
document.writeln("To auto nie ma turbo");
//inicjalizujemy obiekt potomny
var a2 = new AutoSuper("MacLaren");
// sprawdzamy przedefiniowanie metody podajNazwe()
a2.podajNazwe( );
</SCRIPT>
Teraz mamy:
• Definicję obiektu Auto() – z metodą podajNazwe()
• Definicję obiektu potomnego AutoSuper() posiadającą:
o dodatkową właściwość turbo
o przedefiniowaną metodę podajNazwe().