Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
4 конспект лекций ООП Java.doc
Скачиваний:
28
Добавлен:
03.05.2015
Размер:
962.05 Кб
Скачать

Анонимные классы

Можно объявить анонимный (безымянный) класс, который может расширить другой класс или реализовать интерфейс. Объявление такого класса выполняется одновременно с созданием его объекта посредством оператора new.

class Base{

voidshow(){}

}

//объявление класса и его тела

Base ob = new Base(){

void show(){

//новая реализация

    }

};

Анонимные классы эффективно используются, как правило, для реализации (переопределения) нескольких методов и создания собственных методов объекта. Конструкторы ни определять, ни переопределять нельзя. Анонимные классы допускают вложенность друг в друга, что очень сильно запутывает код и делает эти конструкции непонятными, поэтому эти возможности обычно не используются.

/* пример # 6 : анонимные классы и логические блоки : AnonymousDemo.java*/

abstract class A {

    private char c = 'A';

    A() {

    }

    A(char c) {

         this.c = c;

    }

    public char getC() {

         return c;

    }

    public abstract int getNum();

}

classAnonymousDemo {

    static int j = 2;

    static A ob1 = new A((char) 57) {

    //A(charc) {ch=c+ 1;}

// ошибка! Конструктор переопределять нельзя

         {

    System.out.println("первый анонимный класс");

         }

         public int getNum() {

             return Character.digit(getC(), 10);

         }

    };

    public static void main(String[] args) {

         System.out.println(ob1.getNum());

         A ob2 = new A() {

             int i = 1;

             {

    System.out.println("второй анонимный класс");

             }

             public int getNum() {

         i = show(); //вызов собственного метода

    return i + Character.getNumericValue(getC());

             }

             int show() {

                 return i + j;

             }

         };

         System.out.println(ob2.getNum());

    }

}

В результате будет выведено:

первый анонимный класс

9

второй анонимный класс

13

При запуске приложения происходит инициализация полей и выполнение логических блоков класса, содержащего метод main(), поэтому сначала выполняются логические блоки при объявлении поляob1. Затем вmain()полеob1вызывает методgetNum(), реализованный анонимным (безымянным) классом. Процесс создания объектаob2и последующего вызова методаgetNum()отличаются только тем, что объектob2создается как локальный объект методаmain(). В этом случае нет необходимости строить различные реализации классаA, для того чтобы получить немного отличающиеся версии метода.

Использование библиотек классов Файлы. Потоки ввода/вывода

Для работы с файлами в приложениях Javaмогут быть использованы классы из пакетаjava/io.

Класс Fileслужит для хранения и обработки в качестве объектов каталогов и имен файлов. Этот класс не описывает способы работы с содержимым файла, но позволяет манипулировать такими свойствами файла, как права доступа, дата и время создания, путь в иерархии каталогов, создание, удаление, изменение имени файла и каталога и т.д.

Основные методы класса Fileи способы их применения рассмотрены в следующем примере

// пример # 1 : работа с файловой системой : FileTest.java

packagecom.learn;

importjava.io.*;

importjava.util.*;

public class FileTest {

public static void main(String[] args) throws

IOException/*отказ от обработки исключения вmain()*/ {

//cобъектом типаFileассоциируется файл на диске

     File fp = new File("com\\learn\\FileTest.java");

//другие способы создания объекта

     //File fp = new File("\\com\\learn", "FileTest.java");

     //File fp=new File("d:\\temp\\demo.txt");

     //File fp=new File("demo.txt");

         if(fp.isFile()){//если объект дисковый файл

     System.out.println("Имя файла:\t" +fp.getName());

     System.out.println("Путь к файлу:\t" +fp.getPath());

     System.out.println("Абсолютный путь:\t" +fp.getAbsolutePath());

     System.out.println("Канонический путь:\t" +fp.getCanonicalPath());

     System.out.println("Размер файла:\t" +fp.length());

     System.out.println("Последняя модификация файла:\t" +fp.lastModified());

     System.out.println("Файл доступен для чтения:\t" +fp.canRead());

     System.out.println("Файл доступен для записи:\t" +fp.canWrite());

     System.out.println("Файл удален:\t" +fp.delete());          }

         if(fp.createNewFile()){

System.out.println("Файл " +fp.getName() + " создан");

         }

         if(fp.exists()){

System.out.println("tempфайл "+fp.getName() + " существует");

         }

         else

System.out.println("tempфайл " +fp.getName() + " не существует");

//в объект типа Fileпомещается каталог\директория

              File dir = new File("com\\learn");

if(dir.isDirectory())/*если объект объявлен как каталог на диске*/

System.out.println("Директория!");

         if(dir.exists()){//если каталог существует

     System.out.println("Dir " + dir.getName() + " существует");

              File [] files = dir.listFiles();

              System.out.println("");

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

         Date date = new Date(files[i].lastModified());

System.out.println(files[i].getPath() + " \t| " + files[i].length() + "\t| " + date.toString());//toLocaleString());//toGMTString())

              }

         }   

     }

}

У каталога (директории) как объекта класса Fileесть дополнительное свойствопросмотр списка имен файлов с помощью методовlist(), listFiles(), listRoots().

Потоки ввода последовательности байт являются подклассами абстрактного класса InputStream,  потоки вывода последовательности байтподклассами абстрактного классаOutputStream. При работе с файлами используются подклассы  этих классов соответственноFileInputStreamиFileOutputStream, конструкторы которых открывают поток и связывают его с соответствующим файлом.

Рис.1. Иерархия классов потоков ввода.

Рис.2. Иерархия классов потоков вывода.

Для чтения байта или массива байт используются перегружаемый метод read()/read(byte[] b) классаFileInputStream. Метод возвращает1, если достигнут конец потока данных. Поэтому возвращаемое значение имеет типint.

/* пример # 2 : чтение байтов из потока ввода : ReadBytes.java */

importjava.io.*;

public class ReadBytes {

  public static void main(String[] args){

    int b;

 try {

File f = new File("ReadBytes.java");

FileInputStream is = new FileInputStream(f);

     while((b=is.read()) != -1){

//прочитанные данные выводятся на консоль

    System.out.println("прочитан байт = " + b);

    }

   is.close(); //закрытие потока ввода

}

catch(IOException e){

System.out.println("ошибка файла: " + e);

}

}

}

Конструктор FileInputStream("ReadBytes.java") открывает поток is и связывает его с файлом ReadBytes.java. Для закрытия потока используется метод close(). При чтении из потока можно пропуститьnбайт с помощью метода long skip(long n).

Класс System пакета java.lang содержит полеin, которое является ссылкой на объект класса InputStream, и поляout, err класса PrintStream, объявленные со спецификаторамиpublic staticи являющиеся стандартными потоками ввода, вывода и вывода ошибок соответственно. Эти потоки связаны с консолью, но могут быть переназначены на другое устройство. В настоящее время в языкеJavaдля консольного ввода используется не байтовый, а символьный поток. При этом для ввода используется подклассBufferedReader абстрактного классаReader и методыread()иreadLine() чтения символа и строки.

Рис.3. Иерархия символьных потоков ввода/вывода.

Следующая программа демонстрирует ввод строки, числа и символа с консоли и вывод на консоль и в файл.

// пример # 6 : ввод  с консоли : ConsoleInput.java

importjava.io.*;

public class ConsoleInput {

    public static void main(String[] args){

InputStreamReader is = new InputStreamReader(System.in);

BufferedReader bistream = new BufferedReader(is);

try{

charc;

     int number;

System.out.println("введите имя и нажмите <ввод>:");

   String nameStr = bistream.readLine();

System.out.println(nameStr + " введите число:");

   String numberStr = bistream.readLine();

   number = Integer.valueOf(numberStr).intValue();

System.out.println(nameStr + "  вы ввели число " + number);

System.out.println(nameStr + "  введите символ:");

   c = (char)bistream.read();

System.out.println(nameStr+ "  вы ввели символ  " +c);

//Вывод в файл  

PrintStream ps = new PrintStream(

newFileOutputStream ("res.txt"));

ps.println("привет " + nameStr + c + number);

ps.close();

} catch (IOException e){

System.out.println("ошибка ввода " + e);

}

}

}

Для вывода данных в файл в текстовом формате использовался фильтрованный поток вывода PrintStreamи методprintln(). МетодvalueOf(String str)возвращает объект классаInteger, соответствующий цифровой строке, методintValue()преобразует значение этого класса к базовому типуint.

Процесс преобразования объектов в байтовые потоки для хранения называется сериализацией. Процесс извлечения объекта из байтового потока называется десериализацией. Для того чтобы объекты класса могли быть подвергнуты процессу сериализации, этот класс должен расширять интерфейс Serializable. Этот процесс заключается в сериализации каждого поля объекта, но только в том случае если это поле не имеет модификатора static или transient. Модификатор transient означает, что поле им помеченное, не может быть предметом сериализации.

Интерфейс Serializableне имеет методов, которые необходимо реализовать, поэтому его использование ограничивается упоминанием при объявлении класса. Все действия в дальнейшем произодятся по умолчанию. Ввод/вывод объектов производится с использование потоковObjectOutputStreamиObjectInputStream.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]