Программирование мобильных телефонов на Java


Программирование мобильных телефонов

  • Введение
  • Глава 1. Устройство мобильных телефонов
  • Глава 2. Платформа Java 2 Micro Edition
  • Глава 3. Средства разработки мобильных приложений
  • Глава 4. Телефонные эмуляторы
  • Глава 5. Механизм работы приложений Java 2 ME
  • Глава 6. Классы пользовательского интерфейса
  • Глава 7. Программирование графики
  • Глава 8. Техника создания игр
  • Глава 9. Мобильная мультимедиа-библиотека
  • Заключение
  • Приложение 1. Основы языка Java
  • Приложение 2. Справочник по Java 2 Micro Edition

     

    Программирование на Java

  • Введение
  • Глава 1. Встроенные типы данных, операции над ними
  • Глава 2. Объектно-ориентированное программирование в Java
  • Глава 3. Пакеты и интерфейсы
  • Глава 4. Классы-оболочки
  • Глава 5. Работа со строками
  • Глава 6. Классы-коллекции
  • Глава 7. Классы-утилиты
  • Глава 8. Принципы построения графического интерфейса
  • Глава 9. Графические примитивы
  • Глава 10. Основные компоненты
  • Глава 11. Размещение компонентов
  • Глава 12. Обработка событий
  • Глава 13. Создание меню
  • Глава 14. Апплеты
  • Глава 15. Изображения и звук
  • Глава 16. Обработка исключительных ситуаций
  • Глава 17. Подпроцессы
  • Глава 18. Потоки ввода/вывода
  • Глава 19. Сетевые средства Java
  • Приложение. Развитие Java

  • 

    3fb01dc2


     

     

    Как описать класс и подкласс

    Итак, описание класса начинается со слова class, после которого записывается имя класса. Соглашения "Code Conventions" рекомендуют начинать имя класса с заглавной буквы.

    Перед словом class можно записать модификаторы класса (class modifiers). Это одно из слов public, abstract, final, strictfp . Перед именем вложенного класса можно поставить, кроме того, модификаторы protected, private, static . Модификаторы мы будем вводить по мере изучения языка.

    Тело класса, в котором в любом порядке перечисляются поля, методы, вложенные классы и интерфейсы, заключается в фигурные скобки.

    При описании поля указывается его тип, затем, через пробел, имя и, может быть, начальное значение после знака равенства, которое можно записать константным выражением. Все это уже описано в главе 1.

    Описание поля может начинаться с одного или нескольких необязательных модификаторов public, protected, private, static, final, transient, volatile . Если надо поставить несколько модификаторов, то перечислять их JLS рекомендует в указанном порядке, поскольку некоторые компиляторы требуют определенного порядка записи модификаторов. С модификаторами мы будем знакомиться по мере необходимости.

    При описании метода указывается тип возвращаемого им значения или слово void , затем, через пробел, имя метода, потом, в скобках, список параметров. После этого в фигурных скобках расписывается выполняемый метод.

    Описание метода может начинаться с модификаторов public, protected, private, abstract, static, final, synchronized, native, strictfp . Мы будем вводить их по необходимости.

    В списке параметров через запятую перечисляются тип и имя каждого параметра. Перед типом какого-либо параметра может стоять модификатор final . Такой параметр нельзя изменять внутри метода. Список параметров может отсутствовать, но скобки сохраняются.

    Перед началом работы метода для каждого параметра выделяется ячейка оперативной памяти, в которую копируется значение параметра, заданное при обращении к методу. Такой способ называется передачей параметров по значению.

    В листинге 2.1 показано, как можно оформить метод деления пополам для нахождения корня нелинейного уравнения из листинга 1.5.

    Листинг 2.1. Нахождение корня нелинейного уравнения методом бисекцйи

    class Bisection2{

    private static double final EPS = le-8; // Константа 

    private double a = 0.0, b = 1.5, root;  // Закрытые поля

    public double getRoot(}{return root;}   // Метод доступа

    private double f(double x)

    {

    return x*x*x — 3*x*x + 3;   // Или что-то другое 

    }

    private void bisect(){      // Параметров нет —

                                // метод работает с полями экземпляра

    double у = 0.0;             // Локальная переменная — не поле 

    do{

    root = 0.5 *(а + b); у = f(root);

    if (Math.abs(y) < EPS) break;

    // Корень найден. Выходим из цикла

    // Если на концах отрезка [a; root] 

    // функция имеет разные знаки: 

    if (f(а) * у < 0.0} b = root;

          // значит, корень здесь

          // Переносим точку b в точку root

          //В противном случае: 

    else a = root;

          // переносим точку а в точку root

          // Продолжаем, пока [а; Ь] не станет мал 

    } while(Math.abs(b-a) >= EPS); 

    }

    public static void main(String[] args){ 

    Bisection2 b2 = new Bisection2(); 

    b2.bisect(); 

    System.out.println("x = " +

    b2.getRoot() +    // Обращаемся к корню через метод доступа 

    ", f() = " +b2.f(b2.getRoot())); 

    }

    В описании метода f() сохранен старый, процедурный стиль: метод получает аргумент, обрабатывает его и возвращает результат. Описание метода bisect о выполнено в духе ООП: метод активен, он сам обращается к полям экземпляра b2 и сам заносит результат в нужное поле. Метод bisect () — это внутренний механизм класса Bisection2, поэтому он закрыт (private).

    Имя метода, число и типы параметров образуют сигнатуру (signature) метода. Компилятор различает методы не по их именам, а по сигнатурам. Это позволяет записывать разные методы с одинаковыми именами, различающиеся числом и/или типами параметров.

    Замечание

    Тип возвращаемого значения не входит в сигнатуру метода, значит, методы не могут различаться только типом результата их работы.

    Например, в классе Automobile мы записали метод moveTo(int x, int у) , обозначив пункт назначения его географическими координатами. Можно определить еще метод moveTo (string destination) для указания географического названия пункта назначения и обращаться к нему так:

    oka.moveTo("Москва") ;

    Такое дублирование методов называется перегрузкой (overloading). Перегрузка методов очень удобна в использовании. Вспомните, в главе 1 мы выводили данные любого типа на экран методом  printin() не заботясь о том, данные какого именно типа мы выводим. На самом деле мы использовали разные методы t одним и тем же именем printin , даже не задумываясь об этом. Конечно, все эти методы надо тщательно спланировать и заранее описать в классе. Это и сделано в классе Printstream, где представлено около двадцати методов print() и println() .

    Если же записать метод с тем же именем в подклассе, например:

    class Truck extends Automobile{ 

    void moveTo(int x, int y){

       // Какие-то действия 

    }

       // Что-то еще 

    }

    то он перекроет метод суперкласса. Определив экземпляр класса Truck , например:

    Truck gazel = new Truck();

    и записав gazei.moveTo(25, 150) , мы обратимся к методу класса Truck . Произойдет переопределение (overriding) метода.

    При переопределении права доступа к методу можно только расширить. Открытый метод public должен остаться открытым, защищенный protected может стать открытым.

    Можно ли внутри подкласса обратиться к методу суперкласса? Да, можно, если уточнить имя метода, словом super , например, super.moveTo(30, 40) . Можно уточнить и имя метода, записанного в этом же классе, словом this , например, this.moveTo (50, 70) , но в данном случае это уже излишне. Таким же образом можно уточнять и совпадающие имена полей, а не только методов.

    Данные уточнения подобны тому, как мы говорим про себя "я", а не "Иван Петрович", и говорим "отец", а не "Петр Сидорович".

    Переопределение методов приводит к интересным результатам. В классе Pet мы описали метод voice() . Переопределим его в подклассах и используем в классе chorus , как показано в листинге 2.2.

    Листинг 2.2. Пример полиморфного метода

    abstract class Pet{

       abstract void voice(); 

    }

    class Dog extends Pet{

       int k = 10;

       void voice(){

          System.out.printin("Gav-gav!");

       }

    }

    class Cat extends Pet{

       void voice () {

          System.out.printin("Miaou!"); 

       }

    }

    class Cow extends Pet{ 

       void voice(){

          System.out.printin("Mu-u-u!");

       }

    }

    public class Chorus(

       public static void main(String[] args){ 

          Pet[] singer = new Pet[3]; 

          singer[0] = new Dog(); 

          singer[1] = new Cat(); 

          singer[2] = new Cow(); 

          for (int i = 0; i < singer.length; i++)

             singer[i].voice();

       }

    }

    На рис. 2.1 показан вывод этой программы. Животные поют своими голосами!

    Все дело здесь в определении поля singer[]. Хотя массив ссылок singer [] имеет тип Pet , каждый его элемент ссылается на объект своего типа Dog, Cat, cow . При выполнении программы вызывается метод конкретного объекта, а не метод класса, которым определялось имя ссылки. Так в Java реализуется полиморфизм.

    Знатокам C++

    В языке Java все методы являются виртуальными функциями.

    Внимательный читатель заметил в описании класса Pet новое слово abstract . Класс Pet и метод voice() являются абстрактными.

    Рис. 2.1. Результат выполнения  программы Chorus

     

    -
    



    Copyright © vzlom-1.ru 2020-2021