Sobrescribir campos
Se puede sobrescribir val (o un método sin parámetros) con una declaración val con el mismo nombre. La clase tiene privados los atributos y públicos los getters y setters por lo tanto se sobrescribirán estos métodos.
Por ejemplo:
class Person(val name: String) {
override def toString = getClass.getName + "[name=" + name + "]"
}
class SecretAgent(codename: String) extends Person(codename) {
override val name = "secret" // Don’t want to reveal name . . .
override val toString = "secret" // . . . or class name
}
Este ejemplo muestra el mecanismo, pero es bastante artificial. Un caso más común es sobrescribir un def de una clase abstracta, veamos un ejemplo :
abstract class Person { // See Section 8.8 for abstract classes
def id: Int // Each person has an ID that is computed in some way
...
}
class Student(override val id: Int) extends Person
// A student ID is simply provided in the constructor
Note las siguientes restricciones:
- Un def solo puede ser sobrescrito por un def
- Un val solo puede ser sobrescrito por otro val o un def sin parámetros
- Un var solo puede ser sobrescrito por un var abstracto
Veamos un cuadro que describe la sobrecarga:
|
Con val |
Con def |
Con var |
Sobrescribir val |
La subclase tiene un campo privado (con el mismo nombre que el campo de la superclase: está bien). Getter reemplaza al getter de superclase. |
Error |
Error |
Sobrescribir def |
La subclase tiene un campo privado. Getter anula el método de superclase. |
Como java. |
Una var puede anular un par getter / setter. Anular solo el getter produce un error. |
Sobrescribir var |
Error |
Error |
Sólo si la superclase var es abstracta |
Subclases anónimas.
Como en java, se pueden implementar interfaces o extender clases abstractas implementando los métodos a continuación del llamado de dicha clase o interfaz, es más fácil explicar esto con un ejemplo:
val alien = new Person("Fred") {
def greeting = "Greetings, Earthling! My name is Fred."
}
Técnicamente esto creo una persona con el método “greeting” implementado con el texto: "Greetings, Earthling! My name is Fred." El tipo es Person{def greeting: String}. Se puede utilizar este tipo como parámetro de la siguiente forma:
def meet(p: Person{def greeting: String}) {
println(p.name + " says: " + p.greeting)
}
Clases Abstractas.
Como en java, podemos definir una clase abstracta con la palabra “abstract” y esta clase no se podrá instanciar. Normalmente esto es usado de la siguiente manera porque hay uno o más métodos que no podemos definir, es decir que son abstractos.
abstract class Person(val name: String) {
def id: Int // No method body—this is an abstract method
}
Una subclase de Person va a estar obligada a implementar el método id o ser abstracta. A diferencia de java no es necesario utilizar la palabra abstract para los métodos, simplemente debemos omitir el cuerpo de la función.
Una subclase concreta esta obligada a sobre escribir este método:
class Employee(name: String) extends Person(name) {
def id = name.hashCode // override keyword not required
}