AS3 101: OOP Arv, settere & Getters - Basix

AS3 101: OOP Arv, Setters &Getters - Basix
3
Del
en
Del

Dette Cyber ​​mandag Envato Tuts + kurs vil bli redusert til bare $ 3. Ikke gå glipp av
Dette innlegget er en del av en serie som heter AS3 101.AS3 101: Quick Tips - Bruk Tilgang Modifikatorer EffectivelyAS3 101:. Quick Tips - Ved å bruke statiske egenskaper og metoder

Når sist vi snakket sammen, vi hadde en knapp klasse som kan brukes til å raskt lage en knapp av en viss stil. Men jeg har også bedt deg om å ignorere visse aspekter av koden. Vi kommer til å starte denne sesjonen med en liten oppløsning. Det er på tide å forklare hva strekker gjør


I løpet av denne opplæringen, vil vi utvide at Button klasse, gevinst en dypere forståelse av hva som faktisk skjer, og lære noen flere objektorientert programmering vilkår og teknikker, nemlig arv
. Button klassen vil bli bedre og mer nyttig



Trinn 1:. Arv

En av de kraftigste funksjonene i OOP er arv
. Første ting først, det er arv i den forstand av slektsforskning, ikke arv i den forstand av å motta pengesummer fra en avdød onkel.

I et nøtteskall, arv gjør at en gitt klasse til å ta en eksisterende klasse og gjøre alt at det kan gjøre, men med endringer og /eller tilføyelser. Med andre ord, ikke anta klasse A to ting, kalt foo og bar. Hvis klasse B arver fra A, så vil det automatisk også gjøre foo og bar. B kan også deretter definere en ekstra ting den kan gjøre, kalt baz. Den kan også velge å fortsatt gjøre noe som kalles bar, men endre intern opptreden litt

En praktisk illustrasjon vil bidra til å forklare dette



Trinn 2:.. Eks: The Displayobject

I Actionscript 3 er det en klasse som heter Displayobject
. Denne klassen definerer egenskaper og metoder som er relevante for ethvert visuelt element: x og y, bredde og høyde, alfa, filtre, maske, rotasjon, getBounds (), hitTestPoint (), etc (se dokumentasjonen for en fullstendig liste). I hovedsak alle oppgaver som passer for alle
typer fremvisbare objekter er definert her.

Det finnes en rekke klasser som strekker Displayobject. En av disse er Shape
. Alt som Shape gjør er å definere en grafikk eiendom, noe som gjør at programmavektortegning. I utgangspunktet er Shape et display objekt som spesialiserer seg på vektorgrafikk. Og fordi Shape strekker Displayobject, arver alle de andre, mer generelle egenskaper og metoder, og en form sies å være en slags Displayobject (se dokumentasjonen for den Shape klasse).

En annen underklasse av Displayobject er Bitmap
. Bitmap er liksom piksel analog av Shape; det bare legger til noen egenskaper som er relevante å arbeide med punktgrafikk (piksler) med Actionscript. Igjen, skjønt, fordi den strekker seg Displayobject det kan også være plassert, roteres, filtrert, traff testet, etc, akkurat som Displayobject, og dermed Bitmap sies å være en annen type Displayobject (se dokumentasjonen for den Bitmap klasse).

Hva mer, en tredje klasse som arver fra Displayobject er InteractiveObject
. Med InteractiveObject, det er et halvt dusin eiendommer lagt knyttet til kontekstmenyer, tastaturnavigasjon, mus aktivering. Den store tingen InteractiveObject legger er en hel slew av hendelser som det er i stand til å sende ut, fra mus velt til tastaturfokus til alle slags mulige brukerundersøkelser. Og, igjen, er en InteractiveObject en slags Displayobject og så det kan også være plassert, et al (dokumentasjon for InteractiveObject klasse).

Følgende graf viser forholdene mellom de ulike klassene vi bare diskutert ( sammen med en vi har ikke.:. Video
Forhåpentligvis hensikten med denne klassen er opplagt)

I en graf som dette, viser en arv en linje med en pilspiss i den ene enden forhold. Boksen med halen av pilen er den klassen som strekker boksen med hodet av pilen



Trinn 3:. The Inheritance Structure

På dette punktet, vi har sett på fire klasser: en superklasse, og tre av dens subklasser. Legg merke til at mens alle tre underklasser har noen felles funksjonalitet (posisjon, rotasjon, etc.), alt
av overlappingen er definert i Displayobject. The Shape har en grafikk eiendom, Bitmap har bitmapData eiendom, og InteractiveObject sender en roll hendelse, og de er unike for disse klassene. En Bitmap kan ikke programma trukket inn, og en Shape kan ikke sende en roll hendelse

Dette er en vanlig bruk for arv. Å konsolidere funksjonalitet som er felles for en familie av klasser. Alle disse visningsobjekter må være plassert, så i stedet for å sette posisjonering kode i hver av klassene, Adobe setter inn koden i en super klasse som de alle andre visningsobjekter kan arve.

Listen fortsetter : InteractiveObject har undergrupper av sine egne. Textfield
er en imponerende klasse som strekker InteractiveObject men legger også mange egenskaper og metoder som arbeider med innstillingen, får, og styling tekst. Ikke bare forlenge den InteractiveObject, og derfor arver alle hendelser og ting som er definert der, men det (indirekte) arver fra Displayobject, slik at det også kan være plassert, roteres, etc. Det funksjonalitet fortsetter ned i slektstreet (se dokumentasjonen for den Textfield klassen).

En annen klasse som heter Display
er også en underklasse av InteractiveObject, og det legger til funksjonalitet for å håndtere andre visningsobjekter som kan finnes i en annen skjerm objekt, som addChild () og swapChildren () (barnet er den generelle betegnelsen på en skjerm objekt som inngår i en annen skjerm objekt) (se dokumentasjonen for Display klasse). Videre Sprite
strekker InteractiveObject, og legger dra evner sammen med noen interaktivitet bekvemmeligheter og en grafikk objekt (se dokumentasjonen for Sprite-klassen).

Følgende bilde illustrerer hele arven treet som vi ' har diskutert langt



Trinn 4:. Den MovieClip som eksempel

Og sist men ikke minst, MovieClip
strekker Sprite, definere evnen til å arbeide med tidslinje (med egenskaper som currentFrame og metoder som play () og gotoAndStop ()). Innen vi kommer til MovieClip, den har en avstamning som går opp gjennom Sprite til Display å InteractiveObject til Displayobject, og dermed gjør den i stand til:

Position, rotasjon, filtre, og traff tester (takk til Displayobject)

Dealing med interaktivitet, nemlig utsending hendelser knyttet til brukerundersøkelser (takk til InteractiveObject)

innhold av andre visningsobjekter (takk til Display)

Arbeide med å dra og bli trukket inn (takk til Sprite)

Managing sin tidslinje (takk til MovieClip selv)

Det er mye funksjonalitet, men hierarkiet av arv for alle visningsobjekter gjør mye av gjenbruk av kode, slik at virkelig
MovieClip er ikke å legge så mye til bordet. Det er bare det neste logiske steg for å legge til funksjoner (se dokumentasjonen for MovieClip klasse)

Det er også verdt å merke seg at Displayobject er i seg selv en underklasse. Det strekker EventDispatcher
slik at den er i stand til å sende ut arrangementer og jobbe med standard AS3 hendelsen modell. MovieClip har ganske arv.

For en oversikt på Flash visningslisten, se Adobes dokumentasjon på skjerm programmering, samt min forrige tutorial som dekker listevisning.

Følgende illustrasjon oppsummerer hierarkiet av arven som vi har diskutert i de tre foregående trinnene, også legge noen klasser vi har ikke snakket om:

Merk at denne illustrasjonen er ikke omfattende; det er ufullstendige lister over egenskaper og metoder, og faktisk er det hele klasser mangler. Hensikten er å gi en kompakt representasjon av den omfattende Displayobject hierarkiet



Trinn 5:. Utvide MovieClip

Så, når vi skriver dette:
public class Button101 strekker MovieClip < p> Vi sier at klassen vi skriver faktisk vil bare definere ekstra
egenskaper og metoder som vi vil liksom pode på eksisterende MovieClip klasse. Det vil si, Button101 er en
MovieClip, bare med litt ekstra innebygd funksjonalitet.

Til slutt, som betyr at fra i Button101 klasse, kan vi bruke Displayobject egenskaper og metoder som om vi skrev dem selv, som vi gjør her:
BGD = new Shape (); bgd.graphics.beginFill (0x999999, 1); bgd.graphics.drawRect (0, 0, 200, 50); addChild ( BGD);

Det addChild () metoden er definert av Display, men til syvende og sist vi arver fra Display slik at vi kan bruke det

På samme måte, noen litt kode som bruker en Button101 objekt kan i utgangspunktet behandle det som. noen annen skjerm objekt, som vi gjør her, i document:
knapp = new Button101 (); button.x = 10; button.y = 200; addChild (knapp);

Så, når vi skaper den Button101 objekt, kan vi tenke på det som bare en spesialisert MovieClip. Det er ikke ulikt hvordan du oppretter spesialiserte movieclips i Flash IDE og lagre symbolene i biblioteket. Den eneste virkelige forskjellen er at i så fall bruker du de grafiske verktøyene i stedet for å skrive en haug med kode.

Faktisk, her er det dobbelt whammy som document selv strekker MovieClip, og så det
også arver alle disse metoder og egenskaper, som er hvordan vi har tilgang til en addChild () i første omgang.

(Merk at du kan kombinere disse to tilnærmingene og skrive noen egendefinert kode som er knyttet til et symbol på biblioteket, men vi vil ikke ta opp denne teknikken i denne opplæringen)



Trinn 6:.? Hva nå

OK, det var litt av en bit av teori, så ta en rask pust i bakken hvis du trenger det. Poenget er å komme til tak med terminologien og teknikker, men ikke nødvendigvis mestrer det i ett kjør. Objektorientert programmering er en betydelig mental sprang, så ikke forvent alt å synke inn med en gang.

Faktisk, hvis du må, bare slutte å lese akkurat nå, og komme tilbake til dette etter hodet stopper spinne. Eller re-lese tidligere flere skritt for å sørge for at du har det.

Selv om du er klar til å gå videre akkurat nå, den eneste hensikten med dette trinnet er å ikke tenke så mye .. .

Fortsett når du er klar



Trinn 7:. Tilordne en knapp til en handling

Akkurat nå våre to knapper begge har sine KLIKK hendelser behandles på samme måte i dokumentet klassen. Noen ganger er det nyttig å ha to knapper gjør det samme for å gi brukeren noen valg, men oftest forskjellige knappene gjør forskjellige ting. Hvordan kan vi sette opp flere tiltak for flere knapper

Det er noen tilnærminger til dette problemet, og jeg vil skissere noen



Trinn 8:?. Alternativ 1 Multiple Hendelses Handlers

Først og sannsynligvis den mest åpenbare, er å bare sette opp en ny episode håndtering metoden. For eksempel (kode forkortet til å fokusere på de relevante biter ... gjerne å integrere i arbeids prosjekt for å teste det ut, men i forbindelse med videre tutorial dette er ikke offisielt kode for å komme inn i dokumentet klasse):
button.addEventListener (MouseEvent.CLICK, onButton1Click); button2.addEventListener (MouseEvent.CLICK, onButton2Click); //... privat funksjon onButton1Click (e: MouseEvent): void {trace ("Button 1 ble klikket");} privat funksjon onButton2Click (e: MouseEvent): void {trace ("Knapp 2 ble klikket");}

Dette er trolig den vanligste løsningen på denne situasjonen, spesielt når to knapper utføre ganske ulike funksjoner. Når man knappen åpner en informativ overlegg, og en annen kjøper et produkt, er det fornuftig å gjøre det som sannsynligvis kommer naturlig og gjøre separate funksjoner



Trinn 9:. Alternativ 2 Switch /Case

Men når knappene utføre svært lignende funksjoner, for eksempel flere produktminiatyrbilder som ønsker å åpne opp et produkt detalj, bare med forskjellig innhold, og deretter lage flere handlere kan være kjedelig i beste, og kan føre til vanskelige å håndtere kode i verste fall . I dette tilfellet er det sannsynligvis være bedre å bruke en betinget utsagn eller en ordbok (se AS3 101 - Forgrening for mer dyptgående diskusjoner om begge disse teknikkene)
button.addEventListener (MouseEvent.CLICK, onButtonClick);. Knappen2 .addEventListener (MouseEvent.CLICK, onButtonClick); //... privat funksjon onButtonClick (e: MouseEvent): void {switch (e.target) {case knapp: trace ("Button 1 ble klikket"); gå i stykker; case knappen2: trace ("Button 2 ble klikket"); gå i stykker; }}

Hvis miniatyrene ble dynamisk generert (ved hjelp av eksterne data og en loop ... se AS3 101 - Loops og AS3 101 - XML), som gjør det darn nær umulig å skape en unik hendelse behandleren for hver knapp, og selv gjør det ganske vanskelig å trekke av de ovennevnte triks (selv om en ordbok ville fungere godt)



Trinn 10:. Alternativ 3 Objekter som lagrer data

Men det er et annet alternativ som begynner å bli attraktivt som OOP teknikker benyttes. Det er et skritt lenger enn det siste alternativet; stedet for å sammenligne hendelsen målet til en kjent liste over mulige mål, vi bare spør målet for relevant opplysning.

Uten videre modifikasjon til Button101 klasse, kan vi illustrere dette ganske enkelt. Anta i vårt spor budskap, var det vårt mål å sende ut x plasseringen av knappen som ble klikket, noe sånt som dette:
knapp som ble klikket har en x-verdi på 10

Vi kan gjøre det veldig enkelt ved . bare refererer til x tilhører selve målet
privat funksjon onButtonClick (e: MouseEvent): void {trace ("Knappen som ble klikket har en x-verdi på" + e.target.x);}

Sjekk det ut, en linje! Ingen behov for ordbøker, switch uttalelser eller flere, nær-identisk hendelsesbehandlinger.

Husk at overdrevent lang diskusjon om arv? Selvfølgelig gjør du. Fordi e.target er en Button101 objekt, og fordi en Button101 objekt er i siste instans et Displayobject, har vi en x eiendom, selv om vi aldri definert som eiendom i vår Button101 klasse.

Dette blir enda mer
kraftig når vi innser at vi kan opprette egendefinerte egenskaper på Button101 klasse (eller en hvilken som helst egendefinert klasse) hvor objektene kan lagre data. Anta at, for eksempel, i stedet for x-verdien på knappen, ønsket vi å navigere til en URL eller en annen. Og hvis hver knapp eksempel hadde sin egen URL-data som er lagret i en url
eiendom, vi kan håndtere gjennomføringen av klikk veldig enkelt.

Hvis du tenker at dette kan være så enkelt som:
privat funksjon onButtonClick (e: MouseEvent): void {navigateToURL (ny URLRequest (e.target.url));}

Da er du riktig. Men for å få den url eiendom å eksistere i første omgang, har vi en jobb å gjøre i Button101 klassen. Og før vi gjør det, må vi snakke om tilgangsmodifiserings



Trinn 11:. Offentlige Tilgangs

Tiden er kommet for å løse disse offentlige og private ord jeg har vært å fortelle du å ignorere (endelig!). Disse kalles tilgangsmodifiserings Hotell og definere hvordan en egenskap eller metode kan nås (eller ikke) fra andre deler av programmet

Det er fire modifikatorer.
< li> privat

beskyttet

intern

offentlig

Rekkefølgen på den listen er tilsiktet; mengden av tilgangs øker etter hvert som vi går ned på listen. Her er en rask gjennomgang av tilgangstyper:

privat er den minst tilgjengelige. bare
objekt som vil kunne få tilgang til en privat eiendom eller metode er den som eier den. For eksempel, de to egenskapene Button101, etikett og BGD, er privat, og så den eneste objekt som kan arbeide med disse elementene er Button101 eksempel selv. Merk enn selv to forekomster av samme klasse har gjensidig eksklusiv tilgang til sine egne private eiendommer; knappen kan få tilgang til sin label eiendom, men det får ikke tilgang knappen2 plateselskap eiendom, og vice versa.

beskyttet er svært lik private, bare at det gjør noen underklasse å også få tilgang til eiendommen eller metode. Så hvis vi opprettet en underklasse av Button101, som underklasse vil ikke
kunne få tilgang på etiketten eller BGD egenskaper (fordi de er private), men kan Kjøre annen eiendom som ble definert som beskyttet.

intern utvider tilgjengelighet litt mer. Det gir tilgang til andre objekter som er i den samme pakken som klassen. Denne er brukt langt mindre enn de andre og bare virkelig er fornuftig når du forstår pakker, så vi vil ikke borti denne. Vær imidlertid oppmerksom på er at intern standard tilgangs hvis du glemmer å spesifisere (ikke spør meg hvorfor).

offentlige er den mest tilgjengelige. I utgangspunktet kan en hvilken som helst objekt tilgang til eiendommen eller metode. Hvis et annet objekt har tilgang til en Button101 objekt, så det kan ringe setLabel () -metoden.

Actionscript 3 vil håndheve disse reglene. Hvis du gjør en eiendom privat og deretter prøve å få tilgang til det fra en underklasse, da kompilatoren vil klage, og du får en feilmelding. Tanken er at du setter reglene ned som du lage din klasse ("dette burde være tilgjengelig, det bør ikke") og så må du holde deg til dem



Trinn 12:. Lag en privat _url eiendom

I Button101, erklærer en tredje eiendom, _url, for å holde en URL-strengen
privat Var _url. String;

Hva er det med understrek? Dette er en konvensjon som jeg har blitt glatter over før vi har hatt en diskusjon om tilgangs modifikatorer. Det er ikke nødvendig, men det er ganske vanlig å erklære private og beskyttet eiendommer med navn som begynner med understrek. En del av dette har å gjøre med konvensjonen, en del å gjøre med å være i stand til å kjenne igjen på et øyeblikk et objekt eiendom versus en lokal funksjon variabel (husk omfang?), Og mye å gjøre med temaet for neste trinn. Anmeldelser

Jeg vil råde deg til å lese opp på denne Quick Tips om hvordan du velger et tilgangs modifier for dine egenskaper og metoder. I et nøtteskall, skjønt, er den viktigste takeaway å alltid erklære egenskaper som privat eller muligens beskyttet, slik som å sørge for at de ikke blir endret uten objektets godkjenning. Men vi trenger fortsatt en måte å få tilgang til data, og det er her settere og getters kommer i



Trinn 13:. Settere og Getters

OK, så du har en privat eiendom, og du ønsker å gjøre det offentlig. Du kan bare endre "privat" til "offentlig" og bli ferdig med det, bortsett fra at du husker noen crotchety tutorial forfatteren forteller deg å aldri gjøre det. Hva gjør du? Du bruker settere og /eller getters.

settere og getters er, enkelt sagt, metoder som enten setter verdien av noen eiendom, eller få verdien av enkelte eiendom. Det finnes to typer fuglehunden /getter metoder for å huske på:. implisitt Hotell og eksplisitt

Explicit settere /getters er det du sannsynligvis allerede tenker de er : vanlige gamle metoder. Gitt en privat eiendom "_url" av typen String, kanskje en setter se slik ut:
offentlig funksjon setUrl (theUrl: String): void {_url = theUrl;}

Og en getter kan se slik ut:
offentlig funksjon getUrl (): String {return _url;}

Merk at fuglehunden får en eneste parameter av samme type som eiendommen, setter bare eiendommens verdi til at inngangsverdi, og returnerer ingenting. Eiendommen ligger, og det er det

Tilsvarende getter gjør en eneste ting:.. Det returnerer verdien holdt av eiendommen, og tar ingen argumenter

For å bruke disse, du ' d bare ringe dem som enhver annen metode. Hvis vi hadde en forekomst av dette objektet i den variable knappen vi kunne gjøre dette:
button.setUrl ("http://active.tutsplus.com/"); trace (button.getUrl ()); //spor 'http://active.tutsplus.com'

Og det bør ikke være en overraskelse. Så hvorfor skal jeg inn så mange detaljer om dette emnet? På grunn av de implisitte
settere /getters.

De fleste OOP språk råd til denne muligheten, og Actionscript 3 gjør det med settet og få søkeord. Dette er ekstra modifikatorer du plasserer i din metode erklæring som gjør disse metode implisitte settere og getters. Vi skal få til hva det betyr i et sekund, men for nå, legg dette setter til Button101 Klasse:
offentlig funksjon sette url (theUrl: String): void {_url = theUrl;}

Legg merke til det ser ut pen darn nær den forrige setter, bare ordet "set" er ute av seg selv, mellom ordet "funksjon" og navnet på funksjonen. Dette er en subtil detalj; ordet "set" er ikke anbefale en del av funksjonsnavnet. Det er en ekstra søkeord som slår en metode til en implisitt setter. Ellers skjønt, det er formålet bør være opplagt

Deretter legger denne getter:
offentlig funksjon får url (). String {return _url;}

Igjen, det er nesten identisk med den forrige getter , bare med "få" søkeord i mellom "funksjonen" søkeord og funksjonsnavnet (hvis du har lagt den forrige eksplisitte eksempler, kan du fjerne dem for å unngå forvirring).

Nå, her hvor ting blir interessant. Tilbake i document, la oss sette url, og så får vi spore det med en gang til (a) sørge for at det fungerte, og (b) se hva du bruker en implisitt getter ser ut.

På slutten av konstruktøren, etter at begge knappene har blitt opprettet, legge til følgende linjer:
button.url = "http://active.tutsplus.com/";button2.url = "http://www.google.com/search?q=actionscript+3+tutorials";trace(button.url);trace(button2.url);

That's en signifikant forskjell; det ser ut som du jobber med en eiendom, ikke en metode! Det er den magiske implisitte settere og getters. De tar en metode og at det ser ut som en eiendom. Arbeide med det er akkurat som å sette eller få eiendommen, men inne i klassen vi har en funksjon.

Nå, hvorfor gå til dette problemer? Det er naturligvis noen tvingende grunner, noen av dem vil vi utforske i de neste trinnene som vi legger til flere settere og getters



Step. 14: Få URL
< p> La oss gå tilbake til det opprinnelige problemet med å vite hva de skal gjøre når en knapp klikkes. Tidligere nevnte jeg at kunne gå i dokumentet klassen; la oss gjøre det en realitet

I DocumentClass.as, oppdatere onButtonClick () -metoden for å se slik ut:.
privat funksjon onButtonClick (e: MouseEvent): void {navigateToURL (ny URLRequest (e.target .url));}

Og i konstruktøren, Kontroller at nettadressen eiendommene er satt på begge knappene, men gå videre og fjerne spor:
button.url = "http://active.tutsplus.com /";button2.url = "http://www.google.com/search?q=actionscript+3+tutorials";//trace(button.url);//trace(button2.url);

Finally, må du legge til følgende import linje i begynnelsen.
import flash.net *;

For referanse, den fullstendige document skal se slik ut:
pakke {import flash.display. MovieClip; import flash.text.TextField; import flash.events.MouseEvent; import flash.net. *; public class document strekker MovieClip {private Var tf: Textfield; private Var knapp: Button101; private Var knappen2: Button101; offentlig funksjon document () {tf = new Textfield (); addChild (tf); tf.text = "Hello World"; knappen = new Button101 (); button.x = 10; button.y = 200; button.setLabel ("Button 1"); button.url = "http://active.tutsplus.com/"; addChild (knapp); button.addEventListener (MouseEvent.CLICK, onButtonClick); knappen2 = new Button101 (); button2.x = 220; button2.y = 200; button2.setLabel ("Knapp 2"); button2.url = "http://www.google.com/search?q=actionscript+3+tutorials"; addChild (knappen2); button2.addEventListener (MouseEvent.CLICK, onButtonClick); } Private funksjon onButtonClick (e: MouseEvent): void {navigateToURL (ny URLRequest (e.target.url)); }}}

Og bare for å være sikker, her er den komplette Button101 Klasse:
pakke {import flash.display.Shape; import flash.display.Sprite; import flash.events.MouseEvent; import flash.text.TextField; import flash.text.TextFormat; public class Button101 strekker Sprite {private Var BGD: Shape; private Var labelField: Textfield; private Var _url: String; offentlig funksjon Button101 () {BGD = new Shape (); bgd.graphics.beginFill (0x999999, 1); bgd.graphics.drawRect (0, 0, 200, 50); addChild (BGD); labelField = new Textfield (); labelField.width = 200; labelField.height = 30; labelField.y = 15; Var format: tekstformat = new tekstformat (); format.align = "center"; format.size = 14; format.font = "Verdana"; labelField.defaultTextFormat = format; addChild (labelField); addEventListener (MouseEvent.ROLL_OVER, onOver); addEventListener (MouseEvent.ROLL_OUT, onOut); mouseChildren = false; buttonMode = true; } Offentlig funksjon setLabel (label: String): void {labelField.text = label; } Private funksjon onOver (e: MouseEvent): void {bgd.alpha = 0,8; } Private funksjon onOut (e: MouseEvent): void {bgd.alpha = 1; } Offentlig funksjon sett url (theUrl: String): void {if (theUrl.indexOf ("http: //") == -1) {theUrl = "http: //" + theUrl; } _url = TheUrl; } Offentlig funksjon get url (): String {return _url; }}}

Gå videre og prøve den ut. Ved å klikke på knappene vil ta deg til en av to nettsidene



Trinn 15:. Stille og Komme Label

En annen grunn til å rulle med settere og getters er evnen til å gjøre en komplisert oppgave enkel å utføre. For eksempel, la oss legge muligheten til å oppdatere etiketten med en setter. Vi har faktisk allerede gjorde dette i forrige tutorial, men vi fikk ikke bruke begrepet setter. Vi vil oppdatere eksisterende setter å være implisitt og legge en getter

I Button101, vil du se denne metoden.
Offentlig funksjon setLabel (label: String): void {labelField.text = etikett;}

Fjern det, og legge til denne:
offentlig funksjon sett etiketten (tekst: String): void {labelField.text = tekst;} offentlig funksjon get etikett (): String {return labelField.text;} < p> Dette lar oss, fra andre steder i programmet, arbeide med en "label eiendom" som bare setter etiketten teksten på knappen. Hva som egentlig skjer bak kulissene, men er litt mer komplisert; du trenger å jobbe med en Textfield og en String, ikke bare en String.

Dette er innkapsling igjen. Du tenker kanskje, "hvorfor ikke bare gjøre det labelField eiendom offentlig - eller, OK, lage en setter og getter for labelField - og så gjøre noe sånt button.labelField.text =" Knapp 1
<"?" p> Det ville sikkert fungere, men vil du virkelig trenger å eksponere labelField til resten av verden? Forutsatt at den generelle stilen på knappen er satt i stein, det er egentlig ingen grunn til å jobbe med det Textfield utenfor Button101 klassen, bortsett fra å sette etiketten teksten. Utsette labelField ville tillate et annet objekt for å ikke bare sette teksten, men også stilling, rotere, stil, eller til og med skjule etiketten. Dette er sannsynligvis ikke ønskelig; selv om du er en god borger, og ville ikke med vilje skrive kode som gjør det, er det bedre å beskytte deg mot tilfeldige endringer. La kompilatoren advare deg hvis prøvde et stunt som det, i motsetning til å la programmet kjøre og ha etiketten på mystisk rotert

I document, sørg for å endre linjene som kaller setLabel å merke =.
button.label = "Active Tuts"; button2.label = "Søk";



Trinn 16: Justering av bredde og høyde med Styrer

Vi vil undersøke et annet argument i favør av setter. Vi ønsker kanskje å justere bredden eller høyden på knappen. Siden knappen klassen strekker MovieClip, har det allerede bredde og høyde egenskaper, noe som er nyttig, bortsett fra det er ikke helt det vi ønsker. Sjekk ut hva som skjer hvis vi setter det:

Listen SWF var et resultat av å sette høyden eiendom venstre knapp objekt til 100. Hvis du ønsker å prøve dette selv, bare legge til følgende linje på slutten av konstruktøren av document:
button.height = 100;

Nå, dette er ikke forferdelig, men jeg vil hevde at det er uønsket. Det skjer fordi dette er standard virkemåte for skalering movieclips (og alle DisplayObjects, faktisk, siden høyden er definert i Displayobject). Det er bare en lineær strekking av kunstverk som finnes, tekstfelt inkludert. Teksten i hvert fall ikke blir forvrengt, men størrelsen er urovekkende.

Vi kan lage vår egen metode for å angi bredden, slik som offentlig funksjon setWidth (), men det er en enda bedre måte. Vi kan overstyring
oppførselen til en metode som er definert i en superklasse. Vi kan, som en underklasse, faktisk finjustere funksjonaliteten til våre behov ved å endre definisjonen av hva en eksisterende metode gjør. Det ser ut som dette:
styre offentlig funksjon sett bredden (w: Number): {. //Custom kode her} void styre offentlig funksjon satt høyde (h: Number): {. //Custom kode her} void

Det er en standard metode erklæring, bortsett fra med en ekstra søkeord på forsiden: overstyring. Legg merke til at rekkefølgen på "offentlig" og "overstyring" er faktisk utskiftbare, men de fleste code Jeg har sett en tendens til å sette "overstyring" ordet først. Det spiller ingen rolle, men det er lurt å velge en standard for deg selv (eller et selskap) og feste med det.

La oss legge til noen funksjonalitet. Husk at vi er helt erstatte eksisterende sett bredde metode, så vi må sørge for at vi dekker alle baser. Som det viser seg, er det ganske enkelt. I stedet for å strekke hoved MovieClip container, og alle barna i det som standard, vil vi faktisk strekke hvert av barna individuelt. Det er nesten rart at det fungerer, men det gjør:
styre offentlig funksjon sett bredden (w: Number): void {labelField.width = w; bgd.width = w;} overstyre offentlig funksjon satt høyde (h: Number): void {labelField.height = h; labelField.y = (h - labelField.textHeight) /2 - 3 bgd.height = h;}

Ved å sette bredden og høyden på tekstfeltet eksplisitt, unngår vi den keitete tekst skalering. Vi kan også legge inn en linje av logikk å omplassere etiketten Textfield slik at den forblir vertikalt sentrert

Legg merke til at vi er ikke anbefale å skrive en getter.; atferden defineres av Displayobject er helt fint, og det er ingen grunn til å overstyre den.

For å prøve det ut, rett og slett legge til (eller beholde) linjen som setter knappen høyde til 100 piksler i document.

Det finnes en rekke andre grunner til at du ønsker å begynne å bruke settere og getters. Jeg har listet opp fem av dem her



Trinn 17:. Justere Bredde
automatisk

Et siste element på fuglehunden teknikk. Her er målet: å gjøre knappen utvide automatisk i bredden hvis etiketten er for lang. Så, hvis du setter etiketten til "Button 1", det er rikelig med plass, og teksten er pent sentrert. Men hvis du skulle sette etiketten til "Trykk på denne knappen for å hacke Gibson," det ville bli for lang, og teksten vil bli avkortet.

Denne typen atferd er ganske enkelt å administrere med bruk av en setter. Når du setter teksten på etiketten, kan du også gjøre litt etterbehandling på tekstfeltet og bakgrunn for å sørge for at de er dimensjonert riktig. Omarbeide etiketten setter slik at det ser slik ut:
offentlig funksjon sett etiketten (tekst: String): void {labelField.text = tekst; Var autoWidth: Number = Math.max (200, labelField.textWidth + 40); this.width = autoWidth;}

Logikken er relativt grei, men her er en oversikt i tilfelle du ikke har gjort denne typen ting før. Først regne vi ut hva bredden bør være. Som bruker Math.max () -funksjonen, kan vi passere i to tallene og få høyere en tilbake. En av disse tallene er 200, som jeg definerer som vår minimum bredde. Det andre tallet er bredden på teksten i tekstfeltet, pluss en 40 pixel margin (20 piksler på hver side).