CATEGORII DOCUMENTE |
Interfete si clase abstracte
Clase abstracte in Java
Generalizarea si abstractizarea in programarea cu obiecte sunt realizate si prin clase abstracte.
O superclasa defineste un tip mai general decat tipurile definite prin subclasele sale; de exemplu, tipul Number este o generalizare a tipurilor clasa numerice (Double, Float, Integer, Short, Byte). Uneori superclasa este atat de generala incat nu poate preciza nici variabile si nici implementari de metode, dar poate specifica ce operatii (metode) ar fi necesare pentru toate subclasele sale. In astfel de cazuri superclasa Java este fie o clasa abstracta, fie o interfata.
O metoda abstracta este declarata cu atributul abstract si nu are implementare. Ea urmeaza a fi definita intr-o subclasa a clasei (interfetei) care o contine. Metodele abstracte pot apare numai in interfete si in clasele declarate abstracte.
O clasa care contine cel putin o metoda abstracta trebuie declarata ca abstracta, dar nu este obligatoriu ca o clasa abstracta sa contina si metode abstracte. O clasa abstracta nu este instantiabila, dar ar putea contine metode statice sau nestatice utilizabile in subclase.
In Java avem doua posibilitati de a defini clase care contin doar metode statice si, ca urmare, nu pot fi instantiate (nu pot genera obiecte):
- Clase ne-abstracte, cu constructor private, care impiedica instantierea;
- Clase abstracte, care nici nu au nevoie de un constructor
Spre deosebire de interfete, clasele abstracte pot contine variabile si metode neabstracte.
O clasa abstracta este de multe ori o implementare partiala a unei interfete, care contine atat metode abstracte cat si metode definite. Exemplu:
public interface Collection
public abstract class AbstractCollection implements Collection // metoda implementata
.
}
Scopul unei clase abstracte nu este acela de a genera obiecte utilizabile, ci de a transmite anumite metode comune pentru toate subclasele derivate din clasa abstracta (metode implementate sau neimplementate). O clasa abstracta constituie o baza de plecare pentru definirea altor clase.
Derivarea dintr-o clasa abstracta se face la fel ca derivarea dintr-o clasa neabstracta folosind cuvantul extends. Exemplu:
public class MyCollection extends AbstractCollection
public int size()
. // alte metode
}
O clasa abstracta poate face o implementare partiala, deci poate contine si metode neabstracte si/sau variabile in afara metodelor abstracte. Pentru a obtine clase instantiabile dintr-o clasa abstracta trebuie implementate toate metodele abstracte mostenite, respectand declaratiiile acestora ( ca tip si ca argumente).
In bibliotecile de clase Java exista cateva clase adaptor, care implementeaza o interfata prin metode cu definitie nula, unele redefinite in subclase. Ele sunt clase abstracte pentru a nu fi instantiate direct, dar metodele lor nu sunt abstracte, pentru ca nu se stie care din ele sunt efectiv necesare in subclase. Exemplu de clasa adaptor utila in definirea de clase ascultator la evenimente generate de tastatura:
public abstract class KeyAdapter implements KeyListener // la apasare+ridicare tasta
public void keyPressed(KeyEvent e) // numai la apasare tasta
public void keyReleased(KeyEvent e) // numai la ridicare tasta
}
O subclasa (care reactioneaza la evenimente generate de taste) poate redefini numai una din aceste metode, fara sa se preocupe de celalte metode nefolosite de subclasa:
class KListener extends KeyAdapter
}
Interfete Java
O interfata Java ar putea fi considerata ca o clasa abstracta care nu contine decat metode abstracte si, eventual, constante simbolice. Totusi, exista deosebiri importante intre interfete si clase abstracte.
Metodele declarate intr-o interfata sunt implicit publice si abstracte.
De exemplu, interfata mai veche Enumeration contine doua metode comune oricarei clase cu rol de enumerare a elementelor unei colectii :
public interface Enumeration
Enumerarea unor obiecte poate fi privita ca o alternativa la crearea unui vector cu obiectele respective, in vederea prelucrarii succesive a unui grup de obiecte.
O clasa (abstracta sau instantiabila) poate implementa una sau mai multe interfete, prin definirea metodelor declarate in interfetele respective.
Dintre clasele care implementeaza aceasta interfata, sunt clasele enumerator pe vector si enumerator pe un tabel de dispersie Hashtable. Ulterior s-au adaugat metode din aceasta interfata si clasei StringTokenizer, care face o enumerare a cuvintelor dintr-un text:
public class StringTokenizer implements Enumeration
public Object nextElement()
}
Utilizarea unei interfete comune mai multor clase permite unificarea metodelor si modului de utilizare a unor clase cu acelasi rol, dar si scrierea unor metode general aplicabile oricarei clase care respecta interfata comuna. Exemplu de metoda care calculeaza de cate ori apare un obiect intr-o colectie de obiecte care are un enumerator:
public static int count (Enumeration enum, Object obj)
// utilizare
public static void main(String arg[]) ;
Vector v = new Vector (Arrays.asList(a));
System.out.println (count (v.elements(),"1"));
}
Nu pot fi create obiecte de un tip interfata sau clasa abstracta, dar se pot declara variabile, argumente formale si functii de un tip interfata sau clasa abstracta.
Prin definirea unei interfete sau clase abstracte se creeaza un tip de date comun mai multor clase deoarece o variabila (sau un argument) de un tip interfata poate fi inlocuita fara conversie explicita cu o variabila de orice subtip, deci cu referinte la obiecte care implementeaza interfata sau care extind clasa abstracta.
Ca si in cazul claselor abstracte, se pot defini variabile, functii sau argumente de functii de un tip interfata. Astfel de variabile vor fi inlocuite (prin atribuire sau prin argumente efective) cu variabile de un tip clasa care implementeaza interfata respectiva. Exemplu:
// varianta pentru metoda Vector.toString
public final String toString()
buf.append('b]');
return buf.toString();
}
}
In exemplul anterior, metoda "elements" din clasa Vector are ca rezultat un obiect "enumerator pe vector", de tipul Enumeration. Exemplu de posibila implementare a metodei "elements" din clasa "Vector" :
public Enumeration elements()
// definirea clasei iterator pe vector
class VectorEnumerator implements Enumeration
public boolean hasMoreElements()
public Object nextElement()
}
O interfata poate extinde o alta interfata (extends) cu noi metode abstracte. Ca exemplu, interfata TreeNode reuneste metode de acces la un nod de arbore, iar interfata MutableTreeNode o extinde pe prima cu metode de modificare nod de arbore (dupa crearea unui arbore poate fi interzisa sau nu modificarea sa):
public interface MutableTreeNode extends TreeNode
O clasa poate implementa (implements) o interfata sau mai multe si poate extinde (extends) o singura clasa (abstracta sau nu).
Clasele care implementeaza o aceeasi interfata pot fi foarte diverse si nu formeaza o ierarhie (o familie). Un exemplu sunt clasele cu obiecte comparabile, care toate implementeaza interfata Comparable: String, Date, Integer, BigDecimal, s.a.
O interfata este considerata ca un contract pe care toate clasele care implementeaza acea interfata se obliga sa il respecte, deci o clasa isi asuma obligatia de a defini toate metodele din interfetele mentionate in antetul ei, putand contine si alte metode.
O clasa poate simultan sa extinda o clasa (alta decat clasa Object, implicit extinsa) si sa implementeze una sau mai multe interfete. Altfel spus, o clasa poate mosteni date si/sau metode de la o singura clasa, dar poate mosteni mai multe tipuri (poate respecta simultan mai multe interfete). De exemplu, mai multe clase predefinite SDK, cu date, implementeaza simultan interfetele Comparable (obiectele lor pot fi comparate si la mai mic - mai mare), Clonable (obiectele lor pot fi copiate), Serializable (obiectele lor pot fi salvate sau serializate in fisiere disc sau pe alt mediu extern). Exemple:
public class String implements Comparable, Serializable
public class Date implements Serializable, Clonable, Comparable
Este posibil ca in momentul definirii unei interfete sa nu existe nici o singura clasa compatibila cu interfata, cum este cazul interfetei Comparator.
O interfata fara nici o metoda poate fi folosita pentru a permite verificarea utilizarii unor metode numai in anumite clase, in faza de executie. Un exemplu tipic este interfata Clonable, definita astfel:
public interface Clonable
Clasa Object contine metoda 'clone', folosita numai de clasele care declara ca implementeaza interfata Clonable. Metoda neabstracta 'clone' este mostenita automat de toate clasele Java, dar este aplicabila numai pentru o parte din clase.
Pentru a semnala utilizarea gresita a metodei 'clone' pentru obiecte ne-clonabile, se produce o exceptie de tip CloneNotSupportedException atunci cand ea este apelata pentru obiecte din clase care nu adera la interfata Clonable.
O utilizare asemanatoare o are interfata Serializable, pentru a distinge clasele ale caror obiecte sunt serializabile (care contin metode de salvare si de restaurare in / din fisiere) de clasele ale caror obiecte nu pot fi serializate ( fara obiecte 'persistente'). Practic, toate clasele cu date sunt serializabile.
Interfete ca Serializable si Clonable se numesc interfete de 'marcare' a unui grup de clase ('tagging interfaces'), pentru a permite anumite verificari.
Clasa Object nu contine o metoda de comparare pentru stabilirea unei relatii de precedenta intre obiecte, dar daca s-ar fi decis ca metoda 'compareTo' sa faca parte din clasa Object, atunci ar fi fost necesara o interfata de 'marcare' pentru a distinge clasele cu obiecte comparabile de clasele cu obiecte necomparabile.
O interfata care stabileste un tip comun poate fi atat de generala incat sa nu contina nici o metoda. Un exemplu este interfata EventListener (pachetul 'java.util'), care stabileste tipul "ascultator la evenimente", dar metodele de tratare a evenimentului nu pot fi precizate nici ca prototip, deoarece depind de tipul evenimentului. Interfata este extinsa de alte interfete, specifice anumitor ascultatori (pentru anumite evenimente):
public interface ActionListener extends EventListener
public interface ItemListener extends EventListener
Interfetele sunt preferabile in general claselor abstracte, pentru ca ofera mai multa libertate subclaselor. Un exemplu simplu este cel al metodelor considerate esentiale pentru orice clasa dictionar: pune pereche cheie-valoare in dictionar, obtine valoarea asociata unei chei date s.a. Aceste metode au fost reunite inainte de Java 1.2 intr-o clasa abstracta (Dictionary) care continea numai metode abstracte. Incepand cu Java 2 aceleasi metode (plus inca cateva) au fost grupate in interfata Map. Avantajul solutiei interfata in raport cu o clasa abstracta este evident atunci cand definim un dictionar realizat ca un vector de perechi cheie-valoare: o clasa derivata din clasa Vector ar putea mosteni metode utile de la superclasa, dar nu ar putea extinde si clasa abstracta Dictionary .
Interfetele si clasele abstracte nu trebuie opuse, iar uneori sunt folosite impreuna intr-un "framework" cum este cel al claselor colectie sau cel al claselor Swing (JFC): interfata defineste metodele ce ar trebui oferite de mai multe clase, iar clasa abstracta este o implementare partiala a interfetei, pentru a facilita definirea de noi clase prin extinderea clasei abstracte. In felul acesta se obtine o familie de clase deschisa pentru extinderi ulterioare cu clase compatibile, care nu trebuie definite insa de la zero. Un exemplu este interfata Set (sau Collection) si clasa AbstractSet (AbstractCollection) care permit definirea rapida de noi clase pentru multimi (altele decat HashSet si TreeSet), compatibile cu interfata dar care beneficiaza de metode mostenite de la clasa abstracta.
Compararea de obiecte in Java
In unele operatii cu vectori de obiecte (sortare, determinare maxim sau minim s.a.) este necesara compararea de obiecte (de acelasi tip). Functia de comparare depinde de tipul obiectelor comparate, dar poate fi o functie polimorfica, cu acelasi nume, tip si argumente dar cu definitii diferite. In plus, doua obiecte pot fi comparate dupa mai multe criterii (criteriile sunt variabile sau combinatii de variabile din aceste obiecte).
In Java, functia "compareTo" este destinata comparatiei dupa criteriul cel mai "natural" (cel mai frecvent iar uneori si unicul criteriu). Pot fi comparate cu metoda "compareTo" numai clasele care implementeaza interfata Comparable si deci care definesc metoda abstracta "compareTo":
public interface Comparable
Clasele care declara implementarea acestei interfete trebuie sa contina o definitie pentru metoda 'compareTo', cu argument de tip Object. Exemple de clase Java cu obiecte comparabile : Integer, Float, String, Date, BigDecimal s.a. Exemplu:
public class Byte extends Number implements Comparable
}
Metoda "compareTo" se poate aplica numai unor obiecte de tip Comparable si de aceea se face o conversie de la tipul general Object la subtipul Comparable. Exemplu:
// determinare maxim dintr-un vector de obiecte oarecare
public static Object max (Object [ ] a)
Functia "Arrays.sort" cu un argument foloseste implicit metoda "compareTo".
Putem considera ca interfata Comparable adauga metoda "compareTo" clasei Object si astfel creeaza o subclasa de obiecte comparabile.
Este posibil ca egalitatea de obiecte definita de metoda "compareTo" sa fie diferita de egalitatea definita de metoda "equals". De exemplu, clasa "Arc" produce obiecte de tip "arc de graf cu costuri":
class Arc implements Comparable
public boolean equals (Object obj)
public String toString ()
public int compareTo (Object obj)
}
Metoda "equals" este folosita la cautarea intr-o colectie neordonata ("contains", "add" pentru multimi, s.a.), iar metoda "compareTo" este folosita la cautarea intr-o colectie ordonata ("Collections.binarySearch"), ceea ce poate conduce la rezultate diferite pentru cele doua metode de cautare intr-o lista de obiecte "Arc".
Pentru comparare de obiecte dupa alte criterii decat cel "natural" s-a introdus o alta functie cu numele "compare", parte din interfata Comparator:
public interface Comparator
Interfata Comparator putea fi si o clasa abstracta cu o singura metoda, pentru ca este improbabil ca o clasa comparator sa mai mosteneasca si de la o alta clasa.
Functia "Arrays.sort" are si o forma cu doua argumente; al doilea argument este de tipul Comparator si precizeaza functia de comparare (alta decat "compareTo").
Functia care determina maximul dintr-un vector de obiecte poate fi scrisa si astfel:
public static Object max (Object a[ ], Comparator c)
Functia "max" cu doua argumente este mai generala si poate fi folosita pentru a ordona un acelasi vector dupa diferite criterii (dupa diverse proprietati). De exemplu, pentru ordonarea unui vector de siruri dupa lungimea sirurilor, vom defini urmatoarea clasa comparator:
class LengthComparator implements Comparator
}
. . . // ordonare dupa lungime
String [ ] a = ;
Arrays.sort( a, new LengthComparator());
Pentru ordonarea unei matrice de obiecte dupa valorile dintr-o coloana data putem defini o clasa comparator cu un constructor care primeste numarul coloanei:
class CompCol implements Comparator // constructor cu un argument
public int compare(Object o1, Object o2)
}
Exemplu de utilizare a acestui comparator in functia de sortare :
Object a[ ][ ] = , , };
for (int i=0;i<3;i++)
Interfete pentru filtre
Un filtru este un obiect care permite selectarea (sau respingerea) anumitor obiecte dintr-o colectie sau dintr-un vector. Un filtru poate contine o singura metoda cu rezultat boolean, care sa spuna daca obiectul primit ca argument este acceptat sau respins de filtru. In bibliotecile Java filtrele se folosesc in clasa File pentru listare selectiva de fisiere dintr-un director, dar pot fi folosite si in alte situatii.
Clasa File din pachetul "java.io" poate genera obiecte ce corespund unor fisiere sau directoare (cataloage). Ea este destinata operatiilor de listare sau prelucrare a fisierelor dintr-un director si nu contine functii de citire-scriere din/in fisiere.
Cel mai folosit constructor din clasa File primeste un argument de tip String ce reprezinta numele unui fisier de date sau unui fisier director. Cea mai folosita metoda a clasei File este metoda "list" care produce un vector de obiecte String, cu numele fisierelor din directorul specificat la construirea obiectului de tip File. Exemplu simplu de folosire a unui obiect File pentru afisarea continutului directorului curent:
import java.io.*;
class Dir
}
Metoda "listFiles" produce un vector de obiecte File ce corespund fisierelor din directorul pentru care se apeleaza metoda.
Metodele "list" si "listFiles" au si o varianta cu un argument de un tip interfata ce specifica filtrul aplicat fisierelor, pentru extragere selectiva de fisiere din director:
- metoda "list" cu argument de tip FilenameFilter
- metoda "listFiles" cu argument de tip FileFilter sau FilenameFilter.
Interfetele FileFilter si FilenameFilter contin o singura metoda, numita "accept":
public interface FilenameFilter
public interface FileFilter
Metoda "accept" va fi apelata de "list" sau "listFiles" pentru fiecare fisier din director si spune daca acel fisier este sau nu este acceptat in vectorul creat de functie.
Utilizatorul are sarcina de a defini o clasa care implementeaza una din aceste interfete si de a transmite o referinta la un obiect al acestei clase fie metodei "list" fie metodei "listFiles". Exemplu de listare selectiva cu masca a directorului curent:
// clasa pentru obiecte filtru
class FileTypeFilter implements FileFilter
public boolean accept (File f)
}
// Listare fisiere de un anumit tip
class Dir
}
Acelasi filtru dupa extensie fisier in varianta cu interfata FilenameFilter:
class DirFilter implements FilenameFilter
public boolean accept (File dir, String name)
}
Pentru filtrare dupa orice sablon (masca) putem proceda astfel:
a) Se defineste o clasa pentru lucrul cu siruri sablon :
class Pattern
public boolean match ( String str)
}
b) Se defineste o clasa filtru dupa orice masca, derivata din clasa "Pattern" si care implementeaza o interfata filtru din JDK :
class MaskFilter extends Pattern implements FileFilter
public boolean accept (File f)
}
c) Se foloseste un obiect din noua clasa intr-o aplicatie:
class Dir
}
Acest exemplu poate explica de ce FileFilter este o interfata si nu o clasa abstracta: clasa filtru poate prelua prin mostenire metoda "match" de la o alta clasa, pentru ca nu este obligata sa extinda clasa abstracta (posibila) FileFilter.
Functia 'compare' poarta numele de functie 'callback', deoarece este apelata de metode existente (Collections.sort, Collections.max, s.a) dar trebuie furnizata de aplicatia care foloseste una din aceste metode.
Metoda "sort" primeste adresa functiei "compare" (printr-un obiect dintr-o clasa care implementeaza interfata Comparator) ceea ce-i permite sa se refere 'inapoi' la functia de comparare. Practic, se transmite un pointer printr-un obiect ce contine o singura functie; adresa obiectului comparator este transmisa "sort", iar "sort" foloseste adresa continuta in obiectul comparator pentru a se referi inapoi la functia 'compare'. In limbajul C se transmite un pointer explicit la o functie.
Situatia mai poate fi schematizata si astfel: o functie A ('main', de ex.) apeleaza o functie B ('sort', de ex.), iar B apeleaza o functie X ('compare') dintr-un grup de functii posibile. Adresa functiei X este primita de B de la functia A. De fiecare data cand A apeleaza pe B ii transmite si adresa functiei X, care va fi apelata inapoi de B.
La scrierea functiei de sortare (Collections.sort) nu se cunostea exact definitia functiei de comparare (pentru ca pot fi folosite diverse functii de comparare), dar s-a putut preciza prototipul functiei de comparare, ca metoda abstracta inclusa intr-o interfata. Putem deci sa scriem o functie care apeleaza functii inca nedefinite, dar care respecta toate un prototip (tip rezultat, tip si numar de argumente). Exemplu:
// determinare maxim dintr-o enumerare de obiecte necunoscute
public static Object max (Enumeration enum, Comparator c)
return maxim;
}
Tehnica "callback" este folosita la scrierea unor clase de biblioteca, ale caror functii apeleaza functii din programele de aplicatii, scrise ulterior de utilizatorii pachetului. Ideea generala este ca o parte din algoritmul implementat de clasa de biblioteca depinde de specificul aplicatiei care foloseste acest algoritm. Un algoritm de sortare foloseste o functie de comparare, dar functia de comparare face parte din aplicatie, pentru ca ea compara date din aplicatie.
Functia "accept" din interfetele filtru este tot o functie "callback", apelata de metodele "list" si "listFiles" din clasa de biblioteca File, dar definita ca parte din aplicatie.
Un alt exemplu este un analizor lexical SAX, care recunoaste marcaje dintr-un fisier XML si apeleaza metode ce vor fi scrise de utilizatori pentru interpretarea acestor marcaje (dar care nu pot fi definite la scrierea analizorului lexical). Analizorul SAX impune aplicatiei sa foloseasca functii care respecta interfetele definite de analizor si apeleaza aceste functii "callback". In acest caz parserul SAX stie sa recunoasca atomi XML dar nu stie ce sa faca cu acesti atomi; in schimb aplicatia stie cum sa prelucreze atomii XML dar este scutita de analiza documentelor XML (realizata de parser).
Functiile "callback" sunt definite de cei care dezvolta aplicatii dar sunt apelate de catre functii din clase predefinite (de biblioteca).
Clase abstracte si interfete pentru operatii de I/E
Un flux de date Java ('input/output stream') este orice sursa de date (la intrare) sau orice destinatie (la iesire), cu suport neprecizat, vazuta ca sir de octeti. Operatiile elementare de citire si de scriere octet sunt aplicabile oricarui tip de flux si de aceea au fost definite doua clase abstracte: o sursa de date InputStream (Reader) si o destinatie de date OutputStream (Writer), care contin metodele abstracte "read" si "write". Clasele Reader si Writer sunt mai noi si sunt preferabile claselor mai vechi InputStream si OutputStream pentru ca se lucreaza cu caractere in loc de octeti (byte).
Ca suport concret al unui flux de date Java se considera urmatoarele variante: fisier disc, vector de octeti (in memorie), sir de caractere (in memorie), canal de comunicare intre fire de executie (in memorie). Pentru fiecare tip de flux exista implementari diferite ale metodelor abstracte "read" si "write" pentru citire/scriere de octeti.
Clasele abstracte InputStream si OutputStream contin si metode neabstracte pentru citire si scriere blocuri de octeti, care apeleaza metodele de citire/scriere octet, precum si alte metode care nu sunt definite dar nici nu sunt abstracte, transmise tuturor subclaselor. Exemplu:
public abstract class InputStream
public int available( ) throws IOException // alte metode
}
Clasele concrete de tip flux de citire sunt toate derivate din clasa InputStream, ceea ce se reflecta si in numele lor: FileInputStream, ByteInputStream, etc.
Metoda 'read()' este redefinita in fiecare din aceste clase si definitia ei depinde de tipul fluxului: pentru un flux fisier 'read' este o metoda 'nativa' (care nu este scrisa in Java si depinde de sistemul de operare gazda), pentru un flux vector de octeti metoda 'read' preia urmatorul octet din vector.
Clasa Reader difera de InputStream prin utilizarea tipului char in loc de byte:
public abstract class Reader // ptr a interzice instantierea clasei
public int read() throws IOException
public int read(char cbuf[ ]) throws IOException
abstract public int read(char cbuf[ ], int off, int len) throws IOException;
abstract public void close() throws IOException;
. . . // alte metode
}
Interfata DataInput reuneste metode pentru citire de date de tipuri primitive:
public interface DataInput
Clasa RandomAccessFile implementeaza ambele interfete si deci asigura un fisier in care se poate scrie sau din care se poate citi orice tip primitiv. In acest tip de fisiere (binarer) numerele se reprezinta in formatul lor intern (binar virgula fixa sau virgula mobila) si nu se face nici o conversie la citire sau la scriere din/in fisier.
Operatiile cu fisiere depind de sistemul de operare gazda, deci o parte din metodele claselor de I/E sunt metode 'native', dar numarul lor este mentinut la minim.
Un fragment din clasa RandomAccessFile arata astfel:
public class RandomAccessFile implements DataOutput, DataInput
Clasele DataInputStream si DataOutputStream implementeaza interfetele DataInput si respectiv DataOutput. Aceste clase simplifica crearea si exploatarea de fisiere text si de fisiere binare, ce contin date de un tip primitiv ( numere de diferite tipuri s.a. ). Exemplu de varianta modificata a clasei DataInputStream :
public class DataInputStream extends InputStream implements DataInput // constructor
public final byte readByte() throws IOException
public final short readShort() throws IOException
public String readLine ( ) // citeste o linie
public int readInt ( ) // citeste un numar intreg
public float readFloat ( ) // citeste un numar real
. . . // alte metode
}
Obiecte de tip DataInputStream nu pot fi create decat pe baza altor obiecte, care precizeaza suportul fizic al datelor. Clasa DataInputStream nu are constructor fara argumente si nici variabile care sa specifice suportul datelor.
Variabila publica "System.in" este de un subtip (anonim) al tipului InputStream si corespunde tastaturii ca flux de date. Pentru obiectul adresat de variabila "System.in" se poate folosi metoda "read" pentru citirea unui octet (caracter) dar nu se poate folosi o metoda de citire a unei linii.
Pentru a citi linii de la consola (terminate cu Enter), putem crea un obiect de tip DataInputStream , care suporta metoda "readLine". Exemplu:
// citire linie de la tastatura
public static void main (String arg[]) throws Exception
Politica de confidentialitate | Termeni si conditii de utilizare |
Vizualizari: 3864
Importanta:
Termeni si conditii de utilizare | Contact
© SCRIGROUP 2024 . All rights reserved