И.Н. Блинов, В.С. Романчик - Основы программирования на языке Java (1160783), страница 4
Текст из файла (страница 4)
Конструктор не возвращает значение, но может иметь параметры и быть перегружаемым.//пример # 4 : перегрузка конструктора: Book.javaclass Book{String title, publisher;float price;Book(String title, String publisher, float price) {/* конструктор*/}Book(String t, float p){ //второй конструкторtitle = new String(t);price = p; }void printBookInfo(){/*реализация*/}}Объект класса Book может быть создан двумя способами, вызывающими один из конструкторов:Book tips = new Book("Java 2","П.Ноутон, Г.Шилдт",49.95);Book tips = new Book("Java 2",49.95);Объявление можно отделить от инициализации:Book tips ; // объявлениеtips = new Book("Java 2",49.95);// инициализация22Если конструктор в классе не определен, Java предоставляет конструктор по умолчанию, который инициализирует объект значениямипо умолчанию.Использование super и thisКлючевое слово super используется для вызова конструкторасуперкласса и для доступа к члену суперкласса.
Например:super(список_параметров); // вызов конструктора суперклассаsuper.i = a; //присваивание значения члену суперклассаsuper(x,y); //передача параметров конструктору базового классаВторая форма super подобна ссылке this на экземпляр класса. Каждый экземпляр класса имеет неявную ссылку this на себя, котораяпередается также и методам. После этого можно писать this.good;this.price, хотя и необязательно. Ссылку this можно использовать вметоде для доступа к переменной класса, если в методе есть локальнаяпеременная с тем же именем.Следующий код показывает, как, используя this и перегрузку методов, можно строить одни конструкторы на основе других.//пример # 5 : this в конструкторе : Locate.javaclass Locate {int х, у;Locate(int х, int у) {this.x = х; this.у = у; }Locate() { this(-1, -1); }}В этом фрагменте второй конструктор для завершения инициализации объекта обращается к первому конструктору.Абстрактные классыАбстрактные классы объявляются с ключевым словом abstract исодержат объявления абстрактных методов, которые не реализованы вэтих классах.
Объекты таких классов создать нельзя, можно создатьобъекты подклассов, которые реализуют эти методы.//пример #6: абстрактные методы и классы: AbstractDemo.javaabstract class Square {abstract int squareIt(int i); //абстрактный методvoid show(){/*реализация*/}}//squareIt() должен быть реализован подклассом Square23class SquareTwo extends Square {int squareIt(int i) { return i*i; }}class AbstractDemo {public static void main(String[] args) {SquareTwo ob = new SquareTwo();System.out.println("10 в квадрате равно " + ob.squareIt(10));} }Результат: 10 в квадрате равно 100Методы finalize аналогичны деструкторам в C++.
Исполняющаясреда Java будет вызывать его каждый раз, когда сборщик мусора соберется уничтожить объект этого класса.Упражнения1 .Записать конструктор для массива объектов, объявленных следующим образом MyСlass b[3]={1,2,3};2. Проинициализировать объект производного класса, если конструктор базового класса задан с двумя параметрами3. Как объявить массив объектов абстрактного класса?4. В приведенном ниже примере рассматривается класс двоичное дерево.Объяснить, как строится дерево, как подсчитывается число включений слова, каквводятся строки и выделяются слова.import java.io.*;import java.util.*;class Node {String word;int count;Node left, right;Node (String new_word) {word = new_word; count = 1;left = right = null; }}class Btree {Node root;Btree() { root = null; }void insert(Node node, String new_word) {int compare = node.word.compareTo(new_word);if (compare == 0) {node.count++; } // слово уже существуетelse if (compare > 0) {if (node.left != null) insert (node.left, new_word);else node.left = new Node(new_word);}else if (compare < 0) {if (node.right != null) insert (node.right, new_word);else node.right = new Node(new_word);}}void insert_word (String new_word) {if (root == null) { root = new Node(new_word);}24else { insert (root, new_word); }}Node find(Node node, String keyword) {int compare = node.word.compareTo(keyword);if (compare == 0) return node; // найдено ключевое словоelse if (compare > 0) {if (node.left != null) return find (node.left, keyword);else return null; /* ключевое слово не найдено*/}else if (compare < 0) {if (node.right != null) return find (node.right, keyword);else return null;}return null;}int count_word (String keyword) {if (root != null) {Node node = find (root, keyword);if (node != null) return node.count;else return 0;}return 0; // дерево пусто}}public class Wordtree {public static void main (String args[]) {Btree btree = new Btree();try {// открытие файла и вставка слова в двоичное деревоFileReader is = new FileReader("Wordtree.java");BufferedReader bis = new BufferedReader(is);String thisLine;while ((thisLine = bis.readLine()) != null) {StringTokenizer st = new StringTokenizer(thisLine," \t\n\r");while (st.hasMoreTokens()) {btree.insert_word (new String (st.nextToken())); }}} catch (Exception e) { System.out.println("ошибка: " + e); }// получение числа словSystem.out.println("Число слов ' Java ' = "+btree.count_word("Java"));}}5.
ИНТЕРФЕЙСЫ. ПАКЕТЫИнтерфейсы представляют полностью абстрактные классы: ниодин из объявленных методов не может быть им реализован. Все ме25тоды автоматически трактуются как public и abstract, а все переменные – как public, static и final. Каждый интерфейс может быть реализован одним или несколькими классами, не связанными по иерархиинаследования. Класс может реализовывать любое число интерфейсов,указываемых после ключевого слова implements, дополняющего определение класса. На множестве интерфейсов тоже определена иерархия по наследованию, но она не имеет отношения к иерархии классов.В языке Java интерфейсы обеспечивают большую часть той функциональности, которая в C++ представляется с помощью механизма множественного наследования. Определение интерфейса имеет вид:[public] interface имя [extends I1,I2,…,IN]{/*реализация*/}Класс также может наследовать любое число интерфейсов:[доступ] class имя_ класса implements I1,I2, …,IN {/*…реализация…*/}Класс, который реализует интерфейс, должен предоставить полную реализацию всех методов, объявленных в интерфейсе.
Кроме этого, данный класс может объявлять свои собственные методы. Есликласс включает интерфейс, но полностью не реализует его методы, тоэтот класс должен быть объявлен как abstract.// пример #1 : интерфейс и его реализации : InterfacesDemo.javainterface Auto{public String getMark();public String getPassangers();public String getWheels();}class Bus implements Auto{public String getMark(){return "Mercedes";}public String getPassangers(){return "90 человек";}public String getWheels(){return "6 колес";}}class Car implements Auto{public String getMark(){return "BMV";}public String getPassangers(){return "5 человек";}public String getWheels(){return "4 колеса";}}public class InterfacesDemo {public static void main(String[] args){Car c = new Car();Bus b = new Bus();printFeatures(c);printFeatures(b);26}public static void printFeatures(Auto f){System.out.println("марка:"+f.getMark()+" вместимость:"+f.getPassangers()+" количество колес: "+f.getWheels());}}Класс InterfacesDemo содержит метод printFeatures(), которыйвызывает методы того объекта, который передается ему в качествепараметра.
Вначале ему передается объект, соответствующий легковому автомобилю, затем автобусу (объекты с и b). Каким образом метод printFeatures() может обрабатывать объекты двух различныхклассов? Все дело в типе передаваемого этому методу аргумента –класса, реализующего интерфейс Auto. Вызывать, однако, можнотолько те методы, которые были объявлены в интерфейсе.В следующем примере объявляется объектная ссылка, которая использует интерфейсный тип. В такой переменной можно сохранятьэкземпляр любого класса, который реализует объявленный интерфейс.Когда вызывается метод через такую ссылку, то будет вызываться егоправильная версия, основанная на текущем экземпляре.
Выполняемыйметод разыскивается динамически во время выполнения, что позволяет создавать классы позже кода, который вызывает их методы.// пример #2: динамический вызов функций: TestCall.javainterface Callback {void callB(int param); }class Client implements Callback {public void callB(int p) {System.out.println("метод callB() вызван со значением = " + p);}void myMethod() {System.out.println("класс, реализующий интерфейс " +"может иметь свои собственные методы");}}class XClient implements Callback {public void callB(int p) {System.out.print("другая версия метода callВ():");System.out.println("p в квадрате = " + (p*p));}}class TestCall{27public static void main(String[] args) {Callback c = new Client();XClient ob = new XClient();c.callB(11);c = ob; // c присваивается ссылка на другой объектc.callB(11);}}Результат: метод сallB() вызван со значением = 11другая версия метода callB(): p в квадрате = 121ПакетыОператор package, помещаемый в начале исходного программногофайла, определяет пакет, т.
е. область в пространстве имен классов, вкоторой определяются имена классов, содержащихся в этом файле.Внутри указанной области можно выделить подобласти, используятот же оператор package; действие оператора package аналогичнодействию объявления директории на имена файлов. Для обеспечениявозможности использования коротких имен классов, помещенных вдругие пакеты, используется оператор import. Приведем общую форму исходного файла Java:одиночный оператор package (необязателен);любое количество операторов import (необязательны);одиночное объявление открытого (public) класса {/*код*/}любое количество закрытых (private) классов пакета (необязательны) {/*код*/}Каждый класс принадлежит некоторому пакету и добавляется впакет при компиляции. Для добавления класса в какой-то пакет указывается этот пакет после слова package. Например:// пример #3 : простейший пакет : AccountBalance.javapackage com.MyPack;class Balance {String name; double bal;Balance(String n, double b) {name = n; bal = b; }void show() {if(bal < 0) System.out.print("-->> ");else System.out.println(name + ": $" + bal);}}public class AccountBalance {28public static void main(String[] args) {Balance current[] = new Balance[3];current[0] = new Balance("Билл Гейтс", 150000000.0);current[1] = new Balance("Борис Березовский", -170000.02);current[2] = new Balance("Ясир Арафат", 666000.11);for(int i = 0; i < 3; i++) current[i].show();}}Файл начинается с объявления того, что данный класс принадлежит пакету MyPack.