150 likes | 284 Views
Programació orientada a objectes. Objectes. (que hem d’entendre abans de començar a programar?). Classes: Les classes generen el diagrama principal dins del UML en el sentit que és l’únic que s’utilitza per generar codi. Encapsulació:
E N D
Programació orientada a objectes Objectes... (que hem d’entendre abans de començar a programar?) • Classes: • Les classes generen el diagrama principal dins del UML en el sentit que és l’únic que s’utilitza per generar codi. • Encapsulació: • Es la manera de separar el que ofereix un objecte de com s’implementa. • Tota la implementació està oculta i oferim una serie de mètodes i variables. públics. Són les funcionalitats que deixem visibles als usuaris/programadors. • En UML es parla de visibilitat dels atributs o funcions. • Tipus complexes: • Una variable “a de tipus“b” (no representa una variable de tipus simple) • La variable contindrà un objecte. • La variable podrà rebre missatges enviats per altres objectes. • Pas de missatges: • Entre objectes. • No és cridar a un procediment. • En un missatge cal indicar qui serà el receptor. Penseu que hi poden haver múltiples instancies d’un determinat objecte.
Programació orientada a objectes Objectes... • Polimorfisme: Molts mètodes tenen el mateix nom. Hi ha dues maneres d’implementar-ho: • Sobrecàrrega. • Sobreescriure mitjançant l’herència. • Herència: • És la capacitat d’una classe d’utilitzar-ne com a base d’altres ja existents amb tot el que tenia l’original (atributs i operacions públiques i protegides). • Podem definir interfaces (sense codi) o implementacions. • Els constructors no s’hereden. Es criden tots i calen tots!.
Classes vs interfícies Objectes... (d’entrada) • Una classe (no abstracte) pot instanciar-se. Un interface no! (un interface és abstracte per defecte. • Es crida a un constructor un cop instanciades. • Les classes tenen propietats (atributs, variables), mètodes (operacions, funcions) i els implementa. Les interfícies sols defineixen les propietats estàtiques (constants) i mètodes abstractes (no contenen instruccions). • Les interfícies son plantilles!. • Si una classe abstracta no implementa operacions com es diferència d’un interfície?. • Un interfície no pot implementar mètodes i una classe abstracta si. • Una classe pot implementar diversos interfícies però pot derivar tant sols d’una. • Una interfície pot derivar-se d’altres, però no d’una classe. Exemple d’instanciació d’una classe. ... Map = new EU2(); ...
Classes vs interfícies Objectes... Els atributs poden ser públics o privats. S’aconsella que siguin privats i que s’hi accedeixi mijançant funcions públiques. class EU2 extends Map{ private int max[]=new int[320]; private int x[][]=new int[320][165]; private int y[][]=new int[320][165]; private Color c=new Color(230,230,230);private Color cc=new Color(230,230,230); ... EU2(){...} ... public int getX(int elem,int pos){return x[elem][pos];} public int getY(int elem,int pos){return y[elem][pos];} public int getMax(int elem){return max[elem];} public Color getColor(int elem){return cc;} public void setColor(int elem,Color c){...} public int getR(int elem){return 0;} public int getW(int elem){return 0;} public int getCX(int elem){return x[elem][0];} public int getCY(int elem){return y[elem][0];} public boolean canSel(){return true;};//la capa es seleccionable?? }
Classes vs interfícies Objectes... Quan utilitzarem classes i quan interfícies? • Utilitzarem interfícies quan: • poques operacions. • poques variables. • Les classes que implementen la interfície són diverses. • Utilitzarem implementacions quan: • No és una utilitat. • Implementació complexa. • Implementació llarga. • Hi ha variables que són particulars de cada classe.
Interfícies Objectes... Definició del interficiéMouseListener del JDK 1.4 Interface java.awt.event.MouseListener public interface MouseListener extends EventListener La interfície “Mouselistener” per rebre events del mouse en un component (botó, check ...). Métodes mouseClicked(MouseEvent) Invoked when the mouse has been clicked on a component. mouseEntered(MouseEvent) Invoked when the mouse enters a component. mouseExited(MouseEvent) Invoked when the mouse exits a component. mousePressed(MouseEvent) Invoked when a mouse button has been pressed on a component. mouseReleased(MouseEvent) Invoked when a mouse button has been released on a component. Inicialitzacions ... this.addMouseListener(new Mouse(this,1)); ... Afegeix a l’applet la capacitat de respondre als “clicks” del ratolí.
Interfícies Objectes... class Mouse implements MouseListener{atributs; public Mouse(atributs...){...} public void mouseClicked(MouseEvent e){...}; public void mouseEntered(MouseEvent e) {}; public void mouseExited(MouseEvent e){}; public void mouseReleased(MouseEvent e){}; public void mousePressed(MouseEvent e){};} Les dues primeres definidesi implementadesLes següents definides i no implementades Com podria incloure la detecció del moviment del ratoli? 1.- Afegir ... this.addMouseListener(new Mouse(this,1)); this.addMouseMotionListener(new Mouse1(this,1)); ... i la definició de la classe Mouse1 que implementa MouseMotionListener 2.- Modificar la classe Mouse class Mouse implements MouseListener,MouseMotionListener{atributs;... Afegir la implemenentació dels mètodes:public void mouseMoved(MouseEvent e){}; public void mouseDragged(MouseEvent e){};
Classes Objectes... • Com es defineixen • modificador class text ... • modificador class cout extends AppletThread ... • modificador class Mouse implements MouseListener,MouseMotionListener ... • modificador class AppletThread extends Applet implements Runnable ... • Tipus de modificadors: • abstract: la classe no és pot instanciar, els interfaces o són per defecte. • public: la classe és accessible per qualsevol classe del paquet. • final: la classe no pot ser pare d’un altre. Es donen motius de seguretat i de “qualitat de disseny” per justificar-ho. • Tota classe ha de tenir un constructor. Exemple • class text{ • private String tx;int x,y; • text(String tx,int x,int y){this.tx=tx;this.x=x;this.y=y;} • } • com es crida desde la classe GRF • private Vector tx=new Vector(); • ... • public void setText(String tx,int x,int y){ • text txAux=new text(tx,x,y); • this.tx.addElement(txAux); • } • ...
Variables i operacions Objectes... • Modificadors aplicables a les variables • Nivell d’accés: • private: La variable tant sols és accessible per la classe. • protected: La variable és accessible per la classe, subclasses i classes del paquet. • public: La variable es accessible per qualsevol altra classe. • Package: (en java) Per defecte. La variable és accessible pel paquet. • static: si volem que la variable es tracti com a classe i no com a instancia d’una variable. Útil si volem crear un vector d’enters (la classe Vector en java requereix tractar amb objectes). • final: el valor no pot canviar, és una constant. • transient: s’utilitza en serialització (indica quines variables no poden serialitzar-se). • volatile: utilitzada per evitar que el compilador faci certes optimitzacions. • Modificadors aplicables a les operacions • Nivell d’accés: Mateixos variables. • static: Si volem que la variable es tracti com a classe i no com a instancia d’una variable. • abstract: El mètode ha d’estar en una classe abstracta. • final: El mètode no pot ser reescrit en una subclasse. • native: (en java)si utilitzem una llibreria compilada en un altre llenguatge ho indiquem així. • synchronized: Si forma part d’un Thread la funció s’executarà sense interrupcions.
Polimorfisme Objectes... (Sobrecàrrega: A les funcions no els importa el tipus de variable que reben) class DBGEST{ public: int GetFValue(int,int*,int); int GetFValue(int,long*,int); int GetFValue(int,double*,int); int GetFValue(int,CString*,int); ... Al fitxer include .h ... COleVariant DBGEST::GetValue(int FieldNumber,int NRs){...} int DBGEST::GetFValue(int FieldNumber,int* Value,int NRs){ COleVariant vt=GetValue(FieldNumber,NRs); *Value=(int)vt.iVal;} int DBGEST::GetFValue(int FieldNumber,long* Value,int NRs){ COleVariant vt=GetValue(FieldNumber,NRs); *Value=(long)vt.lVal;} int DBGEST::GetFValue(int FieldNumber,double* Value,int NRs){ COleVariant vt=GetValue(FieldNumber,NRs); *Value=(double)vt.dblVal;} int DBGEST::GetFValue(int FieldNumber,CString* Value,int NRs){ COleVariant vt=GetValue(FieldNumber,NRs); *Value=(CString)vt.pbVal;} ... Implementació al fitxercpp. La clau està en que els paràmetres són diferents. He eliminat els try, catch, i retorns.
Polimorfisme Objectes... (Sobreescriure mitjançant l’herència. El pare i el fill poden tenir una funció amb el mateix nom i paràmetres) PERO!!! Applet extends PanelPanel extends ContainerContainer extends Component • Una classe ja té les funcions definides • Un altra classe es deriva d’aquesta • Es torna a definir una funció que ja existia a la pare. import java.applet.*; import java.awt.*; public class AppletThread extends Appletimplements Runnable { Thread theThread; public String getAppletInfo(){...} public void init(){} public void start(){...} public void stop(){...} public void destroy(){} public void paint(Graphics g){} public void run(){} } public class cout extends AppletThread{ public void init() {... this.add(grf=new GRF(width,height,50,75,1,2)); grf.setType(0,1);grf.setSeriecolor(Color.red,2); grf.setType(1,2);grf.setSeriecolor(Color.blue,1); ... grf.setValues(c[0].length,c[0],1,c[0].length,0); recal(); }; public void paint(Graphics g){ ... grf.drawGRF(g); ... }
Herència i classes abstractes Objectes... (Les subclasses hereden les funcions de la seva classe pare. La classe funcions) abstract class funs{private double P1=6,P2=14; protected double max=-9e100,min=9e100; protected Vector p; public double getP1(){return P1;}; public double getP2(){return P2;}; public double getMax(){...}; public double getMin(){...}; public void setP1(double valor){...}; public void setP2(double valor){...}; abstract void calcula(int t0,int tf,double increment); abstract double evaluate(double t);public Punt getP(int quin){if(quin>=p.size())return null; return(Punt)p.elementAt(quin);};} public class cout extends AppletThread{ ... private funs f; ... ... f=(funs)Class.forName(getParameter("funcio")).newInstance(); ... f.setP2(10);KpO_KpD=f.evaluate(KpO_KpD)*0.1; ... class Punt{public double x,y; ... } class logistic extends funs{logistic(){super.p= new Vector();}; public void calcula(int t0,int tf,double increment){...} public double evaluate(double t){ return Math.exp(-getP1()+getP2()*(double)t)/(1+Math.exp(-getP1()+getP2()*(double)t));} } class sin extends funs{sin(){super.p= new Vector();}; public void calcula(int t0,int tf,double increment){...} public double evaluate(double t){return getP1()*Math.sin(((double)t)*getP2());} } ... El “truco” està endefinir la variable deltipus de la classe abstracte.
Herència i classes abstractes Objectes... (Les subclasses hereden les funcions de la seva classe pare. La classe Mapes) abstract class Hole{Hole(){}; abstract boolean existHole(int elem); abstract int getHole(int elem,int n);} • class Chole extends Hole{Hole(){}; • public boolean existHoleint elem){ • if(elem==2)return true; if(elem==3)return true; if(elem==7)return true; • } • public int getHole(int elem){ • if(elem==2)return 228;//NIEDEROSTERREICH-wien • if(elem==3)return 115;//BRABANT-bruxelles • if(elem==7)return 57;//branderburg-berlin • return -1; • } • } Les implementacions poden ser diverses.El resultat és el mateix
Herència i classes abstractes Objectes... (Les subclasses hereden les funcions de la seva classe pare. La classe Mapes) type 1 poligon 2 nodes 3 arcs 4 Boles en centroid abstract class Map { protected int type[]=new int[2],style[]=new int[2]; Map(){}; public Hole hl=null; abstract boolean canSel(); abstract int getX(int elem,int pos); abstract int getY(int elem,int pos);abstract int getMax(int elem); abstract int getR(int elem); abstract int getW(int elem); abstract int getCX(int elem); abstract int getCY(int elem); abstract String getName(int muni); abstract Color getColor(int elem); abstract void setColor(int elem,Color c); } style -1 solid contorn color extern 0 solid no contorn color extern 1 solid contorn color propi 2 solid sense contorn color propi 3 no solid contorn color propi Recordeu!! el “truco” està endefinir la variable deltipus de la classe abstracte.
Herència i classes abstractes Objectes... (Les subclasses hereden les funcions de la seva classe pare. La classe Mapes) class EU2 extends Map{ private int max[]=new int[320]; private int x[][]=new int[320][165]; private int y[][]=new int[320][165];private Color c=new Color(230,230,230); private Color cc=new Color(230,230,230); EU2(){ type[0]=1;style[0]=-1;type[1]=4; style[1]=-1;count=320;nom="Regions";hl=new CHole(); ...} String getName(int id){return n[id];} public int getX(int elem,int pos){return x[elem][pos];} public int getY(int elem,int pos){return y[elem][pos];} public int getMax(int elem){return max[elem];} public Color getColor(int elem){return cc;} public void setColor(int elem,Color c){...} public int getR(int elem){return 0;} public int getW(int elem){return 0;} public int getCX(int elem){return x[elem][0];} public int getCY(int elem){return y[elem][0];} public boolean canSel(){return true;};