Diferență între revizuiri ale paginii „Noțiuni avansate de programare obiect-orientată”

De la WikiLabs
Jump to navigationJump to search
Linia 142: Linia 142:
  
 
=== Polimorfism ===
 
=== Polimorfism ===
 +
 +
Considerând exemplul de mai sus, polimorfismul se referă la faptul că un obiect de tip ''Truck'' este în același și un obiect de tip ''Automobile'', un obiect de tip ''Vehicle'' și un ''Object''. Astfel sunt permise următoarele construcții:
 +
 +
<syntaxhighlight lang="java">
 +
public class MainClass{
 +
   
 +
public static void main(String _args[]){
 +
    // this is a reference variable of type Truck, referring
 +
    // an object of type Truck
 +
    Truck _firstTruck = new Truck("Volvo", "Generic", 8000, 20);
 +
 +
    // this is a reference variable of type Vehicle, referring
 +
    // an object of type Vehicle
 +
    Vehicle _firstVehicle = new Vehicle("Bicycle", "red");
 +
 +
    // since a Truck is also a Vehicle, we can have
 +
    // a reference variable of type Vehicle, referring
 +
    // an object of type Truck
 +
    Vehicle _secondVehicle = new Truck("Scania", "unknown", 7000, 30);
 +
 +
    //better yet, we can do this:
 +
    Vehicle _vehicles[] = new Vehicle[3];
 +
    _vehicles[0] = _firstTruck; // a truck is a vehicle
 +
    _vehicles[1] = _firstVehicle;
 +
    _vehicles[2] = _secondVehicle;
 +
 +
    for(int i=0; i<_vehicles.length; i++){
 +
        _vehicles.increaseSpeedBy(1.1f);
 +
    }
 +
 +
    // this will NOT work, since an Object is not
 +
    // a Vehicle and will generate a compile time error
 +
    _vehicles[0] = new Object();
 +
 +
}
 +
 +
}
 +
</syntaxhighlight>
 +
 +
Același lucru se poate realiza cu ajutorul interfețelor:
 +
 +
<syntaxhighlight lang="java">
 +
public interface Colored{
 +
    public String getColor();
 +
}
 +
</syntaxhighlight>
 +
 +
 +
<syntaxhighlight lang="java">
 +
// all objects of type Vehicle and up are not Colored
 +
public class Vehicle implements Colored{
 +
 +
//... same class content as before
 +
 +
}
 +
</syntaxhighlight>
 +
 +
 +
<syntaxhighlight lang="java">
 +
public class MainClass{
 +
   
 +
public static void main(String _args[]){
 +
    Colored _coloredItems[] = new Colored[3];
 +
    _coloredItems[0] = new Vehicle("Submarine", yellow);
 +
    _coloredItems[1] = new Carriage("brown", 6);   
 +
    _coloredItems[2] = new Automobile("Dacia", "Sandero", "Yellow", 1600);   
 +
 +
    for(int i=0; i<_coloredItems.length; i++){
 +
        System.out.println("Color of item " + i + " is " + _coloredItems[i].getColor());
 +
    }
 +
 +
    // this will fail with a compile time error
 +
    // since class Object does not implement
 +
    // interface Colored
 +
    Colored _coloredItem = new Object();
 +
}
 +
 +
}
 +
</syntaxhighlight>
  
 
== Încapsulare ==
 
== Încapsulare ==

Versiunea de la data 21 august 2012 09:51

Ierarhii de clase

Una din cele mai utile facilități ale unui limbaj orientat obiect, din punct de vedere al ușurinței de a citi și menține o aplicație, este aceea de a crea o ierarhie de clase. Particularitățile unei ierarhii de clase sunt:

  • o clasă poate extinde o altă clasă, moștenind din funcționalitatea acesteia din urmă;
  • un obiect instanțiat dintr-o clasă B care este extinsă dintr-o clasă A, este în același timp de tip B dar și de tip A (polimorfism).

Moștenire

Conceptul de moștenire este util atunci când programatorul are nevoie de o anumită funcționalitate care parțial este deja implementată într-o alta clasă. Astfel, acele bucăți de program nu mai trebuie reimplementate și testate ci doar completate.

Putem lua ca exemplu o clasă Vehicle:

public class Vehicle{

    public static final float MAX_VEHICLE_SPEED = 300;

    protected float currentSpeed;
    private String name;
    private String color;

public Vehicle(String _name, String _color){
    name = _name;
    color = _color;
}

public void increaseSpeedBy(float _speed){
    if(currentSpeed + _speed <= MAX_VEHICLE_SPEED){
        currentSpeed += _speed;
    }
}

public String getName(){
    return name;
}

public String getColor(){
    return color;
}

public float getCurrentSpeed(){
    return currentSpeed;
}

}

... și trei clase extinse: Carriage

public class Carriage extends Vehicle{

    public static final float MAX_VEHICLE_SPEED = 40;

    private int horseCount;

public Carriage(String _color, int _horseCount){
    super("Carriage", _color);
    horseCount = _horseCount;
}

public int getHorseCount(){
    return horseCount();
}

}

... Automobile:

public class Automobile extends Vehicle{

    public static final float MAX_VEHICLE_SPEED = 250;

    private int cylinders;
    private String make;
    private String model; 

public Autombile(String _make, String _model, String _color, int _cylinders){
    super("Automobile", _color);
    make = _make;
    model = _model;
    cylinders = _cylinders;
}

public int getCylinders(){
    return cylinders;
}

public String getMake(){
    return make;
}

public String getModel(){
    return model;
}

}

... și Truck:

public class Truck extends Automobile{

    public static final float MAX_VEHICLE_SPEED = 150;
    private int maxCargo;

public Truck(String _make, String _model, String _color, int _cylinders, int _maxCargo){
    super(_make, _model, _color, _cylinders);
    maxCargo = _maxCargo;
}

public int getMaxCargo(){
    return maxCargo;
}

public String getName(){
    return "Truck";
}

}

Schema bloc a ierarhiei este prezentată mai jos:


Ierarhia claselor implementate mai sus

Regulă: O clasă Java extinde exact o singură altă clasă (dacă nu este specificată, aceasta este clasa Object).


Regulă: O clasă moștenește de la superclasă doar metodele și câmpurile non-statice, declarate public, protejate sau implicite. O clasă nu moștenește membrii privați și statici, și constructorii.

Există două noțiuni foarte importante legate de extinderea claselor: suprascriere și ascundere (overriding & hiding):

  • suprascrierea unei metode se referă la definirea în clasa extinsă a unei metode ne-statice cu aceeași semnătură (prototip) cu o metodă ne-statică din clasa de bază;
  • ascunderea unei metode se referă la definirea în clasa extinsă a unei metode statice cu aceeași semnătură (prototip) cu o metodă statică din clasa de bază.
Regulă: Întotdeauna când o metodă este apelată folosind o referință la un obiect, metoda apelată este cea care suprascrie ultima, indiferent de tipul variabilei referință (polimorfism).

Mai multe despre moștenire și suprascriere/ ascundere pe pagina oficială Oracle:

Polimorfism

Considerând exemplul de mai sus, polimorfismul se referă la faptul că un obiect de tip Truck este în același și un obiect de tip Automobile, un obiect de tip Vehicle și un Object. Astfel sunt permise următoarele construcții:

public class MainClass{
    
public static void main(String _args[]){
    // this is a reference variable of type Truck, referring
    // an object of type Truck
    Truck _firstTruck = new Truck("Volvo", "Generic", 8000, 20); 

    // this is a reference variable of type Vehicle, referring
    // an object of type Vehicle
    Vehicle _firstVehicle = new Vehicle("Bicycle", "red");

    // since a Truck is also a Vehicle, we can have 
    // a reference variable of type Vehicle, referring
    // an object of type Truck
    Vehicle _secondVehicle = new Truck("Scania", "unknown", 7000, 30);

    //better yet, we can do this:
    Vehicle _vehicles[] = new Vehicle[3];
    _vehicles[0] = _firstTruck; // a truck is a vehicle
    _vehicles[1] = _firstVehicle;
    _vehicles[2] = _secondVehicle;

    for(int i=0; i<_vehicles.length; i++){
        _vehicles.increaseSpeedBy(1.1f);
    }

    // this will NOT work, since an Object is not 
    // a Vehicle and will generate a compile time error
    _vehicles[0] = new Object();

}

}

Același lucru se poate realiza cu ajutorul interfețelor:

public interface Colored{
    public String getColor();
}


// all objects of type Vehicle and up are not Colored
public class Vehicle implements Colored{

//... same class content as before

}


public class MainClass{
    
public static void main(String _args[]){
    Colored _coloredItems[] = new Colored[3];
    _coloredItems[0] = new Vehicle("Submarine", yellow);
    _coloredItems[1] = new Carriage("brown", 6);    
    _coloredItems[2] = new Automobile("Dacia", "Sandero", "Yellow", 1600);    

    for(int i=0; i<_coloredItems.length; i++){
        System.out.println("Color of item " + i + " is " + _coloredItems[i].getColor());
    }

    // this will fail with a compile time error
    // since class Object does not implement 
    // interface Colored
    Colored _coloredItem = new Object();
}

}

Încapsulare