Groovy - zorientowany obiektowo

W Groovy, podobnie jak w każdym innym języku zorientowanym obiektowo, istnieje koncepcja klas i obiektów reprezentujących zorientowany obiektowo charakter języka programowania. Klasa Groovy to zbiór danych i metod, które działają na tych danych. Razem dane i metody klasy są używane do reprezentowania obiektu świata rzeczywistego z domeny problemowej.

Klasa w Groovy deklaruje stan (dane) i zachowanie obiektów zdefiniowanych przez tę klasę. W związku z tym klasa Groovy opisuje zarówno pola instancji, jak i metody dla tej klasy.

Poniżej znajduje się przykład klasy w Groovy. Nazwa klasy to Student, która ma dwa pola -StudentID i StudentName. W funkcji głównej tworzymy obiekt tej klasy i przypisujemy wartości doStudentID i StudentName obiektu.

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

Metody pobierające i ustawiające

W każdym języku programowania zawsze praktykuje się ukrywanie elementów członkowskich instancji za pomocą słowa kluczowego private i zamiast tego udostępnianie metod pobierających i ustawiających w celu odpowiedniego ustawiania i pobierania wartości zmiennych instancji. Poniższy przykład pokazuje, jak można to zrobić.

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());
   } 
}

Po uruchomieniu powyższego programu otrzymamy następujący wynik -

1 
Joe

Zwróć uwagę na następujące kluczowe punkty dotyczące powyższego programu -

  • W klasie zarówno studentID, jak i studentName są oznaczone jako prywatne, co oznacza, że ​​nie można uzyskać do nich dostępu spoza klasy.

  • Każdy element członkowski instancji ma własną metodę pobierającą i ustawiającą. Metoda getter zwraca wartość zmiennej instancji, na przykład metoda int getStudentID (), a metoda ustawiająca ustawia wartość identyfikatora instancji, na przykład metoda - void setStudentName (String pName)

Metody instancji

Zwykle naturalne jest dołączanie do klasy większej liczby metod, które faktycznie wykonują jakąś funkcję dla klasy. W naszym przykładzie dla uczniów dodajmy członków instancji Marks1, Marks2 i Marks3, aby oznaczyć oceny ucznia z 3 przedmiotów. Następnie dodamy nową metodę instancji, która obliczy całkowitą ocenę ucznia. Poniżej przedstawiono wygląd kodu.

W poniższym przykładzie metoda Total jest dodatkową metodą Instance, która ma wbudowaną logikę.

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());
   }
}

Po uruchomieniu powyższego programu otrzymamy następujący wynik -

60

Tworzenie wielu obiektów

Można również tworzyć wiele obiektów klasy. Poniżej znajduje się przykład, jak można to osiągnąć. W tym miejscu tworzymy 3 obiekty (st, st1 i st2) i odpowiednio wywołujemy ich elementy członkowskie i metody instancji.

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());
   } 
}

Po uruchomieniu powyższego programu otrzymamy następujący wynik -

60 
70 
80

Dziedzictwo

Dziedziczenie można zdefiniować jako proces, w którym jedna klasa uzyskuje właściwości (metody i pola) innej. Dziedziczenie umożliwia zarządzanie informacjami w porządku hierarchicznym.

Klasa, która dziedziczy właściwości innych, jest znana jako podklasa (klasa pochodna, klasa potomna), a klasa, której właściwości są dziedziczone, jest znana jako nadklasa (klasa bazowa, klasa nadrzędna).

Rozciąga się

extendsjest słowem kluczowym używanym do dziedziczenia właściwości klasy. Poniżej podana jest składnia słowa kluczowego extends. W poniższym przykładzie wykonujemy następujące czynności -

  • Tworzenie klasy o nazwie Person. Ta klasa ma jednego członka instancji o nazwie name.

  • Utworzenie klasy o nazwie Student, która pochodzi z klasy Person. Należy zauważyć, że element członkowski wystąpienia nazwy, który jest zdefiniowany w klasie Person, jest dziedziczony w klasie Student.

  • W konstruktorze klasy Student wywołujemy konstruktor klasy bazowej.

  • W naszej klasie Student dodajemy 2 dodatkowe elementy członkowskie instancji StudentID i 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();
   } 
}

Po uruchomieniu powyższego programu otrzymamy następujący wynik -

Joe

Klasy wewnętrzne

Klasy wewnętrzne są zdefiniowane w innych klasach. Klasa otaczająca może normalnie używać klasy wewnętrznej. Z drugiej strony klasa wewnętrzna może uzyskać dostęp do członków swojej klasy otaczającej, nawet jeśli są one prywatne. Klasy inne niż klasa otaczająca nie mają dostępu do klas wewnętrznych.

Poniżej znajduje się przykład klasy zewnętrznej i wewnętrznej. W poniższym przykładzie wykonujemy następujące czynności -

  • Stworzenie klasy o nazwie Outer, która będzie naszą klasą zewnętrzną.
  • Definiowanie ciągu o nazwie name w naszej klasie Outer.
  • Tworzenie klasy wewnętrznej lub zagnieżdżonej wewnątrz naszej klasy Outer.
  • Zauważ, że w klasie wewnętrznej jesteśmy w stanie uzyskać dostęp do elementu członkowskiego instancji nazwy zdefiniowanego w klasie Outer.
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); 
      } 
   } 
	
}

Po uruchomieniu powyższego programu otrzymamy następujący wynik -

Joe

Klasy abstrakcyjne

Klasy abstrakcyjne reprezentują pojęcia ogólne, dlatego nie można ich tworzyć instancji, ponieważ są tworzone w celu utworzenia podklasy. Ich członkowie obejmują pola / właściwości oraz metody abstrakcyjne lub konkretne. Metody abstrakcyjne nie mają implementacji i muszą być implementowane przez konkretne podklasy. Klasy abstrakcyjne muszą być zadeklarowane za pomocą słowa kluczowego abstract. Metody abstrakcyjne muszą być również zadeklarowane za pomocą słowa kluczowego abstract.

W poniższym przykładzie należy zauważyć, że klasa Person jest teraz przekształcona w klasę abstrakcyjną i nie można jej utworzyć wystąpienia. Należy również zauważyć, że w klasie abstrakcyjnej istnieje metoda abstrakcyjna o nazwie DisplayMarks, która nie ma szczegółów implementacji. Na zajęciach studenckich obowiązkowe jest dodanie szczegółów implementacji.

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); 
   }  
}

Po uruchomieniu powyższego programu otrzymamy następujący wynik -

Joe 
10 
null

Interfejsy

Interfejs definiuje kontrakt, z którym klasa musi być zgodna. Interfejs definiuje jedynie listę metod, które należy zaimplementować, ale nie definiuje implementacji metod. Interfejs należy zadeklarować za pomocą słowa kluczowego interface. Interfejs definiuje tylko sygnatury metod. Metody interfejsu są zawszepublic. Używanie chronionych lub prywatnych metod w interfejsach jest błędem.

Poniżej znajduje się przykład interfejsu w Groovy. W poniższym przykładzie wykonujemy następujące czynności -

  • Utworzenie interfejsu o nazwie Marks i utworzenie metody interfejsu o nazwie DisplayMarks.

  • W definicji klasy używamy słowa kluczowego implements do implementacji interfejsu.

  • Ponieważ implementujemy interfejs, musimy zapewnić implementację dla metody 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);
   }
}

Po uruchomieniu powyższego programu otrzymamy następujący wynik -

10
null