Используя абстрактный класс, мы можем усовершенствовать рассматривавшийся ранее класс TwoDShape-Для неопределенной двумерной геометрической фигуры понятие площади не имеет никакого смысла, поэтому в приведенной ниже версии предыдущей программы метод area и сам класс TwoDShape объявляются как abstract. Это, конечно, означает, что во всех классах, производных от класса TwoDShape, должен быть переопределен метод area . // Создание абстрактного класса. // Теперь класс TwoDShape является абстрактным. abstract class TwoDShape { private double width; private double height; private String name; // Конструктор no умолчанию. TwoDShape { width = height = 0.0; name = "null"; } // Параметризированный конструктор. TwoDShape(double w, double h, String n) { width = w; height = h; name = n; } // построить объект с одинаковыми значениями // переменных экземпляра width и height TwoDShape(double х, String n) { width = height = x; name = n; } // построить один объект на основании другого объекта TwoDShape(TwoDShape ob) { width = ob.width; height = ob.height; name = ob.name; } // Методы доступа к переменным width и height, double getWidth { return width; } double getHeightO { return height; } void setWidth(double w) { width = w; } void setHeight(double h) { height = h; } String getName { return name; } void showDim { System.out.println("Width and height are " + width + " and " + height); } // Теперь метод area является абстрактным. abstract double area; } // Подкласс, производный от класса TwoDShape, // для представления треугольников, class Triangle extends TwoDShape { private String style; // Конструктор по умолчанию. Triangle { super ; style = "null"; } // Конструктор класса Triangle. Triangle(String s, double w, double h) { super(w, h, "triangle"); style = s; } // Конструктор с одним аргументом для построения треугольника. Triangle(double х) { super(х, "triangle"); // вызвать конструктор суперкласса style = "isosceles"; } // построить один объект на основании другого объекта Triangle(Triangle ob) { super(ob); // передать объект конструктору класса TwoDShape style = ob.style; } double area { return getWidth * getHeight / 2; } void showStyle { System.out.println("Triangle is " + style); } } // Подкласс, производный от класса TwoDShape, // для представления прямоугольников. class Rectangle extends TwoDShape { // Конструктор по умолчанию. Rectangle { super; } // Конструктор класса Rectangle. Rectangle(double w, double h) { super(w, h, "rectangle"); // вызвать конструктор суперкласса } // построить квадрат Rectangle(double х) { super(х, "rectangle"); // вызвать конструктор суперкласса } // построить один объект на основании другого объекта Rectangle(Rectangle ob) { super(ob); // передать объект конструктору класса TwoDShape } boolean isSquare { if (getWidth == getHeightO) return true; return false; } double area { return getWidth * getHeightO; } } class AbsShape { public static void main(String args[]) { TwoDShape shapes[] = new TwoDShape[4]; shapes[0] = new Triangle("right", 8.0, 12.0); shapes[1] = new Rectangle(10); shapes[2] = new Rectangle(10, 4); shapes[3] = new Triangle(7.0); for(int i=0; i < shapes.length; i++) { System.out.println("object is " + shapes[i].getName); System.out.println("Area is " + shapes[i].area); System.out.println; } } }
Как показывает представленный выше пример программы, во всех подклассах, производных от класса TwoDShape, метод area должен быть непременно переопределен. Убедитесь в этом сами, попробовав создать подкласс, в котором не переопределен метод area . В итоге вы получите сообщение об ошибке во время компиляции. Конечно, возможность создавать ссылки на объекты типа TwoDShape по-прежнему существует, и это было сделано в приведенном выше примере программы, но объявлять объекты типа TwoDShape уже нельзя. Именно поэтому массив shapes сокращен в методе main до 4 элементов, а объект типа TwoDShape для общей двумерной геометрической формы больше не создается.