Java - Nasljeđivanje


Nasljeđivanje je jedna od ključnih karakteristika OOP-a (Objektno orijentirano programiranje) koja nam omogućuje definisanje nove klase iz postojeće klase. Pogledajmo primjer:

class Animal
{
    // eat() metoda
    // sleep() metoda
}
class Dog extends Animal
{
    // bark() metoda
}

U Javi koristimo ključnu riječ extends za nasljeđivanje iz klase. Ovdje smo nasljedili klasu Dog iz klase Animal. Animal je superklasa (superclass) (roditeljska klasa ili osnovna klasa), a Dog je podkalsa (podređena klasa ili izvedena klasa). Podklasa nasljeđuje polja i metode superklase.



Nasljeđivanje je veza. Nasljeđivanje koristimo samo ako je između dvije klase prisutan odnos is-a. Evo nekoliko primjera:

  • Automobil je vozilo.
  • Narandža je voće.
  • Hirurg je doktor.
  • Pas je životinja.

Primjer 1: Nasljeđivanje u Javi

class Animal {

   public void eat() {
      System.out.println("Ja mogu jesti");
   }

   public void sleep() {
      System.out.println("Ja mogu spavati");
   }
}

class Dog extends Animal {
   public void bark() {
      System.out.println("Ja mogu lajati");
   }
}

class Main {
   public static void main(String[] args) {

      Dog dog1 = new Dog();

      dog1.eat();
      dog1.sleep();

      dog1.bark();
   }
}

Ovdje smo nasljedili podklasu Dog od superklase Animal. Klasa Dog nasljeđuje metode eat() i sleep() iz klase Animal. Dakle, objekti klase Dog mogu pristupiti članovima klase Dog i klase Animal.




Zaštićena (protected) ključna riječ

O modifikatorima privatnog (private) i javnog (public) pristupa naučili smo u prethodnim lekcijama.

  • Privatnim (Private) - članovima može se pristupiti samo unutar klase.
  • Javnim (Public) - članovima se može pristupiti s bilo kog mjesta.

Takođe možete dodijeliti zaštićene metode i polja. Zaštićeni članovi su dostupni:

  • iz klase (class)
  • u okviru svojih podklasa
  • unutar istog paketa

Evo sažetka odakle se može pristupiti modifikatorima pristupa.

Klasa (Class) Paket (Package) Podklasa (subclass) World
public Yes Yes Yes Yes
private Yes No No No
protected Yes Yes Yes No

Primjer 2: Zaštićena (protected) ključna riječ

class Animal {
   protected String type;
   private String color;

   public void eat() {
      System.out.println("Ja mogu jesti");
   }

   public void sleep() {
      System.out.println("Ja mogu spavati");
   }

   public String getColor(){
      return color;
   }

   public void setColor(String col){
      color = col;
   }
}

class Dog extends Animal {
   public void displayInfo(String c){
      System.out.println("Ja sam " + type);
      System.out.println("Moja boja je " + c);
   }
   public void bark() {
      System.out.println("Ja mogu lajati");
   }
}

class Main {
   public static void main(String[] args) {

      Dog dog1 = new Dog();
      dog1.eat();
      dog1.sleep();
      dog1.bark();
 
      dog1.type = "sisar";
      dog1.setColor("crna");
      dog1.displayInfo(dog1.getColor()); 
   }
}

Ovdje je polje type unutar klase Animal zaštićeno. Ovom polju smo pristupili iz klase Main koristeći:

dog1.type = "sisar";

Moguće je, jer su klase Animal i Main u istom paketu (ista datoteka).



Nadjačavanje Java metode

Iz gornjih primjera znamo da objekti podklase takođe mogu pristupiti metodama svoje superklase. Što se događa ako je ista metoda definisana i u superklasi i u podklasi? Pa, u tom slučaju, metoda u podklasi nadjačava metodu u superklasi. Pogledajmo primjer:


Primjer 3: Primjer nadjačavanja metode

class Animal {
   protected String type = "životinja";

   public void eat() {
      System.out.println("Ja mogu jesti");
   }

   public void sleep() {
      System.out.println("Ja mogu spavati");
   }
}

class Dog extends Animal {
  
   @Override
   public void eat() {
      System.out.println("Ja jedem pseću hranu");
   }

   public void bark() {
      System.out.println("Ja mogu lajati");
   }
}

class Main {
   public static void main(String[] args) {

      Dog dog1 = new Dog();
      dog1.eat();
      dog1.sleep();
      dog1.bark();
   }
}

Ovdje je eat() prisutan i u superklasi Animal i u podklasi Dog. Stvorili smo objekt dog1 iz podklase Dog. Kada zovemo eat() pomoću objekta dog1, poziva se metoda unutar klase dog, a ne poziva se ista metoda superklase. To se naziva nadjačavanje metode. U gore navedenom programu koristili smo @Overrideannotation da bismo kompajleru rekli da nadjačavamo metodu. Međutim, nije obavezno. O zamjeni metoda detaljno ćemo naučiti u sljedećoj lekciji. Ako moramo pozvati metodu eat() Animal iz njegovih podklasa, koristimo ključnu riječ super.


Primjer 4: Ključna riječ super

class Animal {
   public Animal() {
     System.out.println("Ja sam životinja");
   }

   public void eat() {
     System.out.println("Ja mogu jesti");
   }
}

class Dog extends Animal {
   public Dog(){
      super();
      System.out.println("Ja sam pas");
   }

  @Override
  public void eat() {
     super.eat();
     System.out.println("Ja jedem pseću hranu");
  }

   public void bark() {
      System.out.println("Ja mogu lajati");
   }
}

class Main {
   public static void main(String[] args) {
      Dog dog1 = new Dog();

      dog1.eat();
      dog1.bark();
   }
}

Ovdje smo koristili ključnu riječ super za pozivanje konstruktora pomoću metode super(). Takođe, pozvali smo metodu eat() superklase Animal koristeći super.eat().