Groovy - Tratti
I tratti sono un costrutto strutturale del linguaggio che consente:
- Composizione dei comportamenti.
- Implementazione runtime delle interfacce.
- Compatibilità con il controllo / compilazione del tipo statico
Possono essere visti come interfacce che trasportano sia le implementazioni predefinite che lo stato. Un tratto viene definito utilizzando la parola chiave tratto.
Di seguito viene fornito un esempio di un tratto:
trait Marks {
void DisplayMarks() {
println("Display Marks");
}
}
È quindi possibile utilizzare la parola chiave implement per implementare il tratto in modo simile alle interfacce.
class Example {
static void main(String[] args) {
Student st = new Student();
st.StudentID = 1;
st.Marks1 = 10;
println(st.DisplayMarks());
}
}
trait Marks {
void DisplayMarks() {
println("Display Marks");
}
}
class Student implements Marks {
int StudentID
int Marks1;
}
Implementazione delle interfacce
I tratti possono implementare interfacce, nel qual caso le interfacce vengono dichiarate utilizzando la parola chiave implements.
Di seguito viene fornito un esempio di un tratto che implementa un'interfaccia. Nell'esempio seguente si possono notare i seguenti punti chiave.
Un'interfaccia Total viene definita con il metodo DisplayTotal.
Il tratto Marks implementa l'interfaccia Total e quindi deve fornire un'implementazione per il metodo DisplayTotal.
class Example {
static void main(String[] args) {
Student st = new Student();
st.StudentID = 1;
st.Marks1 = 10;
println(st.DisplayMarks());
println(st.DisplayTotal());
}
}
interface Total {
void DisplayTotal()
}
trait Marks implements Total {
void DisplayMarks() {
println("Display Marks");
}
void DisplayTotal() {
println("Display Total");
}
}
class Student implements Marks {
int StudentID
int Marks1;
}
L'output del programma di cui sopra sarebbe:
Display Marks
Display Total
Proprietà
Un tratto può definire proprietà. Di seguito viene fornito un esempio di un tratto con una proprietà.
Nell'esempio seguente, Marks1 di tipo integer è una proprietà.
class Example {
static void main(String[] args) {
Student st = new Student();
st.StudentID = 1;
println(st.DisplayMarks());
println(st.DisplayTotal());
}
interface Total {
void DisplayTotal()
}
trait Marks implements Total {
int Marks1;
void DisplayMarks() {
this.Marks1 = 10;
println(this.Marks1);
}
void DisplayTotal() {
println("Display Total");
}
}
class Student implements Marks {
int StudentID
}
}
L'output del programma di cui sopra sarebbe:
10
Display Total
Composizione dei comportamenti
I tratti possono essere utilizzati per implementare l'ereditarietà multipla in modo controllato, evitando il problema del diamante. Nel seguente esempio di codice, abbiamo definito due tratti:Marks e Total. La nostra classe Student implementa entrambi i tratti. Poiché la classe dello studente estende entrambi i tratti, è in grado di accedere a entrambi i metodi:DisplayMarks e DisplayTotal.
class Example {
static void main(String[] args) {
Student st = new Student();
st.StudentID = 1;
println(st.DisplayMarks());
println(st.DisplayTotal());
}
}
trait Marks {
void DisplayMarks() {
println("Marks1");
}
}
trait Total {
void DisplayTotal() {
println("Total");
}
}
class Student implements Marks,Total {
int StudentID
}
L'output del programma di cui sopra sarebbe:
Total
Marks1
Tratti estesi
I tratti possono estendere un altro tratto, nel qual caso devi usare il extendsparola chiave. Nel seguente esempio di codice, stiamo estendendo il tratto Total con il tratto Marks.
class Example {
static void main(String[] args) {
Student st = new Student();
st.StudentID = 1;
println(st.DisplayMarks());
}
}
trait Marks {
void DisplayMarks() {
println("Marks1");
}
}
trait Total extends Marks {
void DisplayMarks() {
println("Total");
}
}
class Student implements Total {
int StudentID
}
L'output del programma di cui sopra sarebbe:
Total