Презареждане на методите

Презареждане на методите (overloading) - възможността да се дефинират повече методи в даден клас, които имат едно и също име, но се различават по аргументите си. При извикването компилаторът избира подходящият метод в зависимост от аргументите.

Презареждането на методите представлява мощно и гъвкаво средство. То представлява форма на параметричен полиморфизъм. Идеята е да се създадат методи, които изглеждат като един метод с различни аргументи.

public class Person {
    String name;
    int age;
    Person(){
        name = "Penda";
        age = 20;
    }
    Person(String name){
        this.name=name;
        age=20;
    }
    Person(int age){
        name="Pijo";
        this.age=age;
    }
    Person(String name, int age){
        this.name=name;
        this.age=age;
    }
    public static void main(String[] arg){
        Person ps[]=new Person[4];
        ps[0]= new Person();
        ps[1]= new Person(22);
        ps[2]= new Person("Kami");
        ps[3]= new Person("Simo",26);
        main(ps);
    }
    public static void main(Person[] ps){
        for(int i=0;i<ps.length;i++){
            System.out.print(ps[i].name);
            System.out.println("   age: "+ps[i].age);
        }
    }
    

}
Penda   age: 20
Pijo   age: 22
Kami   age: 20
Simo   age: 26

 

 

Разрушаване на обекти

Java използва техниката на боклуко-събирач (garbage - collector) за премахване на ненужните обекти. Боклукосъбирача се включва в определен момент от работата на програмата, работи в ниско-приоритетна нишка (thread) и наблюдава обектите. Когато всички псевдоними на даден обект изчезнат, обекът престава да е достъпен и боклуко-събирача разрушава обекта и изпраща паметта му в зоната на свободното пространство.

Преди разрушаването му за обекта се извиква метода finalize() (наследен от класа Object или предефиниран в класа). Боклуко-събирача се занимава само с паметта за обектите но не и с отворените файлове или мрежовите връзки. Важно е да се отбележи, че няма гаранция кога и дали въобще обекта ще бъде разрушен от боклуко-събирача, следователно не трябва да се разчита на метода finalize(), ако някое от горните действия трябва задължително да бъде извършено.

Едно Java приложение може да стартира експлицитно боклуко-събирача, чрез извикването на метода "System.gc()", последван от метода "System.runFinalisation()". Може също така принудително да се стартира боклуко-събирача след края на работата на приложението, чрез извикване на метода  "System.runFinalisersOnExit(true)". Метода обаче е опасен в условията на многонишково изпълнение, предизвиква "deprecation warning" и по подразбиране е изключен.

В следващия пример метода  finalize()  се използва за наблюдение разрушаването на обектите:

 

//: Garbage.java
// Демонстрация на боклуко-събирача и метода finalize()
class Chair {
        static boolean gcrun = false;
        static boolean f = false;
        static int created = 0;
        static int finalized = 0;
        int i;
        Chair() {
                i = ++created;
                if(created == 47)
                System.out.println("Created 47");
        }
        protected void finalize() {
                if(!gcrun) {
                        gcrun = true;
                        System.out.println("Beginning to finalize after " + created
                            + " Chairs have been created");
                }
                if(i == 47) {
                        System.out.println("Finalizing Chair #47, " +
                            "Setting flag to stop Chair creation");
                        f = true;
                }
                finalized++;
                if(finalized >= created)
                        System.out.println("All " + finalized + " finalized");
                }
        }
        public class Garbage {
                public static void main(String[] args) {
                        if(args.length == 0) {
                                System.err.println("Usage: \n" +
                                    "java Garbage before\n or:\n" +
                                    "java Garbage after");
                        return;
                }
                while(!Chair.f) {
                        new Chair();
                        new String("To take up space");
                }
                System.out.println("After all Chairs have been created:\n" +
                    "total created = " + Chair.created +
                    ", total finalized = " + Chair.finalized);
                if(args[0].equals("before")) {
                        System.out.println("gc():");
                        System.gc();
                        System.out.println("runFinalization():");
                        System.runFinalization();
                }
                System.out.println("bye!");
                if(args[0].equals("after"))
                        System.runFinalizersOnExit(true);
        }
}

java Garbage
Usage: 
java Garbage before
or:
java Garbage after

java Garbage before
Created 47
Beginning to finalize after 2929 Chairs have been created
Finalizing Chair #47, Setting flag to stop Chair creation
All 2929 finalized
After all Chairs have been created:
total created = 2929, total finalized = 2929
gc():
runFinalization():
bye!

java Garbage after
Created 47
Beginning to finalize after 2929 Chairs have been created
Finalizing Chair #47, Setting flag to stop Chair creation
All 2929 finalized
After all Chairs have been created:
total created = 2929, total finalized = 2929
bye!

Пакети и компилационни единици

В Java най-малката компилационна единица представлява един клас, който се съхранява във файл носещ името на класа с разширение .java. Компилаторът разчита на имената на файловете за да намери и генерира връзките между класовете. Възможно е да се въведат няколко класа в един файл, но само един от тези файлове трябва да бъде деклариран като public и той определя името на файла. След компилацията всеки файл се съхранява в отделен файл, който носи името на класа и има разширение  .class.

Над класовете има един втори слой, който групира класовете във функционална единица, която се нарича пакет (package). Пакетите формират организацията на второ ниво. Всеки пакет се съхранява в своя собствена директория.

Системните класове и интерфейси на Java платформата са групирани в пакети основно по предлаганите функции - основните класове се намират в java.lang, класовете за вход-изход - в java.io и т.н.т. Групирането на класовете в пакети има следните предимства:

 За да се създаде пакет трябва да се постави поне един клас или интерфейс в него и да се постави в отделна директория. Името на пакета трябва да съответства на името на директорията. Името на пакета се задава чрез специална инструкция в началото на файла (класа) например:

    package mypackage;

Ако не се използва тази инструкция се създава "подразбиращ" се пакет (default package), който няма име. Най-общо казано пакетите без име се използуват само за много малки приложения, в процес на разработка.

 Интерпретаторът и компилаторът на Java използват една променлива от обкръжението - CLASSPATH при търсене на инсталираните файлове. Променливата CLASSPATH съдържа пътища, където да бъдат търсени приложните пакети с класовете. Без да се използва тази променлива могат да се ползват само системните пакети и файловете разположени в текущата директория.

Java може да манипулира архиви, компресирани във формат ZIP. Отделните пътища в CLASSPATH се разделят по приетия в оперционната система начин - двоеточие  в UNIX:

        CLASSPATH=/home/temp/mypackages.zip:/home/momtchev/Java/:.

или точка и запетая в  Windows:

        CLASSPATH=C:\temp\mypackages.zip;D:\users\momtchev\;.

В горните два случая са специфицирани три директории. Компилаторът и интерпретаторът на  Java след проверка на системните директории търси класовете последователно на трите места.

Класът Math

Класът Math осигурява множество от методи - аритметични, тригонометрични, експоненциални, логаритмични, случайни числа и методи за преобразуване:
 
пример резултат
public class MathApp {
   public static void main(String args[]) {
         System.out.println(Math.E);
         System.out.println(Math.PI);
         System.out.println(Math.abs(-1234));
         System.out.println(Math.cos(Math.PI/4));
         System.out.println(Math.sin(Math.PI/2));
         System.out.println(Math.tan(Math.PI/4));
         System.out.println(Math.log(1));
         System.out.println(Math.pow(3.1,2.2));   //степен
         for(int i=0;i<3;++i) 
               System.out.print(Math.random()+" ");  //в  [0, 1.0)
         System.out.println();
   }
}
2.718281828459045
3.141592653589793
1234
0.7071067811865476
1.0
0.9999999999999999
0.0
12.050240825798763

0.797925915204636 
0.43948005533686785 
0.18012940121952126

Трябва да се отбележи, че съществува клас с име Random, които осигурява повече възможности за генериране на псевдослучайни числа. За целта, трябва да се  използва пакета "java.util.Random":

        import java.util.Random;