Предисловие
Классом называется класс, когда у него есть имя и реализованы все имеющиеся методы, которые объявлены во всей иерархии классов. Иерархия вместе с ее супертипом становятся более общим преставлением действующего домена, и, наконец, выходят за пределы этой границы и заканчиваются тем фактом, что почти все является объектом(Очень странное предложение). Суперкласс может быть конкретным классом, который, очевидно, не final или абстрактным классом, или даже одним или несколькими интерфейсами. Комбинирование супер-класса или абстрактоного класса с интерфейсами так же широко известный способ описания класса. Полиморфизм появляется, когда более чем один класс реализует определенный метод различно, в зависимости от назанчения класса. В этой статье рассматривается два из трех супертипов, выделены их основные харрактеристики. Интерфейс и абстрактный класс могут быть созданые экземпляром анонимного класса.
Абстрактный класс
Обычно, абстрактный класс реализует общее поведение и переменные любого конкретного класса и его методы могут быть уже указаны в интерфейсе. Различимое поведение достигается через объявление абстрактных методов, которые необходимо реализовать в определенном классе. Абстрактный класс может наследовать поведение от других абстрактных или конкретных классов и может обогащать дальнейшее поведение при добавлении интерфейса. В java такие реализации могут быть явно подчеркнуты с помощью аннотации Override, которая информирует об изменении. Полиморфизм останавливается в тот момент, когда реализация метода становится final. Методы в абстрактном классе могут быть private, это делает такой класс более подходящим для инкапсуляции private методов, в то же время позволяя рабить сложные методы на мелкие части. Абтрактный класс очень близок к конкретной реализации класса.
Интерфейс
C Java 1.8 интерфейсы могут реализовывать default методы, для обеспечения общего поведения. Следовательно и абстрактный класс и интерфейс имеют свой подход, в отношении своих особенностей. Для переменных интерфейса явно указано, что они public и final, а у переменных абстрактного класса могут быть различные модификаторы доступа. Более того, есть небольшая разница в возможности повлиять на модификатор доступа для default метода. Он всегда public, а у абстрактного класса, реализация может быть с любым доступом (public, protected, default, private). Все, что объявлено в интерфейсе, везде доступно и может расширяться объектом со специфическим поведением. Интерфейс позволяет наследоваться только от другого интерфейса. И интерфейс и абстрактный класс могут реализовывать статические методы. Другой тип интерфейса - интерфейс, который не декларирует ни одного метода и применяется как интерфейс-индикатор.Они просто указывают на договор с разработчиком, например, что класс клонируемый или сериализуемый.
Пример 1
Это сравнение подчеркивает преимущество абстрактного класса над интерфейсом, ориентированным на вычисление угла между двумя прямыми. Однако для этой цели можно использовать и интерфейс, и абстрактный класс, в то время как первый не согласуется с предложениями Мартина о чистом коде.
public interface TwoDimensional {
double PI = 3.141579; //is public and final
default double getAngle(TwoDimensional a, TwoDimensional b) /* is public */{
double alpha = 0.0;
//do complex calculation here
//modulus
//scalar
//to degrees
return alpha;
}
int getX(); //is public
int getY();
}
public abstract class AbstractTwoDimensional {
public final double PI = 3.141579;
private int x;
private int y;
public final double getAngle(AbstractTwoDimensional other) {
double a = calcModulus(x, y);
double b = calcModulus(other.getX(), other.getY());
double s = scalar(other.getX(), other.getY());
return toDegrees(s, a, b);
}
private double toDegrees(double s, double a, double b) {
//compute
return 0;
}
private double calcModulus(int x, int y) {
//compute...
return 0;
}
private double scalar(int x2, int y2) {
//compute...
return 0;
}
abstract int getX();
abstract int getY();
//some other abstract methods…
}
Пример 2
public interface TwoDimensional {
Double PI = 3.141579;
double getAngle(TwoDimensional other);
int getX();
int getY();
}
public abstract class AbstractTwoDimensional implements TwoDimensional {
private int x;
private int y;
@Override
public final double getAngle(TwoDimensional other) {
double a = calcModulus(x, y);
double b = calcModulus(other.getX(), other.getY());
double s = scalar(other.getX(), other.getY());
return toDegrees(s, a, b);
}
@Override
public final int getX() {
return x;
}
@Override
public final int getY() {
return y;
}
protected void setX(int x) {
this.x = x;
}
protected void setY(int y) {
this.y = y;
}
private double toDegrees(double s, double a, double b) {
//compute
return 0;
}
private double calcModulus(int x, int y) {
//compute...
return 0;
}
private double scalar(int x2, int y2) {
//compute...
return 0;
}
}
public class MutableLine extends AbstractTwoDimensional {
//some specific things…
public MutableLine(ImmutableLine line) {
//extract data and init
}
}
public final class ImmutableLine extends AbstractTwoDimensional {
//some specific things...
public ImmutableLine(MutableLine line) {
//extract data
}
@Override
public final void setX(int x) {
//throw an appropriate exception
}
@Override
public final void setY(int y) {
//throw an appropriate exception
}
}
PS это мой перевод данной статьи
Комментариев нет :
Отправить комментарий