Groovy - Orientado a objetos

En Groovy, como en cualquier otro lenguaje orientado a objetos, existe el concepto de clases y objetos para representar la naturaleza orientada a objetos del lenguaje de programación. Una clase Groovy es una colección de datos y los métodos que operan con esos datos. Juntos, los datos y métodos de una clase se utilizan para representar algún objeto del mundo real del dominio del problema.

Una clase en Groovy declara el estado (datos) y el comportamiento de los objetos definidos por esa clase. Por lo tanto, una clase Groovy describe tanto los campos de instancia como los métodos para esa clase.

A continuación se muestra un ejemplo de una clase en Groovy. El nombre de la clase es Estudiante, que tiene dos campos:StudentID y StudentName. En la función principal, estamos creando un objeto de esta clase y asignando valores a laStudentID y StudentName del objeto.

class Student {
   int StudentID;
   String StudentName;
	
   static void main(String[] args) {
      Student st = new Student();
      st.StudentID = 1;
      st.StudentName = "Joe"     
   } 
}

Métodos getter y setter

En cualquier lenguaje de programación, siempre es una práctica ocultar los miembros de la instancia con la palabra clave privada y, en su lugar, proporcionar métodos getter y setter para establecer y obtener los valores de las variables de instancia en consecuencia. El siguiente ejemplo muestra cómo se puede hacer esto.

class Student {
   private int StudentID;
   private String StudentName;
	
   void setStudentID(int pID) {
      StudentID = pID;
   }
	
   void setStudentName(String pName) {
      StudentName = pName;
   }
	
   int getStudentID() {
      return this.StudentID;
   }
	
   String getStudentName() {
      return this.StudentName;
   }
	
   static void main(String[] args) {
      Student st = new Student();
      st.setStudentID(1);
      st.setStudentName("Joe");
		
      println(st.getStudentID());
      println(st.getStudentName());
   } 
}

Cuando ejecutamos el programa anterior, obtendremos el siguiente resultado:

1 
Joe

Tenga en cuenta los siguientes puntos clave sobre el programa anterior:

  • En la clase, tanto el studentID como el studentName están marcados como privados, lo que significa que no se puede acceder a ellos desde fuera de la clase.

  • Cada miembro de la instancia tiene su propio método getter y setter. El método getter devuelve el valor de la variable de instancia, por ejemplo, el método int getStudentID () y el método setter establece el valor del ID de instancia, por ejemplo, el método - void setStudentName (String pName)

Métodos de instancia

Normalmente es natural incluir más métodos dentro de la clase, lo que en realidad hace algún tipo de funcionalidad para la clase. En nuestro ejemplo de estudiante, agreguemos miembros de instancia de Marks1, Marks2 y Marks3 para denotar las calificaciones del estudiante en 3 materias. Luego agregaremos un nuevo método de instancia que calculará las calificaciones totales del estudiante. A continuación se muestra cómo se vería el código.

En el siguiente ejemplo, el método Total es un método de instancia adicional que tiene algo de lógica incorporada.

class Student {
   int StudentID;
   String StudentName;
	
   int Marks1;
   int Marks2;
   int Marks3;
	
   int Total() {
      return Marks1+Marks2+Marks3;
   }
	
   static void main(String[] args) {
      Student st = new Student();
      st.StudentID = 1;
      st.StudentName="Joe";
		
      st.Marks1 = 10;
      st.Marks2 = 20;
      st.Marks3 = 30;
		
      println(st.Total());
   }
}

Cuando ejecutamos el programa anterior, obtendremos el siguiente resultado:

60

Crear varios objetos

También se pueden crear varios objetos de una clase. A continuación se muestra el ejemplo de cómo se puede lograr esto. Aquí estamos creando 3 objetos (st, st1 y st2) y llamando a sus miembros de instancia y métodos de instancia en consecuencia.

class Student {
   int StudentID;
   String StudentName;
	
   int Marks1;
   int Marks2;
   int Marks3;
	
   int Total() { 
      return Marks1+Marks2+Marks3;
   } 
	
   static void main(String[] args) {
      Student st = new Student();
      st.StudentID = 1;
      st.StudentName = "Joe";
		
      st.Marks1 = 10;
      st.Marks2 = 20;
      st.Marks3 = 30;
		
      println(st.Total()); 
   
      Student st1 = new Student();
      st.StudentID = 1;
      st.StudentName = "Joe";
		
      st.Marks1 = 10;
      st.Marks2 = 20;
      st.Marks3 = 40;
		
      println(st.Total());  
        
      Student st3 = new Student();
      st.StudentID = 1;
      st.StudentName = "Joe";
		
      st.Marks1 = 10; 
      st.Marks2 = 20;
      st.Marks3 = 50;
		
      println(st.Total());
   } 
}

Cuando ejecutamos el programa anterior, obtendremos el siguiente resultado:

60 
70 
80

Herencia

La herencia se puede definir como el proceso en el que una clase adquiere las propiedades (métodos y campos) de otra. Con el uso de la herencia, la información se hace manejable en un orden jerárquico.

La clase que hereda las propiedades de otro se conoce como subclase (clase derivada, clase secundaria) y la clase cuyas propiedades se heredan se conoce como superclase (clase base, clase principal).

Se extiende

extendses la palabra clave utilizada para heredar las propiedades de una clase. A continuación se muestra la sintaxis de la palabra clave extiende. En el siguiente ejemplo, estamos haciendo las siguientes cosas:

  • Creando una clase llamada Persona. Esta clase tiene un miembro de instancia llamado nombre.

  • Creando una clase llamada Student que se extiende desde la clase Person. Tenga en cuenta que el miembro de instancia de nombre que se define en la clase Person se hereda en la clase Student.

  • En el constructor de la clase Student, llamamos al constructor de la clase base.

  • En nuestra clase Student, estamos agregando 2 miembros de instancia adicionales de StudentID y Marks1.

class Example {
   static void main(String[] args) {
      Student st = new Student();
      st.StudentID = 1;
		
      st.Marks1 = 10;
      st.name = "Joe";
		
      println(st.name);
   }
} 

class Person {
   public String name;
   public Person() {}  
} 

class Student extends Person {
   int StudentID
   int Marks1;
	
   public Student() {
      super();
   } 
}

Cuando ejecutamos el programa anterior, obtendremos el siguiente resultado:

Joe

Clases internas

Las clases internas se definen dentro de otras clases. La clase adjunta puede usar la clase interna como de costumbre. Por otro lado, una clase interna puede acceder a los miembros de su clase adjunta, incluso si son privados. Las clases distintas de la clase adjunta no pueden acceder a las clases internas.

A continuación se muestra un ejemplo de una clase externa e interna. En el siguiente ejemplo, estamos haciendo las siguientes cosas:

  • Creando una clase llamada Outer que será nuestra clase externa.
  • Definiendo una cadena llamada name en nuestra clase Outer.
  • Creando una clase interna o anidada dentro de nuestra clase externa.
  • Tenga en cuenta que en la clase interna podemos acceder al miembro de instancia de nombre definido en la clase externa.
class Example { 
   static void main(String[] args) { 
      Outer outobj = new Outer(); 
      outobj.name = "Joe"; 
      outobj.callInnerMethod() 
   } 
} 

class Outer { 
   String name;
	
   def callInnerMethod() { 
      new Inner().methodA() 
   } 
	
   class Inner {
      def methodA() { 
         println(name); 
      } 
   } 
	
}

Cuando ejecutamos el programa anterior, obtendremos el siguiente resultado:

Joe

Clases abstractas

Las clases abstractas representan conceptos genéricos, por lo tanto, no se pueden instanciar, ya que se crean para ser subclasificados. Sus miembros incluyen campos / propiedades y métodos abstractos o concretos. Los métodos abstractos no tienen implementación y deben ser implementados por subclases concretas. Las clases abstractas deben declararse con la palabra clave abstracta. Los métodos abstractos también deben declararse con la palabra clave abstracta.

En el siguiente ejemplo, observe que la clase Person ahora se convierte en una clase abstracta y no se puede instanciar. También tenga en cuenta que hay un método abstracto llamado DisplayMarks en la clase abstracta que no tiene detalles de implementación. En la clase de estudiantes es obligatorio agregar los detalles de implementación.

class Example { 
   static void main(String[] args) { 
      Student st = new Student(); 
      st.StudentID = 1;
		
      st.Marks1 = 10; 
      st.name="Joe"; 
		
      println(st.name); 
      println(st.DisplayMarks()); 
   } 
} 

abstract class Person { 
   public String name; 
   public Person() { } 
   abstract void DisplayMarks();
}
 
class Student extends Person { 
   int StudentID 
   int Marks1; 
	
   public Student() { 
      super(); 
   } 
	
   void DisplayMarks() { 
      println(Marks1); 
   }  
}

Cuando ejecutamos el programa anterior, obtendremos el siguiente resultado:

Joe 
10 
null

Interfaces

Una interfaz define un contrato que una clase debe cumplir. Una interfaz solo define una lista de métodos que deben implementarse, pero no define la implementación de métodos. Una interfaz debe declararse utilizando la palabra clave de interfaz. Una interfaz solo define firmas de métodos. Los métodos de una interfaz son siemprepublic. Es un error utilizar métodos protegidos o privados en interfaces.

A continuación se muestra un ejemplo de una interfaz en groovy. En el siguiente ejemplo, estamos haciendo las siguientes cosas:

  • Creando una interfaz llamada Marks y creando un método de interfaz llamado DisplayMarks.

  • En la definición de la clase, usamos la palabra clave implements para implementar la interfaz.

  • Debido a que estamos implementando la interfaz, tenemos que proporcionar la implementación del método DisplayMarks.

class Example {
   static void main(String[] args) {
      Student st = new Student();
      st.StudentID = 1;
      st.Marks1 = 10;
      println(st.DisplayMarks());
   } 
} 

interface Marks { 
   void DisplayMarks(); 
} 

class Student implements Marks {
   int StudentID
   int Marks1;
	
   void DisplayMarks() {
      println(Marks1);
   }
}

Cuando ejecutamos el programa anterior, obtendremos el siguiente resultado:

10
null