Java >> Java tutorial >  >> Tag >> import

Hvad er vigtigheden af ​​abstrakt klasse, der strækker sig fra en anden abstrakt klasse

Det er helt fint, når en abstrakt klasse udvider en anden abstrakt klasse. Det betyder bare, at det detaljer adfærden for den nye klasse baseret om den gamle klasses adfærd. Men det er stadig ikke et komplet objekt, der skal bruges, fordi noget af dets adfærd er stadig ukendt.

I analogi med den virkelige verden.
Forestil dig, at du har en klasse Vehicle . Det kan være ethvert køretøj:bil, fly, bus, cykel, hvad som helst. Dette er din abstrakte klasse. Kan du bruge det nu? Nej, for du ved ikke, om du skal træde i pedalerne eller dreje på hjulet.
Nu opretter du endnu en klasse, f.eks. Car extends Vehicle . Kan du bruge det nu? Sandsynligvis, men du ved stadig ikke, om det er en lastbil eller en personbil. Men du ved, at den har et rat.
Og endelig, når du opretter en klasse mere, siger du MySuperPassengerCar extends Car du ved præcis, hvilket objekt dette er, hvordan det kan bruges, og hvilke metoder det har.


Abstrakt klasse definerer abstrakte metoder. Enhver klasse, der udvider en anden klasse, forbedrer superklassen ved at tilføje mere adfærd. Hvis børneklassen er abstrakt, kan den tilføje noget abstrakt adfærd.

Abstrakte metoder er som kontrakter. Den anden kode kan forbruge den eksisterende kode og kan afhænge af den. Betonklassen er forpligtet til at følge kontrakten ved at sørge for implementeringen.

Lad os se det med et eksempel nedenfor.

public abstract class SuperAbstract {
      public void nonAbstract(){
            // some code
      }
      public abstract void contract();
}

public abstract class SubAbstract extends SuperAbstract{
       public void additionalNonAbstract()
             // some code
        }
        public abstract void additionalContract();
 }

public class Concrete extends SubAbstract{
       public void contract(){
             // implementation
       }
       public void additionalContract(){
               //implementation
       }
}

// although below is allowed and sometimes when we use an external library then this is one of the way but still this is not a good practice. 
// dependencies should be on abstractions only and not on concrete implementation
public abstract class AnotherAbstract extends Concrete{
       public void someMethod(){
             //some code
       }
       public abstract void oneMoreContract();
}

public class ConcreteA extends AnotherAbstract{
        public void oneMoreContract(){
               //some implementation
        }
}

Bemærk nu, at vi i alt har defineret 3 kontrakter og ConcreteA har alle implementeringer. Bemærk også, at som Concrete leverer implementeringer til metoderne contract og additionalContract derfor er disse implementeringer arvet af ConcreteA

Forbrugerkode kan nemt afhænge af abstraktionen. Lad os se det i brugerkode (forbrugerkode)

  public class Consumer{
      public void m1(SuperAbstract c)
             c.contract();
             c.nonAbstract();
     }
     public void m2(AnotherAbstract c){
          c.contract();
          c.nonAbstract();
          c.oneMoreContract();
          c.additionalContract();
    }
 }

Lad os nu se ledningskoden, der giver afhængighederne

 public class Main{
       public static void main(String[] args){
            Consumer c = new Consumer();
             c.m1(new Concrete());
             c.m1(new ConcreteA());
             c.m2(new ConcreteA());
     }
}

Java tag