Java - Abstracción

Según el diccionario, abstractiones la cualidad de lidiar con ideas en lugar de eventos. Por ejemplo, cuando se considera el caso del correo electrónico, detalles complejos como lo que sucede tan pronto como envía un correo electrónico, el protocolo que utiliza su servidor de correo electrónico están ocultos al usuario. Por lo tanto, para enviar un correo electrónico solo necesita escribir el contenido, mencionar la dirección del destinatario y hacer clic en enviar.

Del mismo modo, en la programación orientada a objetos, la abstracción es un proceso de ocultar al usuario los detalles de implementación, solo se le proporcionará la funcionalidad. En otras palabras, el usuario tendrá la información sobre lo que hace el objeto en lugar de cómo lo hace.

En Java, la abstracción se logra mediante clases e interfaces abstractas.

Clase abstracta

Una clase que contiene el abstract La palabra clave en su declaración se conoce como clase abstracta.

  • Las clases abstractas pueden contener o no métodos abstractos , es decir, métodos sin cuerpo (public void get ();)

  • Pero, si una clase tiene al menos un método abstracto, entonces la clase must ser declarado abstracto.

  • Si una clase se declara abstracta, no se puede crear una instancia.

  • Para usar una clase abstracta, debe heredarla de otra clase, proporcionar implementaciones a los métodos abstractos en ella.

  • Si hereda una clase abstracta, debe proporcionar implementaciones para todos los métodos abstractos que contiene.

Ejemplo

Esta sección le proporciona un ejemplo de la clase abstracta. Para crear una clase abstracta, simplemente use elabstract palabra clave antes de la palabra clave de clase, en la declaración de clase.

/* File name : Employee.java */
public abstract class Employee {
   private String name;
   private String address;
   private int number;

   public Employee(String name, String address, int number) {
      System.out.println("Constructing an Employee");
      this.name = name;
      this.address = address;
      this.number = number;
   }
   
   public double computePay() {
     System.out.println("Inside Employee computePay");
     return 0.0;
   }
   
   public void mailCheck() {
      System.out.println("Mailing a check to " + this.name + " " + this.address);
   }

   public String toString() {
      return name + " " + address + " " + number;
   }

   public String getName() {
      return name;
   }
 
   public String getAddress() {
      return address;
   }
   
   public void setAddress(String newAddress) {
      address = newAddress;
   }
 
   public int getNumber() {
      return number;
   }
}

Puede observar que, excepto los métodos abstractos, la clase Empleado es la misma que la clase normal en Java. La clase ahora es abstracta, pero todavía tiene tres campos, siete métodos y un constructor.

Ahora puede intentar crear una instancia de la clase Employee de la siguiente manera:

/* File name : AbstractDemo.java */
public class AbstractDemo {

   public static void main(String [] args) {
      /* Following is not allowed and would raise error */
      Employee e = new Employee("George W.", "Houston, TX", 43);
      System.out.println("\n Call mailCheck using Employee reference--");
      e.mailCheck();
   }
}

Cuando compila la clase anterior, le da el siguiente error:

Employee.java:46: Employee is abstract; cannot be instantiated
      Employee e = new Employee("George W.", "Houston, TX", 43);
                   ^
1 error

Heredar la clase abstracta

Podemos heredar las propiedades de la clase Empleado como una clase concreta de la siguiente manera:

Ejemplo

/* File name : Salary.java */
public class Salary extends Employee {
   private double salary;   // Annual salary
   
   public Salary(String name, String address, int number, double salary) {
      super(name, address, number);
      setSalary(salary);
   }
   
   public void mailCheck() {
      System.out.println("Within mailCheck of Salary class ");
      System.out.println("Mailing check to " + getName() + " with salary " + salary);
   }
 
   public double getSalary() {
      return salary;
   }
   
   public void setSalary(double newSalary) {
      if(newSalary >= 0.0) {
         salary = newSalary;
      }
   }
   
   public double computePay() {
      System.out.println("Computing salary pay for " + getName());
      return salary/52;
   }
}

Aquí, no puede crear una instancia de la clase Empleado, pero puede crear una instancia de la Clase de salario y, con esta instancia, puede acceder a los tres campos y siete métodos de la clase Empleado, como se muestra a continuación.

/* File name : AbstractDemo.java */
public class AbstractDemo {

   public static void main(String [] args) {
      Salary s = new Salary("Mohd Mohtashim", "Ambehta, UP", 3, 3600.00);
      Employee e = new Salary("John Adams", "Boston, MA", 2, 2400.00);
      System.out.println("Call mailCheck using Salary reference --");
      s.mailCheck();
      System.out.println("\n Call mailCheck using Employee reference--");
      e.mailCheck();
   }
}

Esto produce el siguiente resultado:

Salida

Constructing an Employee
Constructing an Employee
Call mailCheck using Salary reference --
Within mailCheck of Salary class 
Mailing check to Mohd Mohtashim with salary 3600.0

 Call mailCheck using Employee reference--
Within mailCheck of Salary class 
Mailing check to John Adams with salary 2400.0

Métodos abstractos

Si desea que una clase contenga un método en particular, pero desea que las clases secundarias determinen la implementación real de ese método, puede declarar el método en la clase principal como un resumen.

  • abstract La palabra clave se utiliza para declarar el método como abstracto.

  • Tienes que colocar el abstract palabra clave antes del nombre del método en la declaración del método.

  • Un método abstracto contiene una firma de método, pero no un cuerpo de método.

  • En lugar de llaves, un método abstracto tendrá dos puntos semoi (;) al final.

A continuación se muestra un ejemplo del método abstracto.

Ejemplo

public abstract class Employee {
   private String name;
   private String address;
   private int number;
   
   public abstract double computePay();
   // Remainder of class definition
}

Declarar un método como abstracto tiene dos consecuencias:

  • La clase que lo contiene debe declararse como abstracta.

  • Cualquier clase que herede la clase actual debe anular el método abstracto o declararse como abstracta.

Note- Eventualmente, una clase descendiente tiene que implementar el método abstracto; de lo contrario, tendría una jerarquía de clases abstractas que no se pueden instanciar.

Suponga que la clase Salario hereda la clase Empleado, entonces debería implementar la computePay() método como se muestra a continuación -

/* File name : Salary.java */
public class Salary extends Employee {
   private double salary;   // Annual salary
  
   public double computePay() {
      System.out.println("Computing salary pay for " + getName());
      return salary/52;
   }
   // Remainder of class definition
}