Предисловие
Классом называется класс, когда у него есть имя и реализованы все имеющиеся методы, которые объявлены во всей иерархии классов. Иерархия вместе с ее супертипом становятся более общим преставлением действующего домена, и, наконец, выходят за пределы этой границы и заканчиваются тем фактом, что почти все является объектом(Очень странное предложение). Суперкласс может быть конкретным классом, который, очевидно, не 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 это мой перевод данной статьи
Комментариев нет :
Отправить комментарий