ВНИМАНИЕ! Опубликовано расписание занятий на 2017-2018 уч. год Подробнее
Toggle Bar

19, Практика. Полиморфизм

Рассмотрим пример с геометрическими фигурами. Имеется базовый класс c именем Figura  и несколько производных классов: окружность (тип Circle), прямоугольник (тип Rect) и трапеция (тип Trap). Необходимо определить площадь каждой фигуры и вывести эти значения на печать.

Вот листинг классов.

public class Figura {
        public double Area (){
            return 0;
        }
        public void PrintArea(){}
}

Обратите внимание, класс не имеет явно записанного конструктора. Компилятор будет использовать конструктор по умолчанию.

Класс содержит два пустых метода Area() и PrintArea(), которые в данном классе совершенно ничего не делают, но их наличие крайне важно: именно через них будет в последующем обеспечен полиморфизм.

public class Circle extends Figura{
    int a;
     public  Circle (int A)
    {
        a=A;
    }
       
    public double Area (){
            return Math.PI*a*a;
    }
  
    public void PrintArea(){
    System.out.println("Площадь круга: "+ Area());
    }
}

Класс Circle является производным от класса Figura, на это указывает ключевое слово extends. Данный класс содержит конструктор public  Circle (int A), методы Area() и    PrintArea(), которые переопределены в Circle (имя метода как у родителя, а в внутри каждого метода записан другой программный код). 

Выполним создание объекта класса Circle, следующим образом:

   Figura f = new Circle(1);

Первое впечатление - это ошибка. Мы видим присвоение между переменными разного типа (тип Figura и тип Circle). Но это не так. Операция допустима, поскольку тип Circle (окружность) является типом Figura посредством наследования.

Все  ссылки на объекты производных классов совместимы по типу с ссылками на объекты базового класса.

 

Выполним метод Area ()

f.Area ();

Какой метод Area() будет вызван: из класса  Figura  или класса Circle?

При выполнении данного оператора работает механизм динамического или позднего связывания. На данном  этапе выполнения программы уже известно, что был создан объект типа Circle и ссылка на этот объект была присвоена переменной f. Следовательно, будет вызван метод Area() класса Circle. Так происходит автоматический выбор нужного метода для исполнения. 

Продолжим листинг классов.

//класс прямоугольник
public class Rect extends Figura {
     int a;
     int b;
    
    public  Rect (int A, int B)
    {
        a=A;
        b=B;
    }
    public double Area (){
               return a*b;
    }
   
    public void PrintArea(){
    System.out.println("Площадь прямоугольника: "+ Area());
    }
}
//класс трапеция
public class Trap extends Figura{
     int a;
     int b;
     int h;
    
    public  Trap (int A, int B, int H)
    {
        a=A;
        b=B;
        h=H;
    }
    public double Area (){
              return (a + b)*h/2;
    }
   
    public void PrintArea(){
    System.out.println("Площадь трапеции: "+ Area());
    }
 }

Метод  main()

   public static void main(String[] args) {
        //создаем массив ссылок на базовый класс
        Figura [] f = new Figura [5];
        //создаем объекты, ссылки на объеты храним
        //в массиве ссылок базового класса
         f[0]= new Circle(1);
         f[1]= new Rect(1,1);
         f[2]= new Trap(1,1,1);
         f[3]= new Circle(1);
         f[4]= new Rect(1,1);
        
         //работает механизм полимофизма
         for(int i=0; i<f.length; i++)
                 f[i].PrintArea();
    }

Результат работы:

Площадь круга: 3.141592653589793
Площадь прямоугольника: 1.0
Площадь трапеции: 1.0
Площадь круга: 3.141592653589793
Площадь прямоугольника: 1.0

Полиморфизм  проявляется строке

                 f[i].PrintArea();

где один и тот же метод используется для вычисления площади разных фигур (окрухность Circle, прямоугольник Rect и трапеция  Trap).

Добавить комментарий
  • Комментарии не найдены
 
DMC Firewall is a Joomla Security extension!