Декларация
на клас:
public class Person { public String name = "namePers"; public int age; public Person(){ name = "name1"; age = 21; } public void growUp(int years) { age += years; } } |
две променливи
- name и age; един метод – growUp() с параметър цяло число, без да връща резултат (void) един конструктор - метод без тип, с името на класа за инициализация на променливите |
Декларацията
на
променливите
и методите,
може да се
извърши в
произволен
ред
За да се
създадат
променливи (instances)
от клас Person:
Person p1, p2;
Всеки език има свои собствени средства за манипулиране на данните. В Java променливите от даден клас представляват псевдоними на обекти. Образно обектът може да се представи като телевизор а псевдонимът - като телеуправлението му. p1 и p2 от класа Person представляват променливи които са псевдоними на обекти от тип Person но обектите не са още създадени и променливите са "празни" - не сочат към реални обекти. За да могат да се използуват трябва динамично да се създадат обекти в специална част на паметта наречена "heap", като се използва ключовата дума new и конструктора на класа:
p1 = new Person();
p2 = new Person();
Пример :
public class Test {
public static void
main (String[] arg){
Person p1;
p1 = new Person(19);
Person p2 = new Person(34);
p2.growUp(4);
System.out.println("p1.age: "+p1.age);
System.out.println("p2.age: "+p2.age);
}
}
p2.age = 21;
p1.growUp();
Всеки обект притежава свое собствено копие от член-данните.
Както и член-данните, методите също са асоциирани с обекта. Но всеки обект не притежава свое собствено копие на методите. Всъщност съществува само една съвкупност от методи, но те работят с данните на даден обект.
За да се реализира този подход, всеки метод (с изключение на статичните методи) получава един имплицитен, скрит параметър, който представлява псевдоним на обекта, с който се работи и който се добавя автоматично всеки път, когато се използува някоя член-променлива. Така например инструкцията:
age++;
се реализира като:
(this.age)++;
Параметъра
this е
достъпен и
може да се
използва явно
в тялото на на
метода.
Инициализацията
на всеки
обект минава
през четири
етапа:
1)Резервиране
на
необходимата
памет в "heap" за
член-данните;
2)Всички
член-променливи
се
инициализират
със стойност 0;
3)Член
променливите
се променят
съгласно
стойностите
декларирани
в
декларацията
на класа;
4)Стартира
се
конструктора,
ако такъв е
създаден за
завършване
на
инициализацията
на класа
Присвояването между два обекта има за резултат два псевдонима, които сочат върху един и същи обект:
class Number {
int i;
}
public class Assignment {
public static void
main(String[]
args) {
Number n1 = new Number();
Number n2 = new Number();
n1.i = 9;
n2.i = 47;
System.out.println("1: n1.i: " + n1.i +", n2.i: " + n2.i);
n1 = n2;
System.out.println("2: n1.i: " + n1.i + ", n2.i: " + n2.i);
n1.i = 27;
System.out.println("3: n1.i: " + n1.i + ", n2.i: " + n2.i);
}
}
Резултат:
1: n1.i: 9, n2.i: 47
2: n1.i: 47, n2.i: 47
3: n1.i: 27, n2.i: 27
Релационните оператори '= =' et '!=' се отнасят не до обектите, а до техните псевдоними:
public class Equivalence {
public static void
main(String[]
args) {
Integer n1 = new Integer(47);
Integer n2 = new Integer(47);
System.out.println(n1 == n2); //сравнява
псевдонимите
- false
System.out.println(n1 != n2); //сравнява
псевдонимите
- true
}
}
За сравняване на самите обекти се използва методът equals() (за нови класове трябва да се предефинира, в противен случай отново сравнява псевдоними) !
System.out.println(n1.equals(n2)); //сравнява обектите - true
Класове - обвивки(wrapper classes)
На всеки примитивен тип съответства един клас -обвивка ("wrapper class"), който позволява създаването на обекти съответстващи на примитивния тип:
char c
=
'd';
Character
C = new Character(c);
или
Character C = new Character('d');
Java 1.1 добави
два класа за
аритметика с
висока
точност – BigInteger и
BigDecimal.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
пример | резултат |
import java.math.BigInteger; public class WrappedClassApp { static final int radix = 16; public static void main(String args[]) { Boolean b1 = new Boolean("TRUE"); Boolean b2 = new Boolean("FALSE"); System.out.println(b1.toString()+" or "+b2.toString()); for(int j=0;j<radix;++j) System.out.print(Character.forDigit(j,radix)); System.out.println(); System.out.print("Radix between "+ Character.MIN_RADIX); System.out.println(" and " + Character.MAX_RADIX); Integer i = new Integer(Integer.parseInt("ef",radix)); Long l = new Long(Long.parseLong("abcd",radix)); long m=l.longValue()*i.longValue(); System.out.println("radix=4: "+Long.toString(m,4)); System.out.println("radix=10: "+Long.toString(m,10)); System.out.println("radix=16: "+Long.toString(m,16)); System.out.println(Float.MIN_VALUE); System.out.println(Double.MAX_VALUE); BigInteger n=new
BigInteger("1000000000000"); |
true or false 0123456789abcdef Radix between 2 and 36 radix=4: 220012101203 radix=10: 10511459 radix=16: a06463 1.4E-45 1.7976931348623157E308 1000000000039 is probably prime. |
Във вътрешността на даден клас всички негови член-компоненти - данни и методи са достъпни непосредствено чрез тяхното име.
Достъпът
до член-данните
и методите от
методи извън
класа зависи
от
модификаторите
за достъп.
Модификаторите
дефинират
различни
нива на
достъп до
компонентите
на класа.
Задават се
преди типа на
компонентата.
Съществуват
четири
модификатори
за достъп:
по
подразбиране
(без
модификатор),
public,
protected,
private
по подразбиране (без модификатор): видим е само от класовете от същия пакет (директория):
public: компонентата е видима за всички без значение дали са вътре вътре или извън класа:
protected: компонентата е видима само за класовете от същия пакет и за производните му класове от други пакети.
private: компонентите са видими само за методите на класа (директен достъп).
Modifier |
class |
package |
subclass |
world |
public |
X |
X |
X |
X |
protected |
X |
X |
X |
|
no modifier |
X |
X |
|
|
private |
X |
|
|
|
Препоръка: Винаги се избира най-ограниченaта възможна видимост,
с изключение на константите.
class Exemple {
int m3=1;
static int m2=3;
static void func() {
Exemple e1 = new Exemple();
Exemple e2 = new Exemple();
int k = m2; // директен
достъп
int n = e1.m3; // достъп
чрез
псевдоним на
обект
…
}…
}
При декларирането на статична член компонента (static), за нея се заделя памет еднократно, независимо от броя на създаваните обекти.
Всички обекти от класа ползват един същи статичен член. Статичните функции не получават this като параметър, следователно те нямат директен достъп до не статичните компоненти на класа. За достъп до тези компоненти в този случай трябва да се използуват псевдонимите на обектите.
Модификатори final, synchronized и native
final: sспецифицира, че член-променливата има константна стойност (инициализирана в момента на декларацията) или че методът не може да бъде предефиниран в производен клас. С други думи final показва, че компонентът е дефиниран във своята окончателна версия.
synchronized: специфицира, че методът е "mono-thread". Синхронизираният метод допуска един единствен thread в даден момент.
native: специфицира, че методът е реализиран на en C и се намира в изпълним файл. Методът има само декларация, не и дефиниция:
native int Cprogramme();
Декларирането на масив се извършва чрез средни скоби:
int
nombre[
];
long
grille
[ ], jours [ ];
За разлика от C, масивите в езика Java предствляват обекти от клас масив. Тези декларации въвеждат само псевдоними на масиви и не резервират никаква памет за масива, следователно декларациите не позволяват въвеждането въвеждането на броя на елемнтите. За да се резервира място за масива трябва или да се използва оператора new:
int nombre[ ] = new int[10]; // масив от 10 цели числа
или да се присвои една последователност от елементи в момента на създаване на масива:
char vowel[ ] = {'a', 'e', 'i', 'o', 'u'}; // масив от 5 елемента
Размерът на всеки масив се съхранява в една public член-променлива с име length:
int longueur = vowel.length; //longueur = 5
Опитът да се достигне до несъществуващ елемент на масива генерира изключение ArrayIndexOutOfBoundsException от тип RuntimeException.
Методът arraycopy() от клас System се използва за копиране на определен брой елементи от един масив в друг:
System.arraycopy (objectsSource, positionSource, objectDestination, positionDestination, length)
Например за да се добави един елемент към масива vowel:
char vowel[
] = {'a', 'e', 'i', 'o', 'u'};
char tmp[
] = new char[vowel.length+1];
System.arraycopy(vowel,
0, tmp, 0, vowel.length);
tmp[vowel.lemgth]
= 'y';
vowel=tmp;
След операцията старият обект не е сочен от нито един псевдоним и ще бъде прибран от garbage collector.
За цялостно или частично обхождане на масива трябва да се
използва цикъл - например for
. Следващия пример
прави пълен обход на масив за показването му на конзолата.:
public class Array{ public static void main(String a[]){ int ar[] = {-3,4,-17,2,-1,8}; for(int i =0; i< ar.length;i++){ System.out.println(" "+ar[i]); } } } |
-3 4 -17 2 -1 8 |
Първият индекс на таблото 0,
последният - ar.length-1
.
Java 5.0 предлага нов цикъл for
,
който позволява лесно цялостно обхождане на всички елементи на дадена
колекция
от обекти
for (<type>
<variable_name> : <collection>)
{
// for body
}
public class Array{ public static void main(String a[]){ int ar[] = {-3,4,-17,2,-1,8}; for(int el :ar){ System.out.println(" "+el); } } } |
-3 4 -17 2 -1 8 |
Java решава въпроса с многомерни масиви чрез обекти, които представляват масиви от други масиви.
Синтаксисът е подобен на този на С:
public class Matrix {
public static void main(String arg[]){
int matrix[][] = new int[3][6];
for(int i
=0;i<matrix.length;i++ ){
// matrix.length - броят на
елементите (линиите) в масива
for (int
j=0;j<matrix[i].length;j++){
//matrix[i].length - броят на елементите (числата)
в линия i на масива
System.out.print("\t"+matrix[i][j]);
}
System.out.println();
}
}
}
public class Matrix {
public static void main(String arg[]){
int matrix[][] = new int[3][6];
for(int line[]:matrix ){
// for ... each
for (int k :
line){
//for … each
System.out.print("\t"+k);
}
System.out.println();
}
matrix[0][0]=3;
matrix[0][1]=5;
}
}
с инициализация
public class Matrix1 {
public static void main(String arg[]){
int matrix[][] =
{{1,2*3,7},{6,8,9}};
for(int line[]:matrix ){
for (int k :
line){
System.out.print("\t"+k);
}
System.out.println();
}
}
}
Възможно е създаването на двумерни масиви, редовете на които са с различна дължина:
public class Tabl {
public static void main(String arg[]){
int ex[][] = new int[3][ ];
ex[0] = new int [3];
ex[1] = new int[5];
ex[2] = new int[4];
for(int line[]:ex ){
for (int k :
line){
System.out.print("\t"+k);
}
System.out.println();
}
}
}
с инициализация
public class Tabl1 {
public static void main(String arg[]){
int ex[][] =
{{1,2,3},{4,5,6,7},{8,9}};
for(int line[]:ex ){
for (int k :
line){
System.out.print("\t"+k);
}
System.out.println();
}
}
}
Референциите към линиите могат да се променят при
изпълнение на програмата
public class Tab_ir {
public static void main(String arg[]){
int tab[][] = new int[3][2];
prt(tab);
tab[1] = new int [4];
prt(tab);
}
public static void prt(int tab[][]){
System.out.println("\ntab:");
for(int line[]:tab ){
for (int k :
line){
System.out.print("\t"+k);
}
System.out.println();
}
}
}
Пример
public class Array{ public static void main(String a[]){ int ar[][] = {{3,4},{17,2,1,8}}; for(int i =0; i< ar.length;i++){ for(int j = 0;j< ar[i].length; j++) System.out.print(" "+ar[i][j]); System.out.println(); } } } |
3 4 17 2 1 8 |
public class Array_s { public static void main(String a[]){ String ar[][] = {{"Koko","Kiko","Kako"},{"Simo", "Sima"}}; for(String[] line :ar){ for(String el:line) System.out.print(" "+el); System.out.println(); } } } |
Koko Kiko Kako Simo Sima |
Масив от обекти
class Birthday
public class Birthday {
private int day,month,year;
public Birthday(int d, int m, int y){
this.day = d;
this.month=m;
this.year = y;
}
public String toString(){
return
"("+day+","+month+","+year+")";
}
}
Birthday tab[] = new Birthday[2];
tab[0] = new Birthday(7, 7, 1980);
tab[1] = new Birthday(20, 12, 1984);
public class Tab {
public static void main(String arg[]){
Birthday bd[][]=new
Birthday[3][4];
init(bd);
for(Birthday line[]:bd ){
for (Birthday
k : line){
System.out.print("\t"+k);
}
System.out.println();
}
}
public static void init(Birthday tb[][]){
for(int i=0;i<tb.length;i++){
for(int j =0;
j<tb[i].length;j++){
tb[i][j]=new Birthday((int)(Math.random()*30+1),
(int)(Math.random()*12+1),
(int)(Math.random()*100+1930));
}
}
}
}
Подредена
последователност от обекти от един и същи тип като за разлика от масива
елементите могат да се увеличават или намаляват.
A Java List
collection can only hold objects.
List
е interface,
- не може да се създаде инстанциира директно . Два класа
ArrayList и LinkedList. Най-използвана ArrayList
.
Постоянно време за достъп и може да се използва System.arraycopy.
List<Object> listOfObjects = new
ArrayList<Object>();
Формален тип
<Object> - може да съхранява всякакви обекти
Може и да се ограничи типа на съхраняваните елементъ
class Person{
...
}
class Student extends Person{
...
}
List<Person> listOfPersons = new ArrayList<Person>();
Може да сухранява обекти само от Person и от производните му
класове - наприемер Student.
Използване
вмъкване в List
import
java.util.*; public class ListDemo { public static void main(String args[]) { // Create an array list ArrayList <String> al = new ArrayList <String>(); System.out.println("initial size:"+al.size()); // add elements to the array list al.add("C"); al.add("A"); al.add("E"); al.add("B"); al.add("D"); al.add("F"); System.out.println("the new size:"+al.size()); for(int i = 0; i <al.size(); i++){ System.out.println(al.get(i)); } String ex = al.remove (2); System.out.println("removing value:"+ex); System.out.println("size after remove:"+al.size()); for(int i = 0; i <al.size(); i++){ System.out.println(al.get(i)); } } } |
initial size:0 the new size:6 C A E B D F removing value:E size after remove:5 C A B D F |
Iterator
получен чрез List
's iterator
операция връща елементи в една
посока. Има и по-богат итератор - ListIterator, които позволява
обхождането в двете посоки, промяна на елементите и справка за текущата
позиция на итератора.import
java.util.*; public class IteratorDem { public static void main(String arg[]){ // Create an array list ArrayList <String> al = new ArrayList <String>(); // add elements to the array list al.add("C"); al.add("A"); System.out.println("ArrayList:"+al.get(0)+" "+al.get(1)); ListIterator<String> litr = al.listIterator(); // litr.set("new"); error- there is no element in the iterator System.out.println("before element "+litr.nextIndex()); System.out.println("after element "+litr.previousIndex()); System.out.println(litr.next()); System.out.println("before element "+litr.nextIndex()); System.out.println("after element "+litr.previousIndex()); litr.set("modified"); // modify the last element returned // by next() or previous() System.out.println("ArrayList:"+al.get(0)+" "+al.get(1)); } } |
ArrayList:C A before element 0 after element -1 C before element 1 after element 0 ArrayList:modified A |
В Java обработката на низове се извършва чрез един специфичен клас с име "String". Дори и литералите (константите) низове се третират като обекти от този клас.
Низовете от символи са непроменяеми. Един път създаден обект от тип низ не може да променя стойността си. Операциите, които позволяват да се замени някакъв символ или размерът на даден низ имат като резултат създаването на нов низ.
String string = "example: making string";
int lenght
= string.length();
String concatenation
= "Pierre" + " and Marie";
Обект от тип String може да се конструира от масив от от символи или от масив от десетични, осмични или шестандесетични числа:
class Test{ public static void main(String[] a){ char datac[ ] = {'p', 'a', 'r', 'c'}; String sc = new String(datac); char datad [ ] = {65,66,67}; String sd = new String(datad, 0,3); char datao [ ] = {065,066,067}; String so = new String(datao, 0,3); char datah [ ] = {0x65,0x66,0x67}; String sh = new String(datah, 0,3); System.out.println(" c:"+sc+ "\n 8:"+so+"\n 10:"+sd+"\n 16:"+sh); } } |
c:parc 8:567 10:ABC 16:efg |
Статичният метод String.valueOf() позволява преобразуването на различни типове под формата на ни от символи:
int i;
//...
String number
= String.valueOf(i);
Всички обекти в Java притежават един метод toString() наследен от класа Objet, който метод се използва от String.valueOf() за представяне под формата на низ.
String number1 = "" + i;
За това преобразуване се използват методите valueOf(), които се осигуряват от класовете обвивки(wrapper):
int i
=
Integer.valueOf("126").intValue();
//основа = 10
float f
=
Float.valueOf("14.75").floatValue();
//основа
= 10
int k =
Integer.parseInt("234");
//основа = 10
int j =
Integer.parseInt("ef",racine);
long l
= Long.parseLong("abcd",racine);
racine - lосновата на бройната система, която може да бъде между Character.MIN_RADIX и Character.MAX_RADIX (2 и 32).
Примери:
parseInt("0",
10)
-> 0
parseInt("473",
10)
-> 473
parseInt("-0",
10)
-> 0
parseInt("-FF",
16)
-> -255
parseInt("1100110",
2)
-> 102
parseInt("2147483647", 10) -> 2147483647
parseInt("-2147483648", 10) -> -2147483648
parseInt("2147483648", 10)
генерира NumberFormatException
parseInt("99",
8) генерира
NumberFormatException
parseInt("Kona",
10) генерира
NumberFormatException
parseInt("Kona",
27)
-> 411787
Релационните оператори сравняват само псевдонимите.
méthode equals(), equalsIgnoreCase(), compareTo().
String
one = "something";
String two = "something";
String three =
"SOMETHING";
if (one ==
two)
//невярно
if(one.equals(two))
//вярно
if(one.equals(three))
//невярно
if
(one.equalsIgnoreCase(three))
//вярно
if(one.compareTo(three)
> 0) //вярно
if(one.compareTo(two)
==0) //вярно
Пример:
public class
StringEx{ public static void main(String a[]){ String names [ ] = {"Rose","Anabelle", "Gerard", "Francoise", "Erik","Constance"},name; for(boolean ok = false; !ok; ){ ok=true; for(int i = 0; i < names.length-1; i++){ if(names[i].compareTo(names[i+1])>0){ name = names[i]; names[i] = names[i+1]; names[i+1] = name; ok = false; } } } for(int i = 0; i <names.length;i++) System.out.println (names[i] + " : "+names[i].length()+" lettres"); } } |
Anabelle : 8
lettres Constance : 9 lettres Erik : 4 lettres Francoise : 9 lettres Gerard : 6 lettres Rose : 4 lettres |
public char charAt(int index)
public boolean endsWith(String suffix)
public int indexOf(String str)
public int indexOf(String str,int fromIndex)
public int lastIndexOf(String str)
public String replace(char oldChar,char newChar)
public boolean startsWith(String prefix)
public String substring(int beginIndex)
public String substring(int beginIndex,int endIndex)
public String toUpperCase()
public String toLowerCase()
public String trim()
Клас StringTokenizer
Разделител - space, табулация
import java.util.StringTokenizer;
public class Test{
public static void main(String arg[]){
String s = "Java is a general-purpose, class-based, and object-oriented language";
StringTokenizer st = new StringTokenizer(s);
while(st.hasMoreTokens()){
String word = st.nextToken();
System.out.println(word);
}
}
}
Разделител символите '/', ':' и '.'
import java.util.StringTokenizer;
public class Test{
public static void main(String arg[]){
String s1 = "http://www.javasoft.com";
StringTokenizer st1 = new StringTokenizer(s1,"/:.");
while(st1.hasMoreTokens()){
String word = st1.nextToken();
System.out.println(word);
}
}
}
Клас StringBuffer
Обектите са променяеми.
Класът StringBuffer има класическата функционалност, но няма никаква връка с класа String и методите му често имат различни имена.
• промяна на символ на дадена позиция: setCharAt();
• достъп до символ : charAt();
• добавяне на низ в края : append() приема аргументи от примитивните типове и от тип String;
• вмъкване на низ на определена позиция : insert(),
• заместване на част от низ : replace(),
• преобразуване на StringBuffer към String : toString().
• ensureCapacity()
public class Test{
public static void main(String arg[]){
StringBuffer sBuf = new StringBuffer ("new ") ;
sBuf.append("test string buffer");
System.out.println (sBuf) ;
sBuf.setCharAt (3, 'J'); System.out.println (sBuf) ;
sBuf.append (" 2") ; System.out.println (sBuf) ;
sBuf.insert (3, "langage ") ; System.out.println (sBuf) ;
}
}