Clases LSUB GSYC 10 de febrero de 2016 (cc) 2015 Laboratorio de Sistemas, Algunos derechos reservados. Este trabajo se entrega bajo la licencia Creative Commons Reconocimiento NoComercial - SinObraDerivada (by-nc-nd). Para obtener la licencia completa, véase http://creativecommons.org/licenses/by-sa/2.1/es. También puede solicitarse a Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA. Clases y objetos Un objeto es una instancia de una clase, y tiene miembros: I Atributos o campos (valirables de la instancia). I Métodos u operaciones. Constructor I Es un método especial que se invoca automáticamente cuando se crea un nuevo objeto de una clase. I Su nombre es el nombre de la clase y no retorna nada. I El constructor por omisión existe si no definimos ningún constructor, y no tiene parámetros. I Si definimos nuestro constructor, perdemos en constructor por omisión. Sobrecarga I Definición de métodos con el mismo nombre pero con distintos argumentos. I Ojo: siempre hay que retornar el mismo tipo. I El constructor suele estar sobrecargado para poder inicializar un objeto de distintas formas. This Es una referencia a ti mismo. I p.move(3,4) es en realidad <Punto>move(p, 3, 4) I Si llamamos al método this(), estamos llamando a nuestro propio constructor. I Si usamos this en un constructor, tiene que estar al principio. Ası́ podemos simplificar la construcción y ahorrar código duplicado. Ocultación Las clases pueden ser: I public: son accesibles desde todas las clases. I package-private: visible desde el paquete, es ası́ si no se pone nada. Los miembros además pueden ser: I public: son accesibles desde fuera del objeto. I private: no son accesibles desde fuera del objeto. I package-private: visible desde el paquete, es ası́ si no se pone nada. Relaciones Objetivo: abstraer correctamente y no repetir código (principio DRY: don’t repeat yourself!): I Composición: una clase tiene uno o más objetos subordinados de otras clases como parte de su estado (tiene-un). I Herencia: una clase deriva de otra clase (es-un). I Delegación: una clase delega parte de su implementación en otra clase subordinada, o expone parte de la interfaz de la clase subordinada que la compone. Herencia I Relación es-un: la clase derivada es-una clase base. I Principio de Liskov: Si S es un subtipo de T, entonces cualquier objeto de clase T puede ser sustituido por un objeto de clase S sin alterar ninguna de las propiedades del programa (corrección, tarea realizada, etc.). Esto es, cualquier método que tiene sentido para un objeto de la superclase tiene que tener sentido para un objeto de la subclase. Herencia I I Una referencia de la clase base puede apuntar a un objeto de la clase derivada. Una clase derivada: I I I I I Hereda miembros. Puede añadir miembros. Puede redefinir (sobreescribir) métodos. Puede llamar al constructor de la clase base invocando a super() (al principio). Con super te refieres a la clase base. Herencia public class Instrumento { p r i v a t e boolean a f i n a d o ; public void a f i n a r (){ ... } } ... p u b l i c c l a s s G u i t a r r a extends Instrumento { p r i v a t e c u e r d a s [ ] = new C u e r d a [ 6 ] ; .... } Late (dynamic) binding I En tiempo de ejecución se decide a qué método se va a invocar. I Se invocará al método de la clase concreta referenciada. I Facilita el polimorfismo: distintas implementaciones con la misma interfaz. Ocultación (II) Además de public, private o package-private, un miembro también puede ser: I protected: son accesibles sólo desde las clases derivadas. Sobrescritura (override) I Las clases derivadas pueden reemplazar la implementación de los métodos heredados. I Ejemplo: hay que sobrescribir equals(), heredado de Object, si no deseamos que los objetos de nuestra clase se comparen en base a si son la misma instancia, sino por su contenido (p.ej. como String). I Si sobrescribimos equals, tenemos que sobrescribir hashCode, y vice versa. Clases abstractas I Una clase de la que sólo se puede heredar, que tiene sus métodos por definir (late binding). I No puede haber instancias: no podemos llamar a new con ella. I Es una forma de obligar a tener una interfaz para las clases derivadas. Clases abstractas p u b l i c a b s t r a c t c l a s s Mamifero { p r i v a t e Pelo pelo ; p r i v a t e Mama mama ; ... } ... p u b l i c c l a s s M a r s u p i a l e x t e n d s Mamifero { ... } Interfaces I Es un contrato: similar a una clase púramente abstracta. I Un clase puede implementar distintas interfaces. En Java, no hay herencia múltiple (no se puede heredar de distintas clases). I Una interfaz no tiene implementación por omisión (una clase abstracta lo puede tener, aunque puede que no sea apropiado). Interfaces public i n t e r f a c e Acondicionado { p u b l i c boolean encenderAire ( double grados ) ; p u b l i c boolean apagarAire ( ) ; p u b l i c boolean ponerTemperatura ( double grados ) ; } p u b l i c c l a s s Coche i m p l e m e n t s A c o n d i c i o n a d o { p u b l i c boolean encenderAire ( double grados ) { . . . } p u b l i c boolean apagarAire () { . . . } p u b l i c boolean ponerTemperatura ( double grados ) { . . . } } p u b l i c c l a s s Casa i m p l e m e n t s A c o n d i c i o n a d o { p u b l i c boolean encenderAire ( double grados ) { . . . } p u b l i c boolean apagarAire () { . . . } p u b l i c boolean ponerTemperatura ( double grados ) { . . . } } Miembros de clase I Existen dentro de la clase, son globales para todos los objetos de la clase. I Se indica con static. I Atributos: son útiles para definir constantes. I Métodos: son útiles para operaciones simétricas. No pueden acceder a miembros de instancia (métodos o atributos no estáticos de la clase) ni usar this. Miembros de clase p u b l i c c l a s s G u i t a r r a extends Instrumento { public static final i n t NCUERDAS = 6 ; p u b l i c s t a t i c b o o l e a n m i s m a A f i n a c i o n ( G u i t a r r a g1 , G u i t a r r a g2 ) { ... } } Clases anidadas I Clases definidas dentro de otra clase. Es un miembro de la clase que la contiene. Ventajas: I I Permite agrupar clases en un fichero. Facilita la ocultación. I Como miembros, pueden ser private, public, protected, o package private. I Dos tipos: Inner class (embebidas) y static nested class. Clases embebidas (inner) I La instancia de la clase interna está contenida en la instancia de la clase contenedora. I Tiene acceso a los miembros de la clase externa (incluidos los privados). I No puede definir miembros estáticos. Clases embebidas (inner) class Coleccion { ... class Iterador { ... } void t o S t r i n g ( ) { I t e r a d o r i = new I t e r a d o r ( ) ; ... } } Clases embebidas (inner) Para poder instanciarlas desde otra clase: C o l e c c i o n c = new C o l e c c i o n ( ) ; C o l e c c i o n . I t e r a d o r i t = c . new I t e r a d o r ( ) ; Clases anidadas estáticas (static nested class) I No está asociada con una instancia de la clase externa. I No puede acceder a miembros de instancia de la clase externa. I Interactua con los miembros de una instancia de la clase externa como cualquier otra clase de nivel superior. P r o t o c o l o . MensajeA msg = new P r o t o c o l o . MensajeA ( ) ;