A felfelé hívás az objektumorientált programozás antimintája. Ebben a szülő osztály egy metódusát a gyermek osztálynak felül kell definiálnia, azonban annak meg kell hívnia azt a metódust, amit éppen felüldefiniál.

A felülírt metódus nem teljes, és a gyermek osztálynak egy előírt módon ki kell bővítenie a funkcionalitását. Azonban nem biztos, hogy kikényszeríthető a szülő osztály metódusának előfeltétele a gyermek osztályban felüldefiniálás közben. Emiatt antimintának tekintik, és a sablon metódust javasolják helyette.

Leírás szerkesztés

Az objektumorientált programozásban egy osztály örökölheti szülője tulajdonságait és viselkedését. A metódusokat felül is írhatja, ezzel saját megvalósítást adva. Ez vagy teljesen helyettesíti a szülő osztály metódusát, vagy meghívja azt is. A legtöbb programozási nyelvben ezt explicit kell megtenni.

A felfelé hívásban egy interfész vagy keretrendszer megköveteli, hogy a felhasználó származtasson egy osztályból, írja felül az adott metódust, és hívja meg a szülő osztály metódusát.[1]

 

Erre azért van szükség, mivel a szülő metódus végzi el az inicializálást, vagy a gyermek osztály csak kibővíti a szülő funkcionalitását.

Meg kell jegyeznünk, hogy a kötelezővé tétel az antiminta. Sok példa van valós kódban, amikor a gyermek osztály csak ki akarja bővíteni a szülő működését. Ha még akkor is meg kell hívnia a szülő metódusát, ha azt teljesen egy új viselkedéssel akarja helyettesíteni, akkor antimintához jutunk.

Ehelyett javasolt a sablon metódus, amikor a szülő osztályban egy metódus bizonyos pontokon meghív tisztán absztrakt metódusokat, amelyek megvalósítását a gyermek osztályokra hagyja.[1]

 

Különböző nyelvi megoldások szerkesztés

A felfelé hívás antimintája azért van jelen, mivel csak kevés nyelvben van olyan lehetőség, ami szerződésben biztosítja, hogy a szülő metódusa meghívódjon. A BETA radikálisan bevezette ezt a lehetőséget. Konstruktorokra több nyelv, a Java és a C++ is használja, a gyermek osztály konstruktorának először meg kell hívnia a szülő konstruktorát az örökölt tagok inicializálására, majd utána csinálhat bármit is.

Az antiminta megoldható az aspektusorientált programozásból eredő before és after, néha around is metódusok definiálásával, ahogy azt a Common Lisp CLOS rendszere is felajánlja. A gyermek osztály ezeket külön felülírhatja, és a rendszer garantálja, hogy ezek végrehajtódnak a szülő metódus előtt, után, vagy körül.

Példák szerkesztés

Legyen egy osztály, ami egy videokölcsönző készletéről készít jelentést! Minden egyes kölcsönzőnek más az éppen elérhető készlete, de a jelentést készítő algoritmus ugyanaz. A felfelé hívást használó keretrendszer a következő absztrakt osztályt nyújtja C Sharp nyelven:

abstract class ReportGenerator {
    public virtual Report CreateReport() {
        // Generate the general report object
        // ...
        return new Report(...);
    }
}

A felhasználónak ehhez hasonlóan kell megvalósítani a gyermek osztályt:

class ConcreteReportGenerator : ReportGenerator {
    public override Report CreateReport() {
        // Tabulate data in the store-specific way
        // ...

        // Design of this class requires the parent CreateReport() function to be called at the 
        // end of the overridden function. But note this line could easily be left out, or the
        // returned report could be further modified after the call, violating the class design
        // and possibly also the company-wide report format.
        return base.CreateReport();
    }
}

Sablon metódussal az absztrakt osztály:

abstract class ReportGenerator {
    public Report CreateReport() {
        Tabulate();

        // Generate the general report object
        // ...
        return new Report(...);
    }
 
    protected abstract void Tabulate();
}

A gyermek osztály:

class ConcreteReportGenerator : ReportGenerator {
    protected override void Tabulate() {
        // Tabulate data in the store-specific way
        // ...
    }
}

Jegyzetek szerkesztés

Fordítás szerkesztés

Ez a szócikk részben vagy egészben a Call super című angol Wikipédia-szócikk fordításán alapul. Az eredeti cikk szerkesztőit annak laptörténete sorolja fel. Ez a jelzés csupán a megfogalmazás eredetét és a szerzői jogokat jelzi, nem szolgál a cikkben szereplő információk forrásmegjelöléseként.