Segédanyag: Java alkalmazások gyakorlat Készítette: Szabó Attila 2009/2010-2 félév, 2. gyakorlat 1 Osztályok és objektumok default, public, protected, private láthatóság a metódusokra és adattagokra (első órán szerepelt) az osztályobjektumok refrenciákon keresztül érhetők el (memóriacímet tárolnak) a referenciák értéke lehet null (a mutatott objektum típusától függetlenül) final kulcsszó: a referencia nem módosítható, a mutatott érték megváltozhat static kulcsszó: osztályszintű adattag vagy metódus: objektum példányosítás nélkül is létezzik és használható, illetve hívható 2 Származtatás az ősosztály szolgáltatásainak bővítésére alkalmas módszer kódújrafelhasználást segíti elő (jó, mert nem szeretjük ismételni a kódot) altípusképzés támogatja a nyelvben (programtervezési tervezési eszköz) Javaban altípusos polimorfizmus van a leszármazott rendelkezik a szülő metódusaival, adattagjaival a leszármazott típusú referencia mutathat szülő típusú objektumra statikus típus: a deklarált típus dinamikus típus: a referált objektum aktuális típusa @Override annotáció: explicit jelzés a metódus felüldefiniálására Object.equals()-t, Object.hashCode()-ot, Object.toString()-et szokás leggyakrabban felüldefiniálni 3 Kivételek Az Exception osztály dokumentációja: http://java.sun.com/j2se/1.5.0/docs/api/java/lang/exception.html (Kivételek: http://rymden.nu/exceptions.html:)) 4 I/O kezelés Néhány alapvető, fájlkezelésnél hasznos osztály: Osztály neve java.io.bufferedreader java.io.filereader java.io.printwriter Leírás Megvalósítja az alapvető olvasási funkciókat: ready(), readline(), stb. Egy java.io.filereader objektumot vár konstruktorparaméterként. Egy fájl elérési útját várja paraméterként. Megvalósítja az alapvető írási funkciókat: println(), stb. Egy java.io.filewriter objektumot vár konstruktorparaméterként és egy boolean értéket: törölje-e a fájlt a megnyitáskor. 1
java.io.filewriter java.util.stringtokenizer java.io.ioexception java.io.filenotfoundexception Egy fájl elérési útját várja paraméterként. Egy String objektumot felbont mezőkre a megadott szeparátor mentén. A java.io.filewriter konstruktora (is) dobja, ha nem sikerül inicializálni az objektumot. A java.io.filereader konstruktora (is) dobja, ha nincs meg a fájl. 5 Példaprogramok A program használni fog egy naplófájlt a hibák kiíratására. A naplózást megvalósító Logger.java forráskódja: package io; import java.io.filewriter; import java.io.ioexception; import java.io.printwriter; import java.util.calendar; public class Logger { //members private static PrintWriter logwriter; private static String file = "log"; //constructors public Logger(){ public Logger( String filename ){ if( filename!= null ) file = filename; //public methods public static void logstring( String line ){ if( logwriter == null ){ logwriter = new PrintWriter( new FileWriter( file, true ) ); catch( IOException e ){ System.out.println( "Couldn't open the log file!" ); Calendar calendar = Calendar.getInstance(); String timestamp = String.valueOf( calendar.get( Calendar.YEAR ) ) + "." + String.valueOf( calendar.get( Calendar.MONTH ) + 1 ) + "." + String.valueOf( calendar.get( Calendar.DATE ) ) + ". " + String.valueOf(calendar.get( Calendar.HOUR ) ) + ":" + String.valueOf( calendar.get( Calendar.MINUTE ) ) + ":" + String.valueOf( calendar.get( Calendar.SECOND ) ) + ":" + String.valueOf( calendar.get( Calendar.MILLISECOND ) ); logwriter.println( timestamp ); logwriter.println(line ); 2
logwriter.flush(); @Override protected void finalize() throws Throwable { logwriter.close(); super.finalize(); A főprogram (IOExampleMain.java) forráskódja: package ioexample; import io.logger; import java.io.bufferedreader; import java.io.filenotfoundexception; import java.io.filereader; import java.io.ioexception; import java.util.iterator; import java.util.stringtokenizer; import java.util.vector; public class IOExampleMain { private static BufferedReader reader = null; private static int linenum = 0; private static int position = 0; private static Vector<Integer> values = new Vector<Integer>(); //public functions public static void main( String[] args ){ //read file: args[0] if( args.length!= 1 ){ System.out.println( "Usage: java ioexample.ioexamplemain <filename>" ); //create reader reader = new BufferedReader( new FileReader( args[0] ) ); catch( FileNotFoundException e ){ System.out.println( "Cannot open file " + "(see log for details)!" ); Logger.logString( "Couldn't open the specified file" ); //read file while( reader.ready() ){ linenum++; String line = reader.readline(); StringTokenizer tokenizer = new StringTokenizer( line ); while( tokenizer.hasmoretokens() ){ position++; String token = tokenizer.nexttoken(); Integer value = 0; value = Integer.valueOf( token ); 3
catch( NumberFormatException e ){ System.out.println( "Error while parsing numbers " + "(see log for details)!" ); Logger.logString( "Error while parsing numbers: line " + linenum + " position " + position ); values.add( value ); reader.close(); catch( IOException e ){ System.out.println( "Error (see log for details)!" ); Logger.logString( "Error: line " + linenum + " position " + position ); //do sg with data SequenceTester tester = new SequenceTester( 1, 3 ); boolean ispermutation = tester.ispermutation( values ); if( ispermutation ){ System.out.println( "The sequence is a permutation!" ); else{ System.out.println( "The sequence is not a permutation!" ); Iterator<Integer> it = values.iterator(); while( it.hasnext() ){ System.out.print( it.next() + " " ); Az input fájl formátuma: az input fájl egész számokat tartalmaz whitespace-ekkel elválasztva. A főprogramban használt SequenceTester forráskódja (egy vektorról képes megállapítani, hogy a tárolt elemek egy megadott intervallum permutációját adják-e): package ioexample; import java.util.iterator; import java.util.vector; public class SequenceTester{ //======================================================================== //members protected int minvalue = 0; protected int maxvalue = 0; //construstors public SequenceTester( int min, int max ){ if( min <= max ){ minvalue = min; maxvalue = max; //public functions public boolean ispermutation( Vector<Integer> candidate ){ //check candidate size: too short or too long sequence cannot be a permutation 4
if( candidate.size()!= maxvalue - minvalue + 1 ) return false; //init the ok vector Vector<Boolean> isok = new Vector<Boolean>( candidate.size() ); for( int i = 0; i < candidate.size(); ++i ) isok.add( i, false ); Iterator<Integer> it = candidate.iterator(); while( it.hasnext() ){ Integer act = it.next(); if( minvalue <= act && act <= maxvalue ){ if(!isok.get( act - minvalue ) ){ isok.set( act - minvalue, true ); else{ return false; //this number is duplicated in the sequence else{ return false; //the next number is out of the interval return true; 6 Feladat 1. Írj sudoku ellenőrző osztályt! Az osztály származzon a SequenceTester osztályból, és ellenőrző metódusokkal egészítse ki azt. protected boolean checkrows( Vector<Integer> candidate ): Ellenőrzi a paraméterként kapott sudoku sorainak helyességét (pl: 9x9-es sudoku esetén candidate vektor sorfolytonos ábrázolásban tárolja a 81 elemet). A megvalósításhoz használja az alábbi segédfüggvényt. protected Vector<Integer> getrow( Vector<Integer> candidate, int index ): A metódus visszaadja a sudoku megadott sorát. protected boolean checkcols( Vector<Integer> candidate ): Ellenőrzi a paraméterként kapott sudoku oszlopainak helyességét. A megvalósításhoz használja az alábbi segédfüggvényt. protected Vector<Integer> getcol( Vector<Integer> candidate, int index ): a metódus visszaadja a sudoku megadott oszlopát. protected boolean checkblocks( Vector<Integer> candidate ): Ellenőrzi a paraméterként kapott sudoku blokkjainak helyességét. A megvalósításhoz használja az alábbi segédfüggvényt. protected Vector<Integer> getblock( Vector<Integer> candidate, int index ): a metódus visszaadja a sudoku megadott blokkját. A három ellenőrző függvényt hívd meg egy publikus isvalidsudoku metódusban. Írj az ellenőrző osztályhoz tesztprogramot! A program várja egy szöveges fájlban a sudokut: a sudoku sorai külön sorokban, az egyes sorok elemei whitespace-el elválasztva következzenek a fájlban. 5