2.8 Constructores e instanciacion - ajpaez/OCA GitHub Wiki

(OCA Objectives 6.4, 6.5, and 7.5)

Todos los objetos son construidos. No puedes crear un nuevo objeto sin invocar a su constructor y también a cada uno de los de sus superclases. Los constructores se ejecutan con la invocación a new, al igual que los bloques init y los bloques static.

Constructor Básico

Todas las clase, incluyendo las abstractas, DEBEN tener un constructor.

Los constructores no tienen return y su nombre coincide con el de la clase.

Cadena de constructores

  1. Se invoca al constructor de Horse. Cada constructor invoca al constructor de su superclase (implícitamente) llamando a super(), a menos que el constructor invoque un constructor sobrecargado de la misma clase.
  2. Se invoca al constructor de Animal
  3. Se invoca al constructor de object. Es el tope de la pila.
  4. Se asignan los valores explícitos dados en Object a sus variables de instancia. (se entiende como valores explícitos los asignados en el momento de declararlas int x = 1; donde 1 es su valor explicito)
  5. El constructor de Object completa
  6. Se asignan los valores explícitos dados en Animal a sus variables de instancia
  7. El constructor de Animal completa
  8. Se asignan los valores explícitos dados en Horse a sus variables de instancia
  9. El constructor de Horse completa
4. Object()
3. Animal() calls super()
2. Horse() calls super()
1. main() calls new Horse()

Reglas en los constructores

  • Los constructores pueden usar cualquier modificador de acceso, incluyendo privado.
  • El nombre de los constructores deben de ser el mismo que el de la clase
  • Los constructores no pueden devolver ningún tipo
  • Es legal tener un método con el mismo nombre que el constructor pero con algún tipo de return.
  • Si la clase no tiene constructor, el constructor por defecto es creado automáticamente por el compilador
  • El constructor por defecto es SIEMPRE sin parámetros
  • Si existe un constructor el compilador no genera el constructor por defecto
  • Cada constructor tiene en su primera linea de declaración: o bien una llamada a un constructor sobrecargado, o una llamada a this() o una llamada a la superclase (super()) insertada por el compilador
  • Las llamadas a super() pueden incluir o no argumentos
  • No se puede hacer una llamada a un método de instancia o acceder a una variable de instancia hasta que termine la llamada a super()
  • Solo variables y métodos estáticos pueden ser accedidos como parte de la llamada a super() o this(). Ej: super(Animal.NAME)
  • Las clases abstractas tienen constructor y siempre es llamada cuando una clase concreta de esta se instancia.
  • Interfaces no tiene constructor.Interfaces no son parte del árbol de herencia de los objetos.
  • El único lugar desde el que se puede llamar a un constructor es desde otro constructor.
class Horse {
  Horse() { } // constructor
  void doStuff() {
    Horse();  // calling the constructor - illegal!
  }
}

¿Que ocurre si el constructor por defecto tiene argumentos?

Dado que existe la posibilidad de no tener constructor por defecto, cuando se indica uno con parámetros explicitamente, si intentamos invocar al constructor por defecto el compilador se quejará. Lo mismo ocurre para el constructor de una subclase, tanto si se indica la llamada a super() de forma explicita como de forma implícita, fallará igual.

class Animal {
  Animal(String name) { }
}
class Horse extends Animal {
  Horse() {
    super();  // Problem!
  }
}
//---------------------------
class Clothing {
  Clothing(String s) { }
}
class TShirt extends Clothing { }

Ambas códigos fallara su compilación.

Sobrecarga de constructores

Los constructores al igual que los métodos se pueden sobrecargas sin problemas.

REGLA CLAVE: La primera linea de un constructor desde ser una llamada a super() o this() Si no tiene ninguna el compilador inserta una llamada a super(). Pero NUNCA podrá tener ambas this() y super()

Bloques de inicialización

Son bloques de código donde ejecutar código cuando la clase es cargada por primera vez (un bloque de inicialización estático) o cada vez que una instancia es creada (un bloque de inicialización de instancia).

class SmallInit {
  static int x;
  int y;
  static { x = 7 ; }       // static init block
  { y = 8; }               // instance init block
}

Los bloques init de instancia se ejecutan después de ejecutar todos los constructores super. Se pueden tener varios bloques de inicialización en la clase, y se ejecutaran en el mismo orden en el que aparecen en la clase, de arriba abajo.

Si cometemos algún error en un bloque de inicialización la JVM arroja ExceptionInInitializerError.