Visualizzazione post con etichetta Object Oriented. Mostra tutti i post
Visualizzazione post con etichetta Object Oriented. Mostra tutti i post
mercoledì 18 marzo 2015

Concetti OO per sviluppatori 4GL. Esempi istanza classe

L'esempio di seguito mostra come istanziare una classe ed usufruire dei suo metodi/attributi. L'esempio si propone di creare una connessione ad un appserver progress.

- Scaricare il file ASCLASS.zip e scompattarlo in un punto del propath accessibile dall'appserver.
- Aprire in procedure editor e copiare le righe seguenti
- Eseguire il codice editato

DEFINE VARIABLE clsASsysappserver          AS cls.ASsysappserver.
DEFINE VARIABLE clsASConnectionString  AS cls.ASConnectionString.
DEFINE VARIABLE clsASConnect                 AS cls.ASConnect.
DEFINE VARIABLE clsASSysConnect           AS cls.ASSysConnect.
DEFINE VARIABLE hAppServer                    AS HANDLE.
DEFINE VARIABLE lSuccess                         AS LOGICAL.


clsASConnect = NEW cls.ASConnect(). /* Crea una nuova istanza alla classe ASConnect */
clsASConnectionString = NEW cls.ASConnectionString(). /* Crea una nuova istanza alla classe clsASConnectionString */
clsASConnectionString:SetConnectionParameter("Nome Appserver" , /* Metodo della classe. Setta la stringa di connessione all'appserver */
                                             "Ip/Nome host dove l'appserver è in running",
                                             "Service/port del Name Server ").
 
clsASConnect:SetASConnectionString(clsASConnectionString).
 
hAppServer = clsASConnect:AppServerConnect (OUTPUT lSuccess ).
IF lSuccess = TRUE THEN DO:
    RUN vostro_programma.p ON hAppServer .
    clsASConnect:AppServerDisconnect().
END.
 
DELETE OBJECT clsASConnectionString.
DELETE OBJECT clsASConnect.

martedì 27 gennaio 2015

Concetti OO per sviluppatori 4GL

Cos'è una CLASSE ?

Una classe è l'elemento base della programmazione orientata agli oggetti e rappresenta l'elemento madre di un programma. E' un insieme di metodi e proprietà raggruppati in un singolo file di definizione allo scopo di realizzare un compito.

/* presentation/classes/Class.cls */
CLASS presentation.classes.Class:
/* data definitions */
/* method definitions */
/* constructor, destructor*/
END CLASS.

Cos'è un OGGETTO ?

Un oggetto è l'attualizzazione di una classe, contiene i suoi dati di default  ed ogni azione azione che può essere eseguita dai suoi metodi.

classe = definisce come fare qualche cosa
oggetto = un'istanza della definizione
In altra parole:
• Una classe è per la programmazione ad oggetti ciò che una persistent o super procedure è per le procedure.
• Un oggetto è per la programmazione ad oggetti ciò che una procedure instance è per una persistent e super procedure.

Costruzione di un oggetto
/* presentation/examples/Class.p */
DEFINE VARIABLE oClass AS presentation.classes.Class NO-UNDO.
oClass = NEW presentation.classes.Class().

METODI
Cos'è un metodo?
Per tenere un parallelismo con la programmazione di codice 4GL, un metodo può essere paragonato ad una funzione. E' racchiuso in una classe.

/* presentation/classes/MethodClass.cls */
CLASS presentation.classes.MethodClass:
    METHOD CHARACTER MethodName():
        RETURN("character string").
    END METHOD.
END CLASS.

/* presentation/classes/MethodClass.cls */
CLASS presentation.classes.MethodClass:
    DEFINE VARIABLE ch-MethodVar AS CHARACTER NO-UNDO.
    METHOD VOID SetVariable(ip-methodvar AS CHARACTER):
        ch-MethodVar = ip-methodvar.
    END METHOD.
    METHOD CHARACTER GetVariable():
        RETURN(ch-MethodVar).
    END METHOD.
END CLASS.

/* presentation/examples/Method.p */
DEFINE VARIABLE oMethodClass AS presentation.classes.MethodClass NO-UNDO.
oMethodClass = NEW presentation.classes.MethodClass().
oMethodClass:SetVariable("class value").
MESSAGE oMethodClass:GetVariable() VIEW-AS ALERT-BOX.

PROPRIETA'
Cos'è una proprietà?
Una proprietà, sempre mantenendo un parallelo con la programmazione 4GL, è una variabile racchiusa in una classe che può:

• essere direttamente accessibile da oggetti e programmi
• contenere una logica.

/* presentation/classes/property/Property.cls */
CLASS presentation.classes.property.PropertyClass:
    DEFINE PUBLIC PROPERTY character-property AS CHARACTER NO-UNDO
    GET.
    SET.
END CLASS.

/* presentation/classes/property/PropertySetterClass.cls */
CLASS presentation.classes.property.PropertySetterClass:
    DEFINE PROPERTY ExampleProperty AS CHARACTER NO-UNDO
    GET:
        RETURN(ExampleProperty).
    END GET.
    SET(ip-char AS CHARACTER):
        ASSIGN ExampleProperty = ip-char.
    END SET.
END CLASS.

/* presentation/classes/Property.p */
DEFINE VARIABLE oProperty AS presentation.classes. property.PropertyClass NO-UNDO.
DEFINE VARIABLE oPropertySetter AS presentation.classes. property.PropertySetterClass NO-UNDO.
oProperty = NEW presentation.classes.property.PropertyClass().
oPropertySetter = NEW presentation.classes. property.PropertySetterClass().
oProperty:ExampleProperty = "class property".
oPropertySetter:ExampleProperty = "class property setter".
MESSAGE oProperty:ExampleProperty VIEW-AS ALERT-BOX.
MESSAGE oPropertySetter:ExampleProperty VIEW-AS ALERT-BOX.

/* presentation/examples/Using.p */
DEFINE VARIABLE oMethodClass AS presentation.classes.MethodClass NO-UNDO.
oMethodClass = NEW presentation.classes.MethodClass().

Oppure:

USING presentation.classes.*.
DEFINE VARIABLE oMethodClass AS MethodClass NO-UNDO.
oMethodClass = NEW MethodClass().
oMethodClass:SetCharacter("class value").
MESSAGE oMethodClass:GetCharacter() VIEW-AS ALERT-BOX.

venerdì 28 marzo 2014

Concetti OO per sviluppatori 4GL - ereditarietà

L’ereditarietà costituisce il secondo principio fondamentale della programmazione ad oggetti. E' il modo usato per raggruppare metodi e proprietà di un oggetto ed estenderne il codice. Ciò viene fatto creando collezioni di attributi e comportamenti in una classe, istanziando la medesima in una nuova classe (sottoclasse), questa ne eredita le funzionalità e ne può generare di nuove.
Questo concetto permette ad una sottoclasse di essere usata ovunque una superclasse è usata.


/* Animal.cls */
CLASS Animal:
DEFINE VARIABLE cSpecies-name AS CHARACTER NO-UNDO.
    METHOD VOID SetSpecies(iSpecies-name AS CHARACTER):
        ASSIGN cSpecies-name = iSpecies-name.
    END METHOD.
    METHOD CHARACTER GetSpecies():
        RETURN(cSpecies-name).
    END METHOD.
    METHOD CHARACTER GetInformation():
        RETURN(cSpecies-name).
    END METHOD.
    CONSTRUCTOR Animal():
    END CONSTRUCTOR.
    CONSTRUCTOR Animal(iSpecies AS CHARACTER):
        SetSpecies(iSpecies).

    END CONSTRUCTOR.
END CLASS.

/* Bird.cls */
CLASS Bird
             INHERITS Animal:
DEFINE VARIABLE iSpan AS INTEGER NO-UNDO.
    METHOD VOID SetWingSpan(ipSpan AS INTEGER):
        ASSIGN iSpan = ipSpan.
    END METHOD.
    METHOD INTEGER GetWingSpan():
       RETURN(iSpan).
    END METHOD.
    CONSTRUCTOR Bird(iSpecies AS CHARACTER, ipSpan AS INTEGER):
        SetSpecies(iSpecies).
        SetWingSpan(iSpan).
    END CONSTRUCTOR.
END CLASS.

/*Dog.cls */
CLASS Dog
             INHERITS Animal:
DEFINE VARIABLE cBreed-name AS CHARACTER NO-UNDO.
    METHOD VOID SetBreed(ip-breed-name AS CHARACTER):
        ASSIGN cBreed-name = ip-breed-name.
    END.
    METHOD CHARACTER GetBreedName():
        RETURN(cBreed-name).
    END METHOD.
    CONSTRUCTOR Dog(iSpecies AS CHARACTER, ip-breed AS CHARACTER):
        SetSpecies(iSpecies).
        SetBreed(ip-breed).
    END CONSTRUCTOR.
END CLASS.

/* Inheritance.p */
USING inheritance.*.
DEFINE VARIABLE oBird AS Bird NO-UNDO.
DEFINE VARIABLE oDog AS Dog NO-UNDO.
    oBird = NEW Bird("Cardellino", 5).
    oDog = NEW Dog("Cani da pastore", "Pastore tedesco").
    MESSAGE oBird:GetSpecies() SKIP
        oBird:GetWingSpan()
    VIEW-AS ALERT-BOX.
    MESSAGE oDog:GetSpecies() SKIP
        oDog:GetBreedName()

    VIEW-AS ALERT-BOX.

principio di sostituzione di Liskov (Definizione tratta da WikipediA)

In altre parole, se una sottoclasse può sempre essere sostituita con la sua superclasse, allora
 il disegno è valido

• la sottoclasse può essere usata ovunque la sua superclasse può.


/* InheritanceAndSubstitution.p */
USING inheritance.*.
DEFINE VARIABLE oBird AS Bird NO-UNDO.
DEFINE VARIABLE oDog AS Dog NO-UNDO.
oBird = NEW Bird("Cardellino", 5).
oDog = NEW Dog("Cani da pastore", "Pastore tedesco").

/* Note passing subclass as a superclass parameter */
RUN show-species(oBird).
RUN show-species(oDog).

PROCEDURE show-species:
DEFINE INPUT PARAMETER oAnimal AS Animal NO-UNDO.
    MESSAGE oAnimal:GetSpecies() SKIP
    VIEW-AS ALERT-BOX.
END PROCEDURE.



lunedì 24 marzo 2014

Concetti OO per sviluppatori 4GL - polimorfismo


POLIMORFISMO
"- nel contesto della programmazione orientata agli oggetti, si riferisce al fatto che una espressione il cui tipo sia descritto da una classe A può assumere valori di un qualunque tipo descritto da una classe B sottoclasse di A (polimorfismo per inclusione).
- nel contesto della programmazione generica, si riferisce al fatto che il codice del programma può ricevere un tipo come parametro invece che conoscerlo a priori (polimorfismo parametrico)."

.... tratto da wikipedia.

In altre parole, lo stesso metodo può essere chiamato utilizzando parametri di diverso tipo.

ProductionOrder:CreateUsing(sales-order-number).
ProductionOrder:CreateUsing(oSalesOrder).

/* Polymorphism.cls */
CLASS PolymorphismClass:

DEFINE VARIABLE chVar AS CHARACTER NO-UNDO.

    METHOD VOID SetVariable(ip-numeric-value AS INTEGER):
        SetVariable(STRING(ip-numeric-value)).
    END METHOD.

    METHOD VOID SetVariable(ipValue AS CHARACTER):
        chVar = ipValue.
    END METHOD.

    METHOD CHARACTER GetVariable():
        RETURN(chVar).
    END METHOD.

END CLASS.

/* Polymorphism.p */
USING PolymorphismClass.*.

DEFINE VARIABLE oPolyClass1 AS PolymorphismClass NO-UNDO.
DEFINE VARIABLE oPolyClass2 AS PolymorphismClass NO-UNDO.

oPolyClass1 = NEW PolymorphismClass().
oPolyClass2 = NEW PolymorphismClass().

oPolyClass1:SetVariable("string").
oPolyClass2:SetVariable(1234).

MESSAGE oPolyClass1:GetVariable() SKIP
    oPolyClass2:GetVariable()
VIEW-AS ALERT-BOX.

Attenzione: il polimorfismo si applica solamente ai parametri e non al return type.

Corretto – due metodi nella stessa classe
• stesso method name,
• stesso data return type,
• differenti parameter signatures.
METHOD PUBLIC VOID SetVariable(ch-var as CHARACTER):
METHOD PUBLIC VOID SetVariable(de-var as DECIMAL):

Errato – due metodi nella stessa classe
• stesso method name,
• stessa parameter signature,
• differenti data return types.
METHOD PUBLIC CHARACTER GetVariable():
METHOD PUBLIC DECIMAL GetVariable():
La compilazione ritorna un errore.