Muistiinpano
Tämän sivun käyttö edellyttää valtuutusta. Voit yrittää kirjautua sisään tai vaihtaa hakemistoa.
Tämän sivun käyttö edellyttää valtuutusta. Voit yrittää vaihtaa hakemistoa.
Huomautus
Yhteisön eturyhmät ovat nyt siirtyneet Yammerista Microsoft Viva Engageen. Liity Viva Engage -yhteisöön ja osallistu uusimpiin keskusteluihin täyttämällä Pyydä käyttöoikeutta rahoitukseen ja toimintoihin Viva Engage -yhteisö -lomake ja valitse yhteisö, johon haluat liittyä.
Tässä artikkelissa kuvataan yhdistelmätietotyypit X++:ssa. X++:n yhdistelmätietotyypit ovat matriiseja, säilöjä, luokkia tietotyypeiksi, delegoituja tietotyypeiksi ja taulukoita tietotyypeiksi.
Array
Matriisi on muuttuja, joka sisältää luettelon tietotyypeistä, joilla on sama tietotyyppi. Matriisin elementtejä voi käyttää kokonaislukuindekseillä. Erillisellä lausekkeella alustat matriisin jokaisen elementin. Kun luot kokoelman säilön tietotyypin tai matriisiobjektin avulla, voit alustaa useita elementtejä käyttämällä yksittäistä lauseketta. Matriisin kaikilla kohteilla on oletusarvoisesti -tietotyypin oletusarvo matriisissa. Matriiseja on kolmentyyppisiä: dynaamisia matriiseja, kiinteäpitkiä matriiseja ja osittain levymatriiseja.
- Dynaamiset matriisit – Nämä matriisit esitellään käyttämällä tyhjää matriisiasetusta. Toisin sanoen niillä on vain hakasulkeet ([]).
- Kiinteän pituiset matriisit – Näissä matriiseissa voi olla esittelyssä määritettyjen kohteiden määrä. Kiinteän pituiset matriisit on määritetty dynaamisten matriisien kaltaisiksi, mutta pituusasetus sisältyy hakasulkeisiin.
- Osittain levymatriiseissa : Nämä matriisit on määritetty joko dynaamisiksi matriiseiksi tai kiinteän pituisiksi matriiseiksi, joilla on ylimääräinen asetus, joka määrittää, kuinka monta kohdetta tulee pitää muistissa. Muut kohteet tallennetaan levylle ja ladataan automaattisesti, kun niihin viitataan.
X++ tukee vain yksiulotteisia matriiseja. Voit kuitenkin jäljitellä useiden matriisiindeksien toimintaa. (Jos haluat lisätietoja, katso Useita matriisi-indeksejä -osio. Objektien ja taulukoiden muuttujat voidaan esitellä matriiseina. Tätä toimintoa käytetään esimerkiksi vakiosovelluksen osoiteriveillä. Matriisikokoelman luokan avulla voit tallentaa objekteja matriisiin.
Matriisiindeksien arvo on 1. Matriisin ensimmäiseen kohteeseen viitataan muodossa [1], toiseen kohteeseen viitataan nimellä [2] ja niin edelleen. Seuraavaa syntaksia käytetään matriisielementin käyttämiseen: ArrayItemReference = ArrayVariable [ Index ]. Tässä syntaksissa ArrayVariable on matriisin tunnus ja Index on matriisielementin numero. Indeksi voi olla kokonaislukulauseke. Kohteen nolla [0] avulla tyhjennetään matriisi. Jos arvo on määritetty matriisin indeksiin 0, kaikki matriisin elementit palautetaan oletusarvoonsa.
Yhden kokonaisen matriisin määrittäminen toiseen suoritetaan viittauksella.
Matriisiesimerkkejä
public void ArrayMethod()
{
int myArray[10]; // Fixed-length array with 10 integers.
myArray[4] = 1; // Accessing the 4th element in the array.
myArray[0] = 0; // Resets all elements in intArray.
// Dynamic array of integers.
int intArray[];
// Dynamic array of variables of type Datatype.
//Datatype arrayVariable[];
// Fixed-length arrays.
boolean boolArray[100]; // Fixed-length array of booleans with 100 items.
// Two examples of Partly On Disk Arrays.
// Dynamic integer array with only 100 elements in memory.
int arrayVariable [ ,100];
// Fixed-length string array with 1000 elements, and only 200 in memory.
str arrayVariable2 [1000,200];
// A dynamic array of integers.
int i[];
// A fixed-length real array with 100 elements.
real r[100];
// A dynamic array of dates with only 10 elements in memory.
date d[,10];
// A fixed length array of NoYes variables with 100 elements and 10 in memory.
NoYes ny[100,10];
}
Useita matriisiindeksejä
Joidenkin kielten, kuten C++:n ja C#:n, avulla voit esitellä matriiseja, joilla on useampi kuin yksi indeksi. Toisin sanoen voit määrittää matriisimatriisit. X++:ssa ei voi luoda suoraan useita matriisiindeksejä, koska vain yksiulotteisia matriiseja tuetaan. Voit kuitenkin ottaa käyttöön useita indeksejä käyttämällä tässä osiossa kuvattua menetelmää. Voit esimerkiksi määrittää matriisin, jossa on kaksi dimensiota. Tämä sisältää maan/alueen ansaitseman summan dimensioittain. Siinä on 10 maata/aluetta ja kolme ulottuvuutta. C++: ssa ja C#:ssa esitellään seuraava matriisi.
// This is C# or C++ code, not X++ code.
long earning[10, 3];
X++ ei kuitenkaan tue tätä esittelyä. Sen sijaan voit määrittää yksiulotteisen matriisin, jossa elementtien määrä on kunkin dimension elementtien tulos. Esimerkki:
public void MultipleArrayMethod()
{
// Step 1: define a one-dimensional array with the number
// of elements that is the product of the elements in each dimension.
real earnings[10*3];
// Step 2: to refer to a specific element, such as earnings[i,j], write the following:
// declare i and j (maybe) and assign the value to something
int i = 1;
int j = 2;
real element = earnings[(i-1)*3 + j];
}
// This can be written into a macro like this:
#localmacro.earningIndex
(%1-1)*3+%2
#endmacro
public void CallTheMacro()
{
// Next, call the specific element within the macro like this:
int i = 1;
int j = 2;
real element = earnings[#earningIndex(i,j)];
// The previous scheme can be extended to any number of dimensions.
// The element a[i1, i2, ..., ik] can be accessed by computing the
// offset into an array containing (d1*d2*...*dk) elements.
//(i1 - 1)*d2*d3*..*dk +
//(i2 - 1)*d3*d4*...*dk + .... +
//(ik-1 -1)*dk +
//(ik-1)
}
Säilö
Säilöobjekti on dynaaminen luettelo kohteista, jotka sisältävät primitiivisiä tietotyyppejä tai yhdistelmätietotyyppejä. Säilö on hyödyllinen, kun sinun on välitettävä erityyppisiä arvoja asiakas- ja palvelintasojen välillä. Jos kuitenkin aiot lisätä toistuvasti silmukan luetteloon, säilö ei ole hyvä valinta. Säilöt sopivat parhaiten prosesseille, joihin ei tarvita säilön koon tai sisällön liiallista muokkaamista. Kun säilöön lisätään liikaa tietoja, järjestelmän yleinen suorituskyky voi vähentyä, koska säilötietoja on kopioitava toistuvasti ja uutta tilaa on varattava toistuvasti.
Säilö ei ole luokka. Säilö sisältää järjestetyn primitiiviarvojen sarjan tai muita säilöjä. Minkä tahansa tyypin joustavuuden vuoksi säilö tarjoaa hyvän tavan tallentaa erityyppisten arvojen yhteen. Säilö voidaan tallentaa tietokantaan. Säilö on yksi saraketyypeistä, jotka voit valita, kun käytät Application Exploreria sarakkeen lisäämiseen taulukkoon. Säilö muistuttaa hieman matriisia tai kokoelmia, kuten Luettelo - tai Stack-luokkia . Et voi kuitenkaan koskaan muuttaa säilön kokoa tai sisältöä säilön luomisen jälkeen.
X++-lausekkeet, jotka näyttävät muokkaavan säilöä, rakentavat sisäisesti uuden säilön ja kopioivat arvoja tarpeen mukaan. Jopa säilön määritys toiseen säilön muuttujaan luo uuden kopion säilöstä. Kaikki nämä toiminnot voivat vaikuttaa suorituskykyyn. Funktioissa, jotka tarjoavat pääsyn säilöön (kuten conPeek), säilö on 1-pohjainen, ei 0-pohjainen. Indeksointi on matriiseissa 1-pohjainen. Säilön oletusarvo on tyhjä. Säilö ei sisällä mitään arvoja. Jotkin säilöjä käyttävät lausekkeet saattavat vaikuttaa muokkaavan säilöä, mutta järjestelmän sisällä säilöjä ei koskaan muokata. Sen sijaan alkuperäisen säilön tiedot yhdistetään komennon tietoihin uuden säilön muodostamiseksi. Voit luoda uuden säilön käyttämällä jotakin seuraavista funktioista: conDel, conIns tai conPoke.
Lisäksi yleinen luokka sisältää staattisia menetelmiä säilöjen käsittelyyn. Tällaisia menetelmiä ovat esimerkiksi con2ArraySource, con2Buf, con2List, con2Str, containerFromXmlNode, conView ja str2Con. Säilön käsittelyyn on useita luontaisia funktioita, kuten conIns ja conPeek. X++ conPeek-funktio palauttaa minkä tahansa tyypin , joten arvot on helpompi lukea säilöstä, kun et tiedä kunkin arvon tyyppiä. Mikä tahansa tyyppi voidaan määrittää mihin tahansa X++-arvotyyppiin, jos arvo voidaan muuntaa. Koodisi on helpompi lukea, kun siinä vältetään eksplisiittiset tietotyyppimuunnokset. Määritä siksi arvot säilöstä samaan tietotyyppiin, jota käytettiin arvon asettamiseen säilöön. Et saa määrittää säilöä millekään tyypille, koska järjestelmä ei ehkä pysty määrittämään oikeita muunnoksia. Näissä tapauksissa voi ilmetä odottamatonta toimintaa tai virheitä.
Säilön vertaaminen muihin asetuksiin
Säilötyyppi muistuttaa muita rakenteita, kuten matriiseja ja kokoelmaluokkia, kuten Luettelo ja Stack. Säilön ja Luettelon ero on se, että List-luokan esiintymä on muunnettavissa. Luettelo-objekti varaa ensin enemmän tilaa kuin sen tiedot kuluttavat. Kun tietoja lisätään, välilyönti täytetään. Tämä toiminta on tehokkaampaa kuin tilan varaaminen enemmän aina, kun elementti lisätään. Luettelon päivitys suoritetaan nopeammin kuin vastaavat toiminnot säilössä.
Kun muodostat luettelo-objektin , määrität yhden tietotyypin, jonka Luettelo-objekti voi tallentaa. Tämä rajoitus on luetteloa varten vähemmän joustava kuin säilössä. Voit kuitenkin tallentaa objekteja luetteloon, kun taas säilö voi tallentaa vain arvotyyppejä. Säilön ja matriisin ero on, että matriisi voi sisältää vain määritettyjä kohteita. Voit varata muistitilaa matriisille ja täyttää välilyönnin arvoilla myöhemmin. Voit esimerkiksi täyttää silmukan arvot. Tämä toiminta on tehokasta ja toimii hyvin. Kun haluat luoda uuden säilön liittämällä uusia tietoja, voit käyttää joko -operaattoria += tai conIns-funktiota . Operaattori += on nopeampi vaihtoehto. Käytä conIns-funktiota vain, jos haluat lisätä uusia tietoja ennen alkuperäisten tietojen viimeistä indeksiä.
Et voi tallentaa objektiviittauksia säilöihin. Kun kääntäjä havaitsee yrityksen tallentaa objektiviittaus säilöön, se antaa virhesanoman. Jos säilöön lisättävän elementin tyyppi on mikä tahansa tyyppi, kääntäjä ei voi määrittää, onko arvo viitetyyppi. Tässä tapauksessa kääntäjä sallii yrityksen. Vaikka kääntäjä ei määritä koodia virheellisesti, suorituksen aikana tapahtuu virhe.
Säilön esimerkit
public void ContainerExample()
{
// First, declare the variables you are using.
container myContainer;
container myContainer4;
container myContainer5;
// Three ways to declare a container.
myContainer = [1];
myContainer += [2];
myContainer4 = myContainer5;
// Declare a container.
container cr3;
// Assign a literal container to a container variable.
cr3 = [22, "blue"];
// Declare and assign a container.
container cr2 = [1, "blue", true];
// Mimic container modification (implicitly creates a copy).
cr3 += [16, strMyColorString];
cr3 = conIns(cr3, 1, 3.14);
cr3 = conPoke(cr3, 2, "violet");
// Assignment of a container (implicitly creates a copy).
cr2 = cr3;
// Read a value from the container.
str myStr = conPeek(cr2, 1);
// One statement that does multiple assignments from a container.
str myStr;
int myInt;
container cr4 = ["Hello", 22, 20\07\1988];
[myStr, myInt] = cr4; // "Hello", 22
// Example of applying the = operator to a container. The example
// initializes myContainer2 and myContainer33.
myContainer2 = [2, "apple"];
// Next, you make a copy of myContainer33 and assign the copy to myContainer2.
myContainer33 = [33, "grape"];
myContainer2 = myContainer33; // The container that myContainer2 had been holding is no longer available and cannot be recovered.
// An example of building a new container by
// assigning a new value to myContainer33 through the += operator.
myContainer33 += [34, "banana"];
}
// Container example. In this example, variable2 and variable33 hold different containers.
static void JobC(Args _args)
{
container variable2, variable33;
variable2 += [98];
variable33 = variable2;
variable2 += [97];
}
// List class example. In this example, variable2 and variable33 refer to the same List object.
static void JobL(Args _args)
{
List variable2,variable33;
variable2 = new List(Types::Integer);
variable2.addEnd(98);
variable33 = variable2;
variable2.addEnd(97);
}
// The automatic type conversion by anytype also applies to the special syntax for making multiple
// assignments from a container in one statement. This is shown in the following code example,
// which assigns a str to an int, and an int to a str.
static void JobContainerMultiAssignmentUsesAnytype(Args _args)
{
container con2;
int int4;
str str7;
con2 = ["11", 222];
[int4, str7] = con2;
info(strfmt("int4==11==(%1), str7==222==(%2)", int4, str7));
}
/*** Output:
Message (10:36:22 am)
int4==11==(11), str7==222==(222)
***/
static void UseQuery()
{
// An example of how the compiler diagnoses attempts to store object in containers
container c = [new Query()]; // This statement will cause the error message shown below.
/*** Instance of type 'Query' cannot be added to a container. ***/
// An example of a code that won't cause an error message, but will
// cause an error message to be thrown at runtime.
anytype a = new Query();
container d = [a];
}
Luokit tietotyypeiksi
Luokka on tyyppimääritys, joka kuvaa sekä muuttujia että menetelmiä luokan esiintymille. (Luokan esiintymiä kutsutaan myös objekteiksi.) Luokka on vain objektien määritys, ja kaikki objektit ovat tyhjäarvoisia , kun ne on määritetty. Application Explorerissa jokainen Luokka-solmun sovellusluokka on tietotyyppi. Voit määrittää koodissasi tämäntyyppisiä muuttujia. Voit muodostaa luokan esiintymiä ja määrittää esiintymiä muuttujille.
Luokat voidaan sijoittaa sisäkkäin lähdekoodissa. Sisäkkäiset luokat ovat käytettävissä vain lomakkeiden sisällä (kuten FormRun-luokan laajentama luokka), ja niitä käytetään edustamaan ohjausobjekteja, tietolähteitä tai tietokenttiä. Määritteen koriste, kuten luokan tai menetelmän määritteen koriste, voi jättää pois määritteen nimen jälkiliitteen, jos jälkiliite on Määrite. Tämän vuoksi X++ sallii [MyFavorite] -arvon sen sijaan, että vaatisit [MyFavoriteAttribute]-toimintoa. Lisäksi määritteitä käytetään nyt edustajien ja menetelmien käsittelijöissä, jotta käsittelijät voidaan yhdistää kyseisiin kohteisiin.
AX 2012:n tai aiempien versioiden tapauksessa voit määrittää menetelmän, joka suoritetaan joko asiakaskoneessa tai palvelimessa. Talous- ja toimintosovelluksissa kaikki käännetyt X++-koodit suoritetaan palvelimessa kuitenkin muodossa .NET Common Intermediate Language (CIL). Asiakassivustolla tai selaimessa ei ole enää koodia, joka arvioidaan. Siksi asiakkaan ja palvelimen avainsanat ohitetaan nyt. Vaikka nämä avainsanat eivät aiheuta käännösvirhettä, jos niitä käytetään, niitä ei tule käyttää uudessa koodissa.
Yksityiset ja suojatut jäsenmuuttujat
Aiemmin kaikki luokassa määritetyt jäsenmuuttujat oli suojattu. Voit nyt määrittää jäsenmuuttujien näkyvyyden eksplisiittisesti lisäämällä yksityiset, suojatut ja julkiset avainsanat. Näiden muokkaajien tulkinta on ilmeinen ja se on tasattu menetelmien semantiikkaan:
- private – Jäsenmuuttujaa voi käyttää vain siinä luokassa, jossa se on määritetty.
- protected – Jäsenmuuttujaa voidaan käyttää luokassa, jossa se on määritetty, ja tämän luokan kaikki aliluokat.
- public – Jäsenmuuttujaa voi käyttää missä tahansa. Se näkyy luokkahierarkian ulkopuolella, jossa se on määritetty.
Oletusarvoisesti jäsenmuuttujat, joita ei ole varustettu eksplisiittisellä muokkaustoiminnolla, ovat silti suojattuja. Parhaana käytäntönä sinun on kuitenkin eksplisiittisesti määritettävä näkyvyys. Kuten aiemmin kerroimme, kun jäsenmuuttuja on määritetty julkiseksi, sitä voidaan käyttää sen luokan ulkopuolella, jossa se on määritetty. Tässä tapauksessa sinun on määritettävä tarkenne, joka määrittää muuttujaa isännöitävän objektin. Määritä tarkenne käyttämällä pistemerkintää, kuten menetelmäkutsuissa.
Seuraavassa esimerkissä field1-kenttää käytetään käyttämällä eksplisiittistä tätä tarkennetta. Tässä tapauksessa ei ehkä ole hyvä idea tehdä jäsenmuuttujasta julkinen, koska tämä lähestymistapa paljastaa luokan sisäisen työn sen kuluttajille ja luo siten vahvan riippuvuuden luokan toteutuksen ja sen kuluttajien välille. Sinun tulee aina yrittää olla riippuvainen vain sopimuksesta, ei toteutuksesta.
public class AnotherClass3
{
int field1;
str field2;
void new()
{
this.field1 = 1; // Explicit object designated.
field2 = "Banana"; // 'this' assumed, as usual.
}
}
Staattiset konstruktorit ja staattiset kentät
Staattiset kentät ovat kenttiä, jotka on määritetty staattisen avainsanan avulla. Käsitteellisesti staattiset kentät koskevat luokkaa, eivät luokan esiintymiä. Staattiset konstruktorit suoritetaan varmasti, ennen kuin staattisia kutsuja tai esiintymäkutsuja tehdään luokkaan. Staattisen konstruktorin suoritus on suhteessa käyttäjän istuntoon. Staattista konstruktoria ei koskaan kutsuta eksplisiittisesti. Sen sijaan kääntäjä luo koodin varmistaakseen, että konstruktoria kutsutaan tasan kerran, ennen kuin mitään muuta luokan menetelmää kutsutaan. Staattisen konstruktorin avulla alustetaan staattisia tietoja tai suoritetaan toiminto, joka on suoritettava vain kerran. Et voi antaa parametreja staattiselle konstruktorille, ja se on merkittävä staattisella avainsanalla.
// An example of how a singleton (call instance in the example below)
// can be created using the static constructor.
public class Singleton
{
private static Singleton instance;
private void new()
{
}
static void TypeNew() // This is the static constructor.
{
instance = new Singleton();
}
public static Singleton Instance()
{
return Singleton::instance;
}
}
// The singleton ensures that only one instance of the class
// will be called, which is consumed by the following.
{
// Your code here.
Singleton i = Singleton::Instance();
}
Luokka-elementit Application Explorerissa
Application Explorerin useimmissa luokkasolmuissa on kaksi erityistä solmua: classDeclaration-solmu ja uusi solmu. ClassDeclaration sisältää aina X++-luokan avainsanan. Muita avainsanoja, kuten laajennuksia, voidaan sisällyttää luokan muokkaamiseksi. Tämä solmu voi sisältää myös jäsenmuuttujien määrittelyjä.
Seuraavassa esimerkissä m_priority ja m_rectangle ovat luokan jäseniä.
// An example of a classDeclaration.
public class YourDerivedClass extends YourBaseClass
{
int m_priority;
Rectangle m_rectangle;
void new(int _length, int _width)
{
this.m_rectangle = new Rectangle(_length, _width);
}
}
Uusi operaattori sisältää logiikan, joka suoritetaan, kun uutta operaattoria käytetään luokan esiintymän luomiseen. Uuden menetelmän logiikka voi muodostaa objektin ja määrittää kyseisen objektin muuttujalle, joka on määritetty luokassaDeclaration. Jokaisella luokalla voi olla vain yksi uusi menetelmä. Uudessa menetelmässä on kuitenkin usein kutsuttava perusluokan uutta menetelmää. Jos haluat kutsua perusluokan uutta menetelmää, kutsu super().
Seuraavassa esimerkissä näytetään YourDerivedClass-luokanuusi menetelmä edellisessä luokanDeklaration-esimerkissä. Tässä uudessa menetelmässä koodi muodostaa suorakulmioluokan esiintymän . Esiintymä määritetään m_rectangle muuttujalle. Tässä esimerkissä käytettävä avainsana on valinnainen. Kuitenkin jos sisällytät sen, IntelliSense voi olla hyödyllisempi.
// An example of the new method from the previous classDeclaration example.
void new(int _length, int _width)
{
this.m_rectangle = new Rectangle(_length, _width);
}
Roskakorien kerääminen
Suoritusaikana useimmilla objekteilla ei enää ole niihin viittaavia muuttujia. Järjestelmä tarkistaa nämä objektit ja poistaa ne muistista. Muistitila tulee sitten saataville muihin käyttötarkoituksiin. Objekti-luokassa on menetelmä, jonka nimi on Viimeistely. Viimeistelymenetelmä ei kuitenkaan ole destruktori. Suorituspalvelu ei koskaan kutsu viimeistelymenetelmää , vaikka objekti kerätään roskana.
Järjestelmäluokat
Application Explorerin Järjestelmän dokumentaatioluokat> -kohdassa on luettelo ydinluokista tai järjestelmäluokista. Järjestelmäluokkia ei ole kirjoitettu X++:lla, etkä näe niiden lähdekoodia. Et voi lisätä järjestelmäluokkia. Järjestelmäluokilla on yleensä uusi menetelmä, mutta niillä ei ole luokanPäätössolmua . Jokainen sovellusluokka laajentaa implisiittisesti Objektijärjestelmä-luokkaa. Jotkin järjestelmäluokat laajennetaan sovellusluokalla, jolla on samanlainen nimi. Esimerkiksi xClassFactory on laajennettu classfactory-arvolla. Näissä tapauksissa sinun ei kannata käyttää järjestelmäluokkaa. Lisätietoja on kohdassa "Järjestelmäluokkien korvaamissovellusluokat" luokissa ja menetelmissä.
Laajennusmenetelmät
Laajennusmenetelmäominaisuuden avulla voit lisätä laajennusmenetelmiä kohdeluokkaan kirjoittamalla menetelmät erilliseen laajennusluokkaan. Seuraavat säännöt pätevät:
- Laajennusluokan on oltava staattinen.
- Laajennusluokan nimen lopussa on oltava 10 merkin jälkiliite _Extension mutta jälkiliitettä edeltävän nimen osalle ei ole rajoitusta.
- Kaikki laajennusluokan laajennusmenetelmät on määritettävä julkisiksi staattisiksi.
- Jokaisen laajennusmenetelmän ensimmäinen parametri on tyyppi, jota laajennusmenetelmä laajentaa. Kun laajennusmenetelmää kutsutaan, soittaja ei saa välittää mitään ensimmäiselle parametrille. Sen sijaan järjestelmä välittää automaattisesti ensimmäisen parametrin vaaditun objektin.
- Laajennusmenetelmän kohteen on oltava luokka-, taulukko-, näkymä- tai karttasovellusobjektityyppi.
Laajennusluokka voi sisältää yksityisiä tai suojattuja staattisia menetelmiä. Näitä menetelmiä käytetään yleensä toteutustiedoissa, eikä niitä näytetä laajennuksina. Laajennusmenetelmän tekniikka ei vaikuta sen laajentaman luokan lähdekoodiin, joten luokan lisääminen ei edellytä ylitasoistamista.
Mitkään olemassa olevat laajennusmenetelmät eivät koskaan vaikuta kohdeluokan päivityksiin. Jos kohdeluokkaan tehtävä päivitys lisää samannimisen menetelmän kuin laajennusmenetelmäsi, laajennusmenetelmää ei enää voi käyttää kohdeluokan objektien kautta. Laajennusmenetelmämenetelmä käyttää samaa pisteeristä erotettua syntaksia, jota käytät usein säännöllisten esiintymämenetelmien kutsumiseen. Laajennusmenetelmät voivat käyttää kaikkia kohdeluokan julkisia artefakteja, mutta ne eivät voi käyttää mitään suojattua tai yksityistä. Siksi laajennusmenetelmiä voidaan pitää syntaktisen sokerin tyyppinä. Kohdetyypistä riippumatta laajennusluokkaa käytetään laajennusmenetelmien lisäämiseen tyyppiin. Esimerkiksi laajennustaulukkoa ei käytetä menetelmien lisäämiseen taulukkoon, eikä laajennustaulukkoa ole olemassa.
// An example of an extension class holding a few extension methods.
public static class AtlInventLocation_Extension
{
public static InventLocation refillEnabled(
InventLocation _warehouse,
boolean _isRefillEnabled = true)
{
_warehouse.ReqRefill = _isRefillEnabled;
return _warehouse;
}
public static InventLocation save(InventLocation _warehouse)
{
_warehouse.write();
return _warehouse;
}
}
Edustajat tietotyyppeinä
Edustaja kerää -menetelmiä, jotka tilaavat sen. Edustaja määrittää parametrin allekirjoituksen, joka kaikkien sen tilaajamenetelmien on jaettava. Kun edustaja kutsutaan, edustaja kutsuu jokaista tilaajaansa. Edustaja ei koskaan palauta arvoa, eikä sillä voi olla oletusarvoa. Aluksi jokaisella edustajalla ei ole tilattavia menetelmiä. Edustajan voi esitellämien parametrien määrää ei ole rajoitettu, eikä näiden parametrien tyyppiä ole rajoitettu. Valtuutettu elin on aina tyhjä, koska edustajan ainoana tarkoituksena on määrittää sopimus, jota tilaajien on noudatettava. Edustajaa ei tarvitse määrittää luokassa. Edustajat voidaan määrittää myös taulukossa, lomakkeessa tai kyselyssä.
Delegoi esimerkkejä
abstract class VarDatClass
{
void new(utcdatetime _dateTime, str _changeDescription)
{
// An example of subscribing a delegate.
this.notifyChanged += eventhandler(this.InfologChanges);
this.notifyChanged += eventhandler(this.SaveInDatabase);
notifyChange(_dateTime, _changeDescription);
}
void notifyChange(utcdatetime _dateTime, str _changeDescription)
{
// An example of calling a delegate.
this.notifyChanged(_dateTime, _changeDescription);
}
// delegate method examples
// An example of declaring a delegate.
delegate void notifyChanged(utcdatetime _dateTime, str _changeDescription)
{
}
// method that is to be subscribed.
public static void InfologChanges(utcDateTime _dateTime, str _changeDescription)
{
info("A notification has occurred calling static handler:" +
DateTimeUtil::toStr(_dateTime) +
" Message:" +
_changeDescription);
}
// method that is to be subscribed.
public static void SaveInDatabase(utcDateTime _dateTime, str _changeDescription)
{
// save changes in database.
}
}
Taulukot tietotyyppeinä
Kaikkia taulukoita voidaan käsitellä luokkamääritelminä. Taulukkomuuttujaa voidaan pitää taulukon (luokan) määrityksen esiintymänä (objektina). Taulukkomuuttujan jokaisen kentän oletusarvo on tyhjä. Voit käsitellä kenttiä ja luoda menetelmiä taulukoille. -menetelmät voidaan käynnistää taulukon esiintymissä. Jos haluat käsitellä (eli lukea, päivittää, lisätä ja poistaa) tietueita taulukoissa, sinun on määritettävä vähintään yksi taulukkomuuttuja, joka voi pitää tietueen tarkastelussa. Paras käytäntö on käyttää taulukon nimeä muuttujan nimenä, mutta käytä aluksi pienillä kirjaimilla kirjoitettua kirjainta. Seuraavassa on muutamia tärkeitä eroja taulukoiden ja objektien välillä:
- Et voi varata tilaa taulukon muuttujille. Kohdistus tehdään implisiittisesti.
- Taulukkomuuttujien kentät ovat julkisia. Niihin voi viitata missä tahansa.
- Taulukkomuuttujien kenttiin voidaan viitata lausekkeilla.
Automaattista muuntamista ei ole, mutta yleisiksi ilmoitetut taulukkomuuttujat voivat sisältää tietoja mistä tahansa taulukosta.
Taulukkomuuttujien laajuus
Useimmissa suhteissa taulukkomuuttujia voidaan pitää objekteina, mutta toisin kuin objekteja, niitä ei nimenomaisesti jaeta. Vain muuttujan esittely vaaditaan. Kaikki taulukot ovat yhteensopivia Common-taulukon kanssa, aivan kuten kaikki objektit ovat yhteensopivia Objekti-luokan kanssa. Taulukkomuuttujat on määritetty yleisiksi puskuiksi, ja niitä voidaan käyttää tietojen tallentamiseen mistä tahansa taulukosta. Et voi käyttää taulukoita, joissa ei ole taulukkomuuttujia. Taulukkomuuttujien ja -objektien ilmoittamisen periaatteet ovat samat, lukuun ottamatta tilan varaamista.
Taulukkoesimerkkejä
-syntaksi mahdollistaa kenttien viittaamisen eri mahdollisuuksiin tietueissa. Voit esimerkiksi käyttää TableName.( FieldId) -syntaksi.
Seuraavassa esimerkissä tulostetaan asiakastaulukon nykyisen tietueen kenttien sisältö.
// Declares and allocates space for one CustTable record.
public void myMethod()
{
CustomerTable custTable;
}
// An example of referencing table variables.
public void printAccountNo()
{
CustomerTable custTable;
print custTable.AccountNo; // Prints the field reference.
}
Seuraavassa esimerkissä käytetään menetelmiä fieldCnt ja fieldCnt2Id . fieldCnt-menetelmä laskee taulukon kenttien määrän, kun taas fieldCnt2Id palauttaa kentän luvun tunnuksen. FieldCnt2Id-menetelmän avulla voit esimerkiksi tietää, että taulukon kentän numero 6 sisältää tunnuksen 54. Tämä muunnos vaaditaan, koska ei ole mitään takeita sille, että taulukon kenttien tunnukset ovat peräkkäisiä.
// An example of the various possibilities for referencing fields in records.
public void printCust()
{
int i, n, k;
CustomerTable custTable;
DictTable dictTable;
dictTable = new DictTable(custTable.TableId);
n = dictTable.fieldCnt();
print "Number of fields in table: ", n;
for(i=1; i<=n; i++)
{
k = dictTable.fieldCnt2Id(i);
print "The ", dictTable.fieldName(k),
" field with Id=",k, " contains '",
custTable.(k), "'";
}
}