Table of Contents

Clase abstracte

Clasele abstracte sunt clase ce nu pot fi instantiate. Declarate unei clase abstracte se face cu modificatorul abstract. O clasa abstracta poate contine metode abstracte. O metoda abstracta este o metoda ce nu are implementare ci doar semnatura.

Nota: Se poate declara o clasa abstracta ce nu contine nici o metoda abstracta.

Metodele abstracte sunt folosite doar pentru a specifica faptul ca orice subclasa trebuie sa ofere implementare pentru toate metodele abstracte mostenite, sau, in caz contrar, sa fie declarata si aceasta ca abstracta.

abstract class GraphicObject {
                               int x, y;                               
                               void moveTo(int newX, int newY) { //metoda normala
                                 System.out.println("Move graphic object to position"+x+":"+y);
                               }
                               abstract void draw();                                         //metoda abstracta
}     
 
class Circle extends GraphicObject {
                               void draw() {
                                   System.out.println("Draw circle");
                               }
               }
 
class Rectangle extends GraphicObject {
                               void draw() {
                                   System.out.println("Draw rectangle");
                               }
}
 

Interfete

Interfetele duc conceptul de clasa abstracta cu un pas înainte prin eliminarea oricarei implementari a metodelor, punând în practica unul din conceptele POO de separare a modelului unui obiect (interfata) de implementarea sa. Asadar, o interfata poate fi privita ca un protocol de comunicare între obiecte. O interfata Java defineste un set de metode dar nu specifica nici o implementare pentru ele. O clasa care implementeaza o interfata trebuie obligatoriu sa specifice implementari pentru toate metodele interfetei, supunându-se asadar unui anumit comportament.

Definirea unei interfete se face prin intermediul cuvântului cheie interface.

Variabilele unei interfete sunt implicit publice chiar daca nu sunt declarate cu modificatorul public.

Variabilele unei interfete sunt implicit constante chiar daca nu sunt declarate cu modificatorii static si final.

Metodele unei interfete sunt implicit publice chiar daca nu sunt declarate cu modificatorul public.

interface Instrument {
                               //defineste o metoda fara implementare
                               void play();
               }
 
class Pian implements Instrument {
                               //clasa care implementeaza interfata
                               //trebuie obligatoriu sa implementeze metoda play
                               public void play() {
                                              System.out.println("Pian.play()");
                               }
               }
 
class Vioara implements Instrument {
                               //clasa care implementeaza interfata
                               //trebuie obligatoriu sa implementeze metoda play
                               public void play() {
                                              System.out.println("Vioara.play()");
                               }
               }
 
public class Muzica { //clasa principala
                               static void play(Instrument i) {
                                              //metoda statica care porneste un instrument generic
                                              //ce implementeaza interfata Instrument
                                              i.play();
                               }
                               static void playAll(Instrument[] e) {
                                              for(int i = 0; i < e.length; i++)
                                                             play(e[i]);
                               }
                               public static void main(String[] args) {
                                              Instrument[] orchestra = new Instrument[2];
                                              int i = 0;
                                              orchestra[i++] = new Pian();
                                              orchestra[i++] = new Vioara();
                                              playAll(orchestra);
                               }
               } 
 

O versiune modificata a programului de mai sus este prezentata in continuare. In aceasta versiune instrumentul poate porni un clip audio de tip .wav. Clipurile audio trebuie stocate in pachetul default pentru a putea fi gasite si rulate. Exemplul presupune existenta a doua clipuri audio piano1.wav si string1.wav in pachetul default.

import java.util.Random;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
 
class SoundControler {
 
    public static void playSound(final String note) {
        try {
 
            Clip clip = AudioSystem.getClip();
            AudioInputStream inputStream = AudioSystem.getAudioInputStream(
                    Muzica.class.getResourceAsStream(note));
 
            System.out.println("PLAY SOUND " + inputStream.getFrameLength());
            clip.open(inputStream);
            clip.start();
            while (!clip.isRunning()) {
                Thread.sleep(10);
            }
            while (clip.isRunning()) {
                Thread.sleep(10);
            }
            clip.close();
            System.out.println("Note played");
        } catch (Exception e) {
            e.printStackTrace();
            System.err.println(e.getMessage());
        }
 
    }
}
 
abstract class Instrument {
 
    //defineste o metoda fara implementare
    abstract void play();
}
 
class Pian extends Instrument {
    //clasa care implementeaza interfata
    //trebuie obligatoriu sa implementeze metoda play
 
    public void play() {
        System.out.println("Pian.play()");
        SoundControler.playSound("piano1.wav");
 
    }
}
 
class Vioara extends Instrument {
    //clasa care implementeaza interfata
    //trebuie obligatoriu sa implementeze metoda play
 
    public void play() {
        System.out.println("Vioara.play()");
        SoundControler.playSound("string1.wav");
    }
}
 
public class Muzica { //clasa principala
 
    static void play(Instrument i) {
        //metoda statica care porneste un instrument generic
        //ce implementeaza interfata Instrument
        i.play();
    }
 
    static void playAll(Instrument[] e) {
        for (int i = 0; i < e.length; i++) {
            play(e[i]);
        }
    }
 
 
    public static void main(String[] args) {
        Instrument[] orchestra = new Instrument[2];
        int i = 0;
        orchestra[i++] = new Pian();
        orchestra[i++] = new Vioara();
        playAll(orchestra);
 
    }
}

O clasa poate implementa oricâte interfete.

O clasa care implementeaza o interfata trebuie obligatoriu sa specifice cod pentru toate metodele interfetei. Din acest motiv, odata creata si folosita la implementarea unor clase, o interfata nu mai trebuie modificata , în sensul ca adaugarea unor metode noi sau schimbarea semnaturii metodelor existente va duce la erori în compilarea claselor care o implementeaza.

Modificarea unei interfete implica modificarea tuturor claselor care implementeaza acea interfata.

Implementarea unei interfete poate sa fie si o clasa abstracta.