domingo, 4 de junio de 2017

Un resumen de Scala for the Impatient, parte 20


Encadenado de paquetes

La definición de paquetes puede tener nombres encadenados por punto, por ejemplo:

package com.horstmann.impatient {
   package people {
     class Person
     …
  }
}

Notación Top-of-File

Similar a java podemos optar por notación al principio de la clase, este paquete va a finalizar en el final del archivo. Por ejemplo:

package com.horstmann.impatient
package people
class Person


Esto es similar a :

package com.horstmann.impatient {
package people {
class Person
...
// Until the end of the file
}
}

Esta notación es útil cuando tenemos un solo paquete para todo un archivo.

Objetos paquete

Un paquete puede contener object, class o traits pero no una definición de funciones o variables por limitaciones en la maquina virtual java. Pero se puede definir un objeto paquete, este objeto contendrá variables o funciones globales en el paquete.

Veamos un ejemplo:

package com.horstmann.impatient
package object people {
val defaultName = "John Q. Public"
}
package people {
class Person {
var name = defaultName // A constant from the package
}
...
}

Note que defaultName no es necesario dado que se encuentra en un objeto con el mismo nombre del paquete, y podemos acceder a los valores desde otro paquete con el siguiente nombre: com.horstmann.impatient.people.defaultName

Es buena idea crear usar el mismo esquema de paquetes que los directorios de los archivos fuente. Y podemos poner un archivo package.scala donde van a estar los objetos de paquete, para tener una convención.

Visibilidad de paquetes. 

En java si una clase no es declarada como publica, privada o protected, es default y solo puede ser vista en el paquete. En scala existen calificadores que nos permiten hacer esto y tener mayor control de la visibilidad:

package com.horstmann.impatient.people
class Person {
private[people] def description = "A person with name " + name
...
}

Y se puede extender la visibilidad a paquetes padres:

private[impatient] def description = "A person with name " + name

Imports

Podemos importar una clase particular, para no utilizar el nombre largo:

import java.awt.Color

o podemos importar todos los elementos de un paquete de la siguiente manera:

import java.awt._

Como podemos ver es similar al * de java. También se pueden importar todos los miembros de una clase o objeto:

import java.awt.Color._
val c1 = RED // Color.RED
val c2 = decode("#ff0000") // Color.decode

Esto es similar a static import de java.

Importado todo un paquete podemos acceder a los objetos o clases de los subpaquetes con el nombre del subpaquete + el nombre de la clase o objeto:

import java.awt._
def handler(evt: event.ActionEvent) { // java.awt.event.ActionEvent
...
}

Como dice el comentario estamos usando  java.awt.event.ActionEvent cuando nombramos  event.ActionEvent porque  java.awt fue importado en su totalidad.