!pado&en&objetos& · 2016-06-02 · – pero el offset en la tabla de funciones virtuales puede ser...

41
!pado en objetos

Transcript of !pado&en&objetos& · 2016-06-02 · – pero el offset en la tabla de funciones virtuales puede ser...

Page 1: !pado&en&objetos& · 2016-06-02 · – pero el offset en la tabla de funciones virtuales puede ser distinta, y de esta forma perder eficiencia (como en Smalltalk) • si no funciona

!pado  en  objetos  

Page 2: !pado&en&objetos& · 2016-06-02 · – pero el offset en la tabla de funciones virtuales puede ser distinta, y de esta forma perder eficiencia (como en Smalltalk) • si no funciona

tipado en Simula

•  el tipo de un objeto es su clase •  el tipo de una subclase se trata como un

subtipo del tipo asociado con la superclase •  ejemplo:

–  class A(…); ... – A class B(…); ... –  ref (A) a :- new A(…) –  ref (B) b :- new B(…) –  a := b /* legal porque B es una subclase de A */ –  ... –  b := a /* también legal, pero hay que

comprobarlo en tiempo de ejecución*/

Page 3: !pado&en&objetos& · 2016-06-02 · – pero el offset en la tabla de funciones virtuales puede ser distinta, y de esta forma perder eficiencia (como en Smalltalk) • si no funciona

tipado en Smalltalk

•  cada objeto tiene una interfaz –  interfaz = conjunto de métodos de instancia declarados

en la clase –  ejemplo:

Point { x:y:, moveDx:Dy:, x, y, draw} !ColorPoint { x:y:, moveDx:Dy:, x, y, color, draw}!

–  es una forma de tipo •  sólo los nombres de los métodos, nada sobre los argumentos de

los métodos

•  uso de objetos con tipo –  cuando se envía un mensaje a un objeto...

p draw p x:3 y:4!q color q moveDx: 5 Dy: 2!

–  la expresión anda si el mensaje está en la interfaz

Page 4: !pado&en&objetos& · 2016-06-02 · – pero el offset en la tabla de funciones virtuales puede ser distinta, y de esta forma perder eficiencia (como en Smalltalk) • si no funciona

Subtipado en C++

•  relación entre interfaces –  supongamos que la expresión tiene sentido

p msg:params -- funciona si msg está en la interfaz de p

–  substituimos p por q si la interfaz de q contains contiene a la interfaz de p

•  subtipado –  si la interfaz es un superconjunto, entonces es un

subtipo –  ej: ColorPoint es un subtipo de Point –  a veces llamado “conformidad”

Page 5: !pado&en&objetos& · 2016-06-02 · – pero el offset en la tabla de funciones virtuales puede ser distinta, y de esta forma perder eficiencia (como en Smalltalk) • si no funciona

Subtipado y herencia

•  el subtipado es implícito – no es parte del lenguaje – es un aspecto importante de cómo se

construyen los sistemas

•  la herencia es explícita – se usa para implementar sistemas – no fuerza la relación a subtipado

Page 6: !pado&en&objetos& · 2016-06-02 · – pero el offset en la tabla de funciones virtuales puede ser distinta, y de esta forma perder eficiencia (como en Smalltalk) • si no funciona

jerarquía de collection

Collection

Set

Sorted collection

Indexed

Array

Dictionary

subtipado

herencia

Updatable

isEmpty, size, includes: , …

add: remove:

sortBlock: …

at:Put:

at:

associationAt:

replaceFrom:to:with:

Page 7: !pado&en&objetos& · 2016-06-02 · – pero el offset en la tabla de funciones virtuales puede ser distinta, y de esta forma perder eficiencia (como en Smalltalk) • si no funciona

funciones virtuales vs. sobrecargadas

class parent { public:! void printclass() {printf("p ");};! virtual void printvirtual() {printf("p ");}; };!class child : public parent { public:! void printclass() {printf("c ");};! virtual void printvirtual() {printf("c ");}; };!main() {! parent p; child c; parent *q;! p.printclass(); p.printvirtual(); ! c.printclass(); c.printvirtual();! q = &p; q->printclass(); q->printvirtual();! q = &c; q->printclass(); q->printvirtual();!}!Output: p p c c p p p c

Page 8: !pado&en&objetos& · 2016-06-02 · – pero el offset en la tabla de funciones virtuales puede ser distinta, y de esta forma perder eficiencia (como en Smalltalk) • si no funciona

subtipado

•  subtipado en principio: A es un subtipo de B (A <:B) si todo objeto A se puede usar en un contexto en el que se necesitaba B sin errores de tipo ejemplo:

Point: int getX(); ! void move(int);!ColorPoint: int getX(); ! int getColor();! void move(int);! void darken(int tint);!

•  en C++: A es un subtipo de B si la clase A tiene como clase base pública a B –  esto es más débil de lo que sería necesario

Page 9: !pado&en&objetos& · 2016-06-02 · – pero el offset en la tabla de funciones virtuales puede ser distinta, y de esta forma perder eficiencia (como en Smalltalk) • si no funciona

no hay tipado sin herencia

class Point {!

public:!

int getX();!

void move(int);!

protected: ...!

private: ... !

};!

class ColorPoint { ! public:! int getX();! void move(int);! int getColor();! void darken(int);! protected: ...! private: ... !

};!

C++  no  trata  este  ColorPoint  como  sub!po  de  Point,  pero  Smalltalk  sí  lo  haría  

Page 10: !pado&en&objetos& · 2016-06-02 · – pero el offset en la tabla de funciones virtuales puede ser distinta, y de esta forma perder eficiencia (como en Smalltalk) • si no funciona

slide 10

por qué esta decisión de diseño?

•  el código de cliente depende sólo de la interfaz pública –  en principio, si la interfaz de ColorPoint contiene

a la interfaz de Point los clientes podrían usar ColorPoint en lugar de Point (como en Smalltalk)

–  pero el offset en la tabla de funciones virtuales puede ser distinta, y de esta forma perder eficiencia (como en Smalltalk)

•  si no funciona ligada a la herencia, el subtipado lleva a pérdida de eficiencia

•  también por encapsulación: el subtipado basado en herencia se preserva si hacemos modificaciones en la clase base

Page 11: !pado&en&objetos& · 2016-06-02 · – pero el offset en la tabla de funciones virtuales puede ser distinta, y de esta forma perder eficiencia (como en Smalltalk) • si no funciona

slide 11

subtipado de funciones

•  subtipado en principio: A es un subtipo de B (A <: B) si una expresión A se puede usar en todo contexto en el que se requiere una expresión B

•  subtipado para resultados de función –  si A es un subtipo de B, entonces C → A es un

subtipo de C → B –  covariante: A <: B implica F(A) <: F(B)

•  subtipado para argumentos de función –  si A <: B, entonces B → C <: A → C –  contravariante: A <: B implica F(B) <: F(A)

Page 12: !pado&en&objetos& · 2016-06-02 · – pero el offset en la tabla de funciones virtuales puede ser distinta, y de esta forma perder eficiencia (como en Smalltalk) • si no funciona

para  saber  más...  ...  sobre  covariación  y  contravariación:  hAp://en.wikipedia.org/wiki/Covariance_and_contravariance_(computer_science)  es  seguro  sus!tuir  una  función  f  en  el  lugar  de  una  función  g  si  f acepta  un  !po  más  general  de  argumentos  y  devuelve  un  !po  más  específico  que  g (el  constructor  de  !po  ->  es  contravariante  en  el  !po  del  iput  y  covariante  en  el  !po  del  output).    Por  ejemplo,  si  tenemos  una  función  gato -> animal la  podemos  sus!tuir  por  gato -> gato o  por  animal -> animal,    pero  no  podríamos  si  en  lugar  de  gato -> animal  tuviéramos  animal -> gato.  

Page 13: !pado&en&objetos& · 2016-06-02 · – pero el offset en la tabla de funciones virtuales puede ser distinta, y de esta forma perder eficiencia (como en Smalltalk) • si no funciona

ejemplos

•  si circle <: shape, entonces

los  compiladores  de  C++  reconocen  sólo  algunas  formas  de  sub!pado  de  función  

circle  →  shape        

shape  →  shape      circle  →  circle      

shape  →  circle  

Page 14: !pado&en&objetos& · 2016-06-02 · – pero el offset en la tabla de funciones virtuales puede ser distinta, y de esta forma perder eficiencia (como en Smalltalk) • si no funciona

subtipado con funciones

•  en principio, podríamos tener ColorPoint <: Point •  en la práctica, algunos compiladores lo permiten y

otros no

class  Point  {        public:              int  getX();              virtual  Point  *move(int);          protected:        ...          private:                ...                                  };  

class  ColorPoint:  public  Point  {              public:                int  getX();                    int  getColor();                ColorPoint  *  move(int);                void  darken(int);        protected:        ...        private:                ...                              };  

heredado, pero lo repetimos acá por claridad

Page 15: !pado&en&objetos& · 2016-06-02 · – pero el offset en la tabla de funciones virtuales puede ser distinta, y de esta forma perder eficiencia (como en Smalltalk) • si no funciona

tipos en Java

•  dos clases generales de tipos –  tipos primitivos que no son objetos: enteros, booleanos

–  tipos de referencia: clases, interfaces, arrays

•  chequeo estático de tipos –  toda expresión tiene tipo, determinado por sus partes –  algunas conversiones automáticas, muchos casteos se

comprueban en tiempo de ejecución –  ejemplo, si tenemos A <: B

•  si A x, se puede usar x como argumento para un método que requiere B

•  si B x, entonces podemos intentar castear a A •  el casteo se comprueba en tiempo de ejecución, y puede levantar

una excepción

Page 16: !pado&en&objetos& · 2016-06-02 · – pero el offset en la tabla de funciones virtuales puede ser distinta, y de esta forma perder eficiencia (como en Smalltalk) • si no funciona

clasificación de tipos de java tipos de referencia

tipos primitivos

int

Shape

Object[ ]

Object

Shape[ ]

boolean …

Throwable

Square Square[ ] Circle Circle[ ]

long float byte

tipos de excepción

definidos por usuario arrays

Page 17: !pado&en&objetos& · 2016-06-02 · – pero el offset en la tabla de funciones virtuales puede ser distinta, y de esta forma perder eficiencia (como en Smalltalk) • si no funciona

subtipado

•  tipos primitivos –  conversiones: int -> long, double -> long, …

•  subtipado de clase semejante a C++ –  una subclase produce un subtipo –  herencia simple => las subclases forman un árbol

•  Interfaces –  clases completamente abstractas, sin implementación –  subtipado múltiple: una interfaz puede tener múltiples subtipos,

que la implementan, la extienden

•  Arrays –  subtipado covariante

Page 18: !pado&en&objetos& · 2016-06-02 · – pero el offset en la tabla de funciones virtuales puede ser distinta, y de esta forma perder eficiencia (como en Smalltalk) • si no funciona

subtipado en clases

•  conformidad de la signatura –  las signaturas de las subclases tienen que

conformar a la de la superclase •  formas conformantes en que puede variar

la signatura: –  tipos de los argumentos –  tipo del resultado – excepciones – en Java 1.1, los argumentos y resultados

debían tener tipos idénticos – en Java 1.5 se permite especialización de tipo

covariante

Page 19: !pado&en&objetos& · 2016-06-02 · – pero el offset en la tabla de funciones virtuales puede ser distinta, y de esta forma perder eficiencia (como en Smalltalk) • si no funciona

subtipado en interfaces: ejemplo interface Shape {!!public float center();! public void rotate(float degrees);!}!interface Drawable {!!public void setColor(Color c);! public void draw();!}!class Circle implements Shape, Drawable {!  //  no  hereda  ninguna  implementación  

     //  pero  !ene  que  definir  los  métodos  de  Shape  y  Drawable  }!

Page 20: !pado&en&objetos& · 2016-06-02 · – pero el offset en la tabla de funciones virtuales puede ser distinta, y de esta forma perder eficiencia (como en Smalltalk) • si no funciona

propiedades de las interfaces

•  flexibilidad –  permite un grafo de subtipado, en lugar de un árbol –  evita problemas con herencia múltiple de

implementaciones (como la herencia en diamante de C++)

•  coste –  no se conoce el offset en la tabla de consulta de

métodos (method lookup table) en tiempo de compilación

–  hay diferentes bytecodes para consulta de métodos: •  uno cuando se conoce la clase •  otro cuando sólo se conoce la interfaz

Page 21: !pado&en&objetos& · 2016-06-02 · – pero el offset en la tabla de funciones virtuales puede ser distinta, y de esta forma perder eficiencia (como en Smalltalk) • si no funciona

tipos arreglo

•  Automatically defined –  Array type T[ ] exists for each class, interface type T –  Cannot extended array types (array types are final) –  Multi-dimensional arrays are arrays of arrays: T[ ] [ ]

•  Treated as reference type –  An array variable is a pointer to an array, can be null –  Example: Circle[] x = new Circle[array_size] –  Anonymous array expression: new int[] {1,2,3, ... 10}

•  Every array type is a subtype of Object[ ], Object –  Length of array is not part of its static type

Page 22: !pado&en&objetos& · 2016-06-02 · – pero el offset en la tabla de funciones virtuales puede ser distinta, y de esta forma perder eficiencia (como en Smalltalk) • si no funciona

Array subtyping

•  Covariance –  if S <: T then S[ ] <: T[ ]

•  Standard type error class A {…} class B extends A {…} B[ ] bArray = new B[10] A[ ] aArray = bArray // considered OK since B[] <: A[]

aArray[0] = new A() // compiles, but run-time error

// raises ArrayStoreException

Page 23: !pado&en&objetos& · 2016-06-02 · – pero el offset en la tabla de funciones virtuales puede ser distinta, y de esta forma perder eficiencia (como en Smalltalk) • si no funciona

Covariance problem again …

•  Remember Simula problem –  If A <: B, then A ref <: B ref – Needed run-time test to prevent bad assignment – Covariance for assignable cells is not right in

principle •  Explanation

–  interface of “T reference cell” is put : T → T ref get : T ref → T

– Remember covariance/contravariance of functions

Page 24: !pado&en&objetos& · 2016-06-02 · – pero el offset en la tabla de funciones virtuales puede ser distinta, y de esta forma perder eficiencia (como en Smalltalk) • si no funciona

Afterthought on Java arrays Date: Fri, 09 Oct 1998 09:41:05 -0600 From: bill joy Subject: …[discussion about java genericity] actually, java array covariance was done for less noble reasons …: it made some generic "bcopy" (memory copy) and like operations much easier to write... I proposed to take this out in 95, but it was too late (...). i think it is unfortunate that it wasn't taken out... it would have made adding genericity later much cleaner, and [array covariance] doesn't pay for its complexity today.

wnj

Page 25: !pado&en&objetos& · 2016-06-02 · – pero el offset en la tabla de funciones virtuales puede ser distinta, y de esta forma perder eficiencia (como en Smalltalk) • si no funciona

programación genérica

•  la clase Object es supertipop de todos los tipos objeto – esto permite polimorfismo en objetos, porque

se pueden aplicar las operacines de la clase T a toda subclase S <: T

•  Java 1.0 – 1.4 no tenían genéricos, y se consideró una gran limitación

Page 26: !pado&en&objetos& · 2016-06-02 · – pero el offset en la tabla de funciones virtuales puede ser distinta, y de esta forma perder eficiencia (como en Smalltalk) • si no funciona

ejemplo de construcción genérica: pila

•  se pueden hacer pilas para cualquier tipo de objeto, y las operaciones asociadas a pila pila funcionan para cualquier tipo

•  en C++ tendríamos la clase genérica stack!!!template <type t> class Stack {!!! !private: t data; Stack<t> * next;!!! !public: void push (t* x) { … }!

! ! t* pop ( ) { … } !!!};!

•  qué se puede hacer en Java 1.0?

Page 27: !pado&en&objetos& · 2016-06-02 · – pero el offset en la tabla de funciones virtuales puede ser distinta, y de esta forma perder eficiencia (como en Smalltalk) • si no funciona

Java 1.0 vs genéricos class Stack {! void push(Object o)

{ ... }! Object pop() { ... }! ...}!!String s = "Hello";!Stack st = new Stack(); !...!st.push(s);!...!s = (String) st.pop();!

class Stack<A> {! void push(A a) { ... }! A pop() { ... }! ...}!!!String s = "Hello";!Stack<String> st = ! new Stack<String>();!st.push(s);!...!s = st.pop();!

Page 28: !pado&en&objetos& · 2016-06-02 · – pero el offset en la tabla de funciones virtuales puede ser distinta, y de esta forma perder eficiencia (como en Smalltalk) • si no funciona

por qué no se incorporan al principio?

•  muchas distintas propuestas •  los objetivos básicos del lenguaje parecían

cubiertos •  varios detalles que requieren esfuerzo

–  precisar exactamente las restricciones de tipado –  implementación

•  en la virtual machine que ya existe? •  bytecodes adicionales? •  duplicar el código para cada instancia? •  usar el mismo código, con casteos, para todas las

instancias

la propuesta de la comunidad de Java (JSR 14) se incorpora a Java 1.5

Page 29: !pado&en&objetos& · 2016-06-02 · – pero el offset en la tabla de funciones virtuales puede ser distinta, y de esta forma perder eficiencia (como en Smalltalk) • si no funciona

JSR 14 Java Generics (Java 1.5, “Tiger”)

•  Adopts syntax on previous slide •  Adds auto boxing/unboxing

User conversion Automatic

conversion Stack<Integer>  st  =              new    Stack<Integer>();  st.push(new  Integer(12));  ...  int  i  =  (st.pop()).intValue();  

Stack<Integer>  st  =              new    Stack<Integer>();  st.push(12);  ...  int  i  =  st.pop();    

Page 30: !pado&en&objetos& · 2016-06-02 · – pero el offset en la tabla de funciones virtuales puede ser distinta, y de esta forma perder eficiencia (como en Smalltalk) • si no funciona

los genéricos de Java tienen comprobación de tipos

•  una clase genérica usa operaciones en un tipo de parámetros –  Example: PriorityQueue<T> … if x.less(y)

then … •  Two possible solutions

– C++: Link and see if all operations can be resolved

–  Java: Type check and compile generics w/o linking

•  May need additional information about type parameter –  What methods are defined on parameter type? –  Example: PriorityQueue<T extends ...>

Page 31: !pado&en&objetos& · 2016-06-02 · – pero el offset en la tabla de funciones virtuales puede ser distinta, y de esta forma perder eficiencia (como en Smalltalk) • si no funciona

Example •  Generic interface

•  Generic class implementing Collection interface class LinkedList<A> implements Collection<A> { protected class Node { A elt; Node next = null; Node (A elt) { this.elt = elt; } } ... }

interface Iterator<E> { E next(); boolean hasNext(); }

interface Collection<A> { public void add (A x); public Iterator<A> iterator (); }

Page 32: !pado&en&objetos& · 2016-06-02 · – pero el offset en la tabla de funciones virtuales puede ser distinta, y de esta forma perder eficiencia (como en Smalltalk) • si no funciona

Wildcards

•  Example void printElements(Collection<?> c) { for (Object e : c) System.out.println(e); }

•  Meaning: Any representative from a family of types –  unbounded wildcard ?

•  all types

–  lower-bound wildcard ? extends Supertype •  all types that are subtypes of Supertype

–  upper-bound wildcard ? super Subtype •  all types that are supertypes of Subtype

Page 33: !pado&en&objetos& · 2016-06-02 · – pero el offset en la tabla de funciones virtuales puede ser distinta, y de esta forma perder eficiencia (como en Smalltalk) • si no funciona

Type concepts for understanding Generics

•  Parametric polymorphism – max : ∀t ((t × t) → bool) → ((t × t) → t)

•  Bounded polymorphism – printString : ∀t <: Printable . t → String

•  F-Bounded polymorphism

–  max : ∀t <: Comparable (t) . t × t → t

given lessThan function return max of two arguments

for every subtype t of Printable function from t to String

for every subtype t of … return max of object and argument

Page 34: !pado&en&objetos& · 2016-06-02 · – pero el offset en la tabla de funciones virtuales puede ser distinta, y de esta forma perder eficiencia (como en Smalltalk) • si no funciona

F-bounded subtyping

•  Generic interface interface Comparable<T> { public int compareTo(T arg); }

•  x.compareTo(y) = negative, 0, positive if y is < = > x

•  Subtyping

interface A { public int compareTo(A arg); int anotherMethod (A arg); … } <: interface Comparable<A> { public int compareTo(A arg); }

Page 35: !pado&en&objetos& · 2016-06-02 · – pero el offset en la tabla de funciones virtuales puede ser distinta, y de esta forma perder eficiencia (como en Smalltalk) • si no funciona

Example static max method

•  Generic interface interface Comparable<T> { public int compareTo(T arg); … }

•  Example public static <T extends Comparable<T>> T max(Collection<T> coll) { T candidate = coll.iterator().next(); for (T elt : coll) { if (candidate.compareTo(elt) < 0) candidate = elt; } return candidate; }

candidate.compareTo : T → int

Page 36: !pado&en&objetos& · 2016-06-02 · – pero el offset en la tabla de funciones virtuales puede ser distinta, y de esta forma perder eficiencia (como en Smalltalk) • si no funciona

This would typecheck without F-bound …

•  Generic interface interface Comparable<T> { public int compareTo(T arg); … }

•  Example public static <T extends Comparable<T>> T max(Collection<T> coll) { T candidate = coll.iterator().next(); for (T elt : coll) { if (candidate.compareTo(elt) < 0) candidate = elt; } return candidate; }

candidate.compareTo : T → int

Object

Object

How could you write an implementation of this interface?

Page 37: !pado&en&objetos& · 2016-06-02 · – pero el offset en la tabla de funciones virtuales puede ser distinta, y de esta forma perder eficiencia (como en Smalltalk) • si no funciona

Generics are not co/contra-variant

•  Array example (review) Integer[] ints = new Integer[] {1,2,3}; Number[] nums = ints; nums[2] = 3.14; // array store -> exception at run

time •  List example

List<Integer> ints = Arrays.asList(1,2,3); List<Number> nums = ints; // compile-time error –  Second does not compile because List<Integer> <: List<Number>

Page 38: !pado&en&objetos& · 2016-06-02 · – pero el offset en la tabla de funciones virtuales puede ser distinta, y de esta forma perder eficiencia (como en Smalltalk) • si no funciona

Return to wildcards

•  Recall example void printElements(Collection<?> c) {

for (Object e : c) System.out.println(e); }

•  Compare to void printElements(Collection<Object> c) {

for (Object e : c) System.out.println(e);

} –  This version is much less useful than the old one

•  Wildcard allows call with kind of collection as a parameter, •  Alternative only applies to Collection<Object>, not a supertype of

other kinds of collections!

Page 39: !pado&en&objetos& · 2016-06-02 · – pero el offset en la tabla de funciones virtuales puede ser distinta, y de esta forma perder eficiencia (como en Smalltalk) • si no funciona

Implementing Generics

•  Type erasure – Compile-time type checking uses generics – Compiler eliminates generics by erasing them

•  Compile List<T> to List, T to Object, insert casts

•  “Generics are not templates” – Generic declarations are typechecked – Generics are compiled once and for all

•  No instantiation •  No “code bloat”

More later when we talk about virtual machine …

Page 40: !pado&en&objetos& · 2016-06-02 · – pero el offset en la tabla de funciones virtuales puede ser distinta, y de esta forma perder eficiencia (como en Smalltalk) • si no funciona

Additional links for material not in book

•  Enhancements in JDK 5 – http://java.sun.com/j2se/1.5.0/docs/guide/

language/index.html •  J2SE 5.0 in a Nutshell

– http://java.sun.com/developer/technicalArticles/releases/j2se15/

•  Generics – http://www.langer.camelot.de/Resources/

Links/JavaGenerics.htm

Page 41: !pado&en&objetos& · 2016-06-02 · – pero el offset en la tabla de funciones virtuales puede ser distinta, y de esta forma perder eficiencia (como en Smalltalk) • si no funciona

Type Safety of JVM

•  Run-time type checking – All casts are checked to make sure type safe – All array references are checked to make sure the

array index is within the array bounds – References are tested to make sure they are not

null before they are dereferenced. •  Additional features

– Automatic garbage collection – No pointer arithmetic

If program accesses memory, that memory is allocated to the program and declared with correct type