Download Conceptos más avanzados de Programación Orientada a Objetos

Document related concepts
no text concepts found
Transcript
Conceptos más avanzados de
Programación Orientada a Objetos
Programación 2008
Licenciatura de Lingüística y Nuevas Tecnologías
Repaso: API de Java
• API = Application Programming Interface
• Una API describe la especificación de los datos y
subrutinas para una aplicación especifica que cualquier
programador puede integrar en su código.
• La API estándar de Java define una librería jerarquizada
de clases con la definición de sus métodos y datos
asociados.
• La API de Java esta organizada por paquetes (packages).
• Las clases en la API de Java están organizadas como un
árbol, con Object como la clase raíz. Todas las demás
clases son subclases (directas o indirectas) de Object.
• Cualquiera nueva clase que creamos es automáticamente una
sub-clase de Object.
Herencia
• La herencia permite definir una clase muy general y luego
definir clases más especializadas que contienen más detalle.
– Clase general = super-clase, clase madre, clase de base
– Clase especializada = sub-clase, clase hija, clase derivada
• Después de desarrollar la clase general, solo tenemos que
escribir la diferencia, o el código especializado de la clase
derivada.
• Conseguimos una jerarquía de clases
– Clase arriba de la jerarquía = clase ancestro
– Clase abajo de la jerarquía = clase decendiente
• Una clase hija hereda los métodos y variables de instancia de
una clase madre (y de todos sus ancestros).
3
Herencia
• Ejemplo 1: La clase Morpho tiene como subclases
Verb, Noun, etc.
Morpho.java , Noun.java ,Verb.java, Main.java
• La palabra clave extends permite definir una clase madre para
una subclase.
• Verb y Noun heredan de Morpho: heredan las variables de
instancia “lemma” y “category” e el método imprimir().
• Verb y Noun definen sus propias variables y métodos.
• EL constructor de Verb llama de forma explicita al constructor de
su super-clase con la palabra clave super.
• El constructor de Noun llama de forma implicita al constructor por
defecto de su super-clase.
• En el Main de Ejemplo 1, una variable de objeto de tipo Morpho
puede apuntar a cualquier objeto de tipo Morpho o de una subclase de Morpho.
4
public class Morpho {
String lemma;
String category;
public class Verb extends Morpho {
String tense;
String person;
String number;
String aspect;
public Morpho() { }
public Morpho(String l,String c) {
lemma = l;
category = c;
}
}
public void imprimir() {
System.out.println(lemma + "/" + category);
}
}
public Verb(String lemma,String tense,String person,String number,String aspect) {
super(lemma,"Verb");
this.tense = tense;
this.person = person;
this.number = number;
this.aspect = aspect;
}
public class Noun extends Morpho {
String gender;
String person;
String number;
}
public Noun(String lemma, String gender, String person, String number) {
this.lemma = lemma;
this.category = "Noun";
this.person = person;
this.number = number;
this.gender = gender;
}
public class Main {
public static void main(String[] args) {
Noun thisNoun = new Noun("perro","masculine","third","singular");
Verb thisVerb = new Verb("ladra","present","third","singular","indicative");
}
}
thisNoun.imprimir();
thisVerb.imprimir();
Morpho thisMorpho = new Verb("ladra","present","third","singular","indicative");
thisMorpho.imprimir();
thisMorpho = new Morpho("el","Det");
thisMorpho.imprimir();
5
Overriding
• Ejemplo 2: Las subclases pueden redefinir los
métodos de su superclase. Se llama overriding
Morpho.java , Noun.java ,Verb.java, Main.java
• Noun y Verb redefinen el método imprimir de Verb. Al
llamar el imprimir de un objeto de tipo Verb, se llama
el imprimir de Verb (y no al imprimir de Morpho).
6
public class Morpho {
String lemma;
String category;
public Morpho() { }
public class Verb extends Morpho {
String tense;
String person;
String number;
String aspect;
//... MISMO CONSTRUCTOR QUE ANTES
public Morpho(String l,String c) {
lemma = l;
category = c;
}
}
public void imprimir() {
System.out.println(lemma + "/" + category);
}
}
}
public void imprimir() {
System.out.println(lemma + "/" + category + "[TENSE: " + tense +
" ASPECT: " + aspect + " PERSON: " + person +
" NUMBER: " + number + "]");
public class Noun extends Morpho {
String gender;
String person;
String number;
// ....MISMO CONSTRUCTOR QUE ANTES
}
public void imprimir() {
System.out.println(lemma + "/" + category +
"[GENDER: " + gender + " PERSON: " + person +
" NUMBER: " + number);
}
public class Main {
public static void main(String[ ] args) {
Noun thisNoun = new Noun("perro","masculine","third","singular");
Verb thisVerb = new Verb("ladra","present","third","singular","indicative");
thisNoun.imprimir();
thisVerb.imprimir();
}
}
Morpho thisMorpho = new Verb("ladra","present","third","singular","indicative");
thisMorpho.imprimir();
thisMorpho = new Morpho("el","Det");
thisMorpho.imprimir();
7
Herencia y API de Java
•
En la documentación de la API de Java, se da para cada clase su posición en la
jerarquia (cuales son sus super-clases) y sus subclases directas. Por ejemplo, la
clase Number tiene como super-clase Object y como subclases directas (entre
otras) Integer, Double, Float:
http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Number.html
•
Además del listado de los métodos de la clase, se proporciona las listas de los
métodos heredados de cada super-clase. Por ejemplo, con FileWriter utilizamos
el método void write(String s) de su super-clase indirecta Write:
http://java.sun.com/j2se/1.4.2/docs/api/java/io/FileWriter.html
•
Overriding: La clase Object define el método equals(). Su subclase String lo
redefine para la comparación de objetos de tipo String.
8
Clases abstractas
•
•
•
•
Definición de la clase Number en la API de Java:
public abstract class Number extends Object {...}
Una clase abstracta es una clase que nunca se puede instanciar. O sea
que no podemos tener objetos del tipo de una clase abstracta.
No podemos tener objetos de tipo Number, pero sí podemos instanciar
objetos con las subclases de Number (que no son abstractas). Por
ejemplo lo siguiente provoca un error de compilación:
Number n = new Number();
java.lang.Number is abstract; cannot be instantiated
Una clase abstracta sirve para agrupar conceptualmente sub-clases y
definir métodos y variables que heredan sus sub-clases.
9
Métodos abstractos
• Una clase abstracta puede definir métodos abstractos.
•
•
Un método abstracto no tiene definición (o cuerpo). Lo hereden las
subclases, y cada una tiene que darle una implementación especifica, o
sea redefinirla (overrides).
Un método abstracto se declara así (con el punto coma al final y sin
llaves):
abstract tipoDeStalida methodName(parametros-entrada);
• La clase Number define los siguientes métodos abstractos:
doubleValue() , floatValue() , intValue(), longValue(), shortValue().
• Estos métodos están redefinidos (overriden) por obligación por
las subclases de Number: Integer, Float, Double. Por ejemplo,
podemos ver estos métodos en la API de Integer:
http://java.sun.com/j2se/1.3/docs/api/java/lang/Integer.html
10
Clases y métodos abstractos
• ¿Tiene sentido tener a la clase Morpho como una clase
abstracta?
• ¿Tiene sentido tener el método imprimir de Morpho
como método abstracto?
• Ejemplo 3: Morpho.java, Verb.java, Noun.java, Main.java
11
public abstract class Morpho {
String lemma;
String category;
public Morpho() {
}
public Morpho(String l,String c) {
lemma = l;
category = c;
}
}
Si Noun y Verb no definen el método
imprimir, tendremos un error de compilación!
public abstract void imprimir();
public class Main {
public static void main(String[] args) {
Noun thisNoun = new Noun("perro","masculine","third","singular");
Verb thisVerb = new Verb("ladra","present","third","singular","indicative");
thisNoun.imprimir();
thisVerb.imprimir();
}
}
Morpho thisMorpho = new Verb("ladra","present","third","singular","indicative");
thisMorpho.imprimir();
// Estas llamadas no las podemos hacer: no se puede instanciar un objeto de tipo Morpho
//thisMorpho = new Morpho("el","Det");
//thisMorpho.imprimir();
12
Polimorfismo con Overriding
•
•
•
Una variable de objeto puede apuntar a cualquier objeto de la clase
que le corresponde o de las sub-clases de esta clase. Por ejemplo,
partiendo del Ejemplo 3:
– Morpho morpho1= new Verb(....);
– Morpho morpho2= new Noun(....);
morpho1.imprimir() llama al imprimir de Verb; morpho2.imprimir() llama al
imprimir de Noun.
Esta capacidad de diferentes objetos de comportarse de diferentes
formas con el mismo mensaje (i.e., método) se llama polimorfismo.
13
Polimorfismo con Overriding
•
¿En qué nos interesa el polimorfismo?
Por ejemplo, podemos tener un ArrayList de categorias (Verb,
Noun,etc). Podemos imprimir en bucle cada uno de los objetos del
ArrayList con imprimir(), confiando que se llamará el método
imprimir() relevante para cada caso.
14
Overloading
•
•
•
El nombre del método no es suficiente para identificar de manera única a un
método dentro de una clase. También sirven el número y tipo de los argumentos
de entrada.
El nombre de un método juntos con su argumentos de entrada se llama
signature (firma), porque identifica de manera única a un método.
Por ejemplo, la clase String tiene dos métodos substring distintos (el
segundo tiene un argumento extra):
–
–
•
Otro ejemplo: la clase Math tiene cuatro métodos con nombre max para
devolver el máximo de dos numero, entre otros:
–
–
•
public String substring(int beginIndex)
public String substring(int beginIndex,int endIndex)
public static double max(double a, double b)
public static int max(int a, int b)
Esta habilidad de métodos (y constructores) a tener el mismo nombre pero a
distinguirse por los argumentos de entrada se llama method overloading.
15
Polimorfismo con Overloading
•
La clase java.io.PrintStream tiene varios métodos print() con firmas
diferentes:
–
–
–
–
–
–
–
–
–
•
public void print(boolean b)
public void print(char c)
public void print(char[] s)
public void print(float f)
public void print(double d)
public void print(int i)
public void print(long l)
public void print(Object obj)
public void print(String s)
Cuando escribimos: System.out.print(variable), el método llamado
depende del tipo de variable. Esto es polimorfismo con overloading de
método.
16
Interfaz
•
•
•
•
•
Una interfaz contiene las firmas (signature) de unos métodos. No
implementa ninguno.
La clase que implementa una interfaz tiene que implementar los
métodos declarados en la interfaz.
Dicho de otro modo: una interfaz define un contrato que una clase
que la implementa tiene que cumplir.
Esto no es lo mismo que la herencia. Una interfaz no forma parte de la
jerarquia de clases de Java.
Una interfaz se define con la palabra clave interface:
public interface Collection { ... }
•
Se dice que una clase implementa una interfaz y se utiliza la palabra
clave implements. Por ejemplo:
public class ArrayList ... implements List {...}
17
Interfaz
•
Los ventajas de una interfaz sobre una super-clase (abstracta) son:
– No tenemos que forzar una jerarquía de clases si lo único que queremos es
que se cumpla algun contrato. Por ejemplo, queremos poder decir que un
Coche (o una Casa) es un Bien Imponible sin tener que decir que Coche es
una subclase de BienImponible.
– Como en Java no es posible tener más de una clase madre, usamos
interfaces para describir propiedades adicionales de los objetos. Por
ejemplo, un Coche es un Vehiculo (super-clase) pero también un Bien
Imponible (interfaz que define las propiedades de los bienes imponibles) y
un Objeto Polutante (interfaz que define las propiedades de los objetos
polutantes).
18