Java - Абстракция
Согласно словарю, abstractionэто качество работы с идеями, а не с событиями. Например, когда вы рассматриваете случай электронной почты, сложные детали, такие как то, что происходит, как только вы отправляете электронное письмо, протокол, который использует ваш почтовый сервер, скрыты от пользователя. Таким образом, чтобы отправить электронное письмо, вам просто нужно ввести содержимое, указать адрес получателя и нажать кнопку «Отправить».
Точно так же в объектно-ориентированном программировании абстракция - это процесс сокрытия деталей реализации от пользователя, пользователю предоставляется только функциональность. Другими словами, пользователь будет иметь информацию о том, что делает объект, а не о том, как он это делает.
В Java абстракция достигается с помощью абстрактных классов и интерфейсов.
Абстрактный класс
Класс, содержащий abstract ключевое слово в его объявлении известно как абстрактный класс.
Абстрактные классы могут содержать или не содержать абстрактные методы , то есть методы без тела (public void get ();)
Но если у класса есть хотя бы один абстрактный метод, тогда класс must быть объявленным абстрактным.
Если класс объявлен абстрактным, он не может быть создан.
Чтобы использовать абстрактный класс, вы должны унаследовать его от другого класса, предоставить реализации абстрактных методов в нем.
Если вы наследуете абстрактный класс, вы должны предоставить реализации для всех абстрактных методов в нем.
пример
В этом разделе представлен пример абстрактного класса. Чтобы создать абстрактный класс, просто используйтеabstract ключевое слово перед ключевым словом class в объявлении класса.
/* 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;
}
}
Вы можете заметить, что, за исключением абстрактных методов, класс Employee такой же, как обычный класс в Java. Класс теперь абстрактный, но у него все еще есть три поля, семь методов и один конструктор.
Теперь вы можете попробовать создать экземпляр класса Employee следующим образом:
/* 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();
}
}
Когда вы компилируете вышеуказанный класс, он дает следующую ошибку:
Employee.java:46: Employee is abstract; cannot be instantiated
Employee e = new Employee("George W.", "Houston, TX", 43);
^
1 error
Наследование абстрактного класса
Мы можем унаследовать свойства класса Employee, как и конкретный класс, следующим образом:
пример
/* 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;
}
}
Здесь вы не можете создать экземпляр класса Employee, но вы можете создать экземпляр класса Salary, и с помощью этого экземпляра вы можете получить доступ ко всем трем полям и семи методам класса Employee, как показано ниже.
/* 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();
}
}
Это дает следующий результат -
Вывод
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
Абстрактные методы
Если вы хотите, чтобы класс содержал определенный метод, но вы хотите, чтобы фактическая реализация этого метода определялась дочерними классами, вы можете объявить метод в родительском классе как абстрактный.
abstract ключевое слово используется для объявления метода абстрактным.
Вы должны разместить abstract ключевое слово перед именем метода в объявлении метода.
Абстрактный метод содержит подпись метода, но не тело метода.
Вместо фигурных скобок в конце абстрактного метода будет двоеточие (;).
Ниже приведен пример абстрактного метода.
пример
public abstract class Employee {
private String name;
private String address;
private int number;
public abstract double computePay();
// Remainder of class definition
}
Объявление метода абстрактным имеет два последствия:
Класс, содержащий его, должен быть объявлен абстрактным.
Любой класс, наследующий текущий класс, должен либо переопределить абстрактный метод, либо объявить себя абстрактным.
Note- В конце концов, класс-потомок должен реализовать абстрактный метод; в противном случае у вас будет иерархия абстрактных классов, экземпляры которых невозможно создать.
Предположим, что класс Salary наследует класс Employee, тогда он должен реализовать computePay() метод, как показано ниже -
/* 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
}