CodeGym/Java-blogg/Tilfeldig/Prinsipper for OOP
John Squirrels
Nivå
San Francisco

Prinsipper for OOP

Publisert i gruppen
Java er et objektorientert språk. Dette betyr at du må skrive Java-programmer ved hjelp av et objektorientert paradigme. Og dette paradigmet innebærer bruk av objekter og klasser i programmene dine. La oss prøve å bruke eksempler for å forstå hva klasser og objekter er, og hvordan man bruker grunnleggende OOP-prinsipper (abstraksjon, arv, polymorfisme og innkapsling) i praksis.

Hva er en gjenstand?

Verden vi lever i består av gjenstander. Når vi ser oss rundt, kan vi se at vi er omgitt av hus, trær, biler, møbler, servise og datamaskiner. Alle disse tingene er objekter, og hver av dem har et sett med spesifikke egenskaper, atferd og formål. Vi er vant til gjenstander, og vi bruker dem alltid til helt spesifikke formål. Hvis vi for eksempel trenger å komme oss på jobb, bruker vi bil. Hvis vi vil spise, bruker vi retter. Og hvis vi vil hvile, finner vi en komfortabel sofa. Mennesker er vant til å tenke i termer av objekter for å løse problemer i hverdagen. Dette er en grunn til at objekter brukes i programmering. Denne tilnærmingen kalles objektorientert programmering. La oss gi et eksempel. Tenk deg at du har utviklet en ny telefon og ønsker å starte masseproduksjon. Som utvikler av telefonen vet du hva den er til for, hvordan den fungerer, og hvilke deler den er (kropp, mikrofon, høyttaler, ledninger, knapper osv.). Dessuten er det bare du som vet hvordan du kobler sammen disse delene. Men du planlegger ikke å lage telefonene personlig - du har et helt team med arbeidere til å gjøre dette. For å eliminere behovet for gjentatte ganger å forklare hvordan du kobler sammen telefonens deler, og for å sikre at alle telefonene er laget på samme måte, før du begynner å produsere dem, må du lage en tegning som beskriver hvordan telefonen er organisert. I OOP kaller vi en slik beskrivelse, tegning, diagram eller mal for en klasse. Det danner grunnlaget for å lage objekter når programmet kjører. En klasse er en beskrivelse av objekter av en bestemt type - som en vanlig mal som består av felt, metoder og en konstruktør. Et objekt er en forekomst av en klasse.

Abstraksjon

La oss nå tenke på hvordan vi kan flytte fra et objekt i den virkelige verden til et objekt i et program. Vi bruker telefonen som eksempel. Dette kommunikasjonsmidlet har en historie som strekker seg over mer enn 100 år. Den moderne telefonen er en mye mer kompleks enhet enn forgjengeren fra 1800-tallet. Når du bruker telefonen, tenker vi ikke på dens organisasjon og prosessene som skjer inne i den. Vi bruker ganske enkelt funksjonene som tilbys av telefonens utviklere: knapper eller en berøringsskjerm for å taste inn et telefonnummer og ringe. Et av de første telefongrensesnittene var en sveiv som måtte roteres for å ringe. Dette var selvfølgelig ikke særlig praktisk. Men den fylte sin funksjon feilfritt. Hvis du sammenligner de mest moderne og de aller første telefonene, du kan umiddelbart identifisere de viktigste funksjonene for enheten fra slutten av 1800-tallet og for den moderne smarttelefonen. De er muligheten til å ringe og muligheten til å motta anrop. Det er faktisk dette som gjør telefonen til en telefon, og ikke noe annet. Nå har du bare brukt et OOP-prinsipp: identifiser et objekts viktigste egenskaper og informasjon. Dette prinsippet kalles abstraksjon. I OOP kan abstraksjon også defineres som en metode for å representere elementer i en oppgave i den virkelige verden som objekter i et program. Abstraksjon er alltid assosiert med generalisering av visse egenskaper til et objekt, så det viktigste er å skille meningsfull informasjon fra det ubetydelige i sammenheng med oppgaven. I tillegg kan det være flere nivåer av abstraksjon. La' Prøv å bruke abstraksjonsprinsippet på telefonene våre. Til å begynne med vil vi identifisere de vanligste typene telefoner - fra de aller første telefonene til de i dag. For eksempel kan vi representere dem i form av diagrammet i figur 1. Prinsipper for OOP - 2Ved å bruke abstraksjon kan vi nå identifisere den generelle informasjonen i dette objekthierarkiet: det generelle abstrakte objektet (telefon), vanlige kjennetegn ved telefonen (f.eks. år for dens opprettelse), og det vanlige grensesnittet (alle telefoner kan motta og foreta anrop). Slik ser det ut i Java:
public abstract class AbstractPhone {
    private int year;

    public AbstractPhone(int year) {
        this.year = year;
    }
    public abstract void call(int outgoingNumber);
    public abstract void ring(int incomingNumber);
}
I et program kan vi lage nye typer telefoner ved å bruke denne abstrakte klassen og bruke andre grunnleggende prinsipper for OOP, som vi skal utforske nedenfor.

Innkapsling

Med abstraksjon identifiserer vi hva som er felles for alle objekter. Men hver type telefon er unik, på en eller annen måte forskjellig fra de andre. Hvordan trekker vi grenser og identifiserer denne individualiteten i et program? Hvordan gjør vi det slik at ingen ved et uhell eller bevisst kan ødelegge telefonen vår eller prøve å konvertere en modell til en annen? I den virkelige verden er svaret åpenbart: du må legge alle delene i et telefondeksel. Tross alt, hvis du ikke gjør det - i stedet lar alle telefonens interne deler og tilkoblingsledninger ligge på utsiden - vil en nysgjerrig eksperimentator definitivt ønske å "forbedre" telefonen vår. For å forhindre slik fiksering, brukes prinsippet om innkapsling i et objekts design og drift. Dette prinsippet sier at et objekts attributter og oppførsel er kombinert i en enkelt klasse, objektet' s interne implementering er skjult for brukeren, og et offentlig grensesnitt er tilgjengelig for arbeid med objektet. Programmererens oppgave er å bestemme hvilke av et objekts attributter og metoder som skal være tilgjengelig for offentlig tilgang, og hvilke interne implementeringsdetaljer som skal være utilgjengelige.

Innkapsling og adgangskontroll

Anta at informasjon om en telefon (produksjonsåret eller produsentens logo) er gravert på baksiden når den lages. Informasjonen (dens tilstand) er spesifikk for denne modellen. Vi kan si at produsenten sørget for at denne informasjonen var uforanderlig - det er usannsynlig at noen ville tenke på å fjerne graveringen. I Java-verdenen beskriver en klasse tilstanden til fremtidige objekter ved hjelp av felt, og deres oppførsel beskrives ved hjelp av metoder. Tilgang til et objekts tilstand og oppførsel kontrolleres ved hjelp av modifikatorer som brukes på felt og metoder: privat, beskyttet, offentlig og standard. For eksempel bestemte vi at produksjonsåret, produsentens navn og en av metodene er interne implementeringsdetaljer for klassen og ikke kan endres av andre objekter i programmet. I koden,
public class SomePhone {

    private int year;
    private String company;
    public SomePhone(int year, String company) {
        this.year = year;
        this.company = company;
    }
private void openConnection(){
    // findSwitch
    // openNewConnection...
}
public void call() {
    openConnection();
    System.out.println("Calling");
}

public void ring() {
    System.out.println("Ring-ring");
}

 }
Den private modifikatoren tillater tilgang til klassens felt og metoder kun innenfor denne klassen. Dette betyr at det er umulig å få tilgang til private felt fra utsiden, fordi de private metodene ikke kan kalles. Å begrense tilgangen til openConnection- metoden gir oss også muligheten til fritt å endre metodens interne implementering, siden metoden garantert ikke blir brukt av eller avbryter arbeidet til andre objekter. For å jobbe med objektet vårt lar vi ringe- og ringemetodene være tilgjengelige ved å bruke den offentlige modifikatoren. Å tilby offentlige metoder for å jobbe med objekter er også en del av innkapsling, siden hvis tilgang ble nektet fullstendig, ville det blitt ubrukelig.

Arv

La oss ta en ny titt på diagrammet over telefoner. Du kan se at det er et hierarki der en modell har alle funksjonene til modellene plassert høyere langs grenen, og legger til noen av sine egne. En smarttelefon bruker for eksempel et mobilnettverk for kommunikasjon (har egenskapene til en mobiltelefon), er trådløs og bærbar (har egenskapene til en trådløs telefon), og kan motta og foreta anrop (har egenskapene til en telefon). Det vi har her er arv av objektegenskaper. I programmering betyr arv å bruke eksisterende klasser for å definere nye. La oss vurdere et eksempel på bruk av arv for å lage en smarttelefonklasse. Alle trådløse telefoner drives av oppladbare batterier, som har en viss batterilevetid. Følgelig legger vi denne egenskapen til den trådløse telefonklassen:
public abstract class CordlessPhone extends AbstractPhone {

    private int hour;

    public CordlessPhone (int year, int hour) {
        super(year);
        this.hour = hour;
    }
    }
Mobiltelefoner arver egenskapene til en trådløs telefon, og vi implementerer ringe- og ringemetodene i denne klassen:
public class CellPhone extends CordlessPhone {
    public CellPhone(int year, int hour) {
        super(year, hour);
    }

    @Override
    public void call(int outgoingNumber) {
        System.out.println("Calling " + outgoingNumber);
    }

    @Override
    public void ring(int incomingNumber) {
        System.out.println("Incoming call from " + incomingNumber);
    }
}
Og til slutt har vi smarttelefonklassen, som i motsetning til klassiske mobiltelefoner har et fullverdig operativsystem. Du kan utvide smarttelefonens funksjonalitet ved å legge til nye programmer som kan kjøres på operativsystemet. I kode kan klassen beskrives som følger:
public class Smartphone extends CellPhone {

    private String operationSystem;

    public Smartphone(int year, int hour, String operationSystem) {
        super(year, hour);
        this.operationSystem = operationSystem;
    }
public void install(String program) {
    System.out.println("Installing " + program + " for " + operationSystem);
}

}
Som du kan se har vi laget en del ny kode for å beskrive smarttelefonklassen , men vi har fått en ny klasse med ny funksjonalitet. Dette OOP-prinsippet gjør det mulig å redusere mengden Java-kode som kreves betydelig, og dermed gjøre livet enklere for programmereren.

Polymorfisme

Til tross for forskjeller i utseende og design på ulike typer telefoner, kan vi identifisere noen vanlig atferd: de kan alle motta og foreta anrop, og alle har et ganske klart og enkelt sett med kontroller. Når det gjelder programmering, lar abstraksjonsprinsippet (som vi allerede er kjent med) oss si at telefonobjekter har et felles grensesnitt. Det er derfor folk enkelt kan bruke forskjellige telefonmodeller som har de samme kontrollene (mekaniske knapper eller en berøringsskjerm), uten å fordype seg i de tekniske detaljene til enheten. Dermed bruker du en mobiltelefon konstant og du kan enkelt ringe fra din venns fasttelefon. Prinsippet til OOP som sier at et program kan bruke objekter med felles grensesnitt uten informasjon om objektets interne struktur kalles polymorfisme. La' Tenk deg at vi trenger programmet vårt for å beskrive en bruker som kan bruke hvilken som helst telefon til å ringe en annen bruker. Slik kan vi gjøre det:
public class User {
    private String name;

    public User(String name) {
        this.name = name;
            }

    public void callAnotherUser(int number, AbstractPhone phone){
// And here's polymorphism: using the AbstractPhone type in the code!
        phone.call(number);
    }
}
 }
Nå skal vi beskrive flere typer telefoner. En av de første telefonene:
public class ThomasEdisonPhone extends AbstractPhone {

public ThomasEdisonPhone(int year) {
    super(year);
}
    @Override
    public void call(int outgoingNumber) {
        System.out.println("Crank the handle");
        System.out.println("What number would you like to connect to?");
    }

    @Override
    public void ring(int incomingNumber) {
        System.out.println("The phone is ringing");
    }
}
En vanlig fasttelefon:
public class Phone extends AbstractPhone {

    public Phone(int year) {
        super(year);
    }

    @Override
    public void call(int outgoingNumber) {
        System.out.println("Calling " + outgoingNumber);
    }

    @Override
    public void ring(int incomingNumber) {
        System.out.println("The phone is ringing");
    }
}
Og til slutt, en kul videotelefon:
public class VideoPhone extends AbstractPhone {

    public VideoPhone(int year) {
        super(year);
    }
    @Override
    public void call(int outgoingNumber) {
        System.out.println("Connecting video call to " + outgoingNumber);
    }
    @Override
    public void ring(int incomingNumber) {
        System.out.println("Incoming video call from " + incomingNumber);
    }
  }
Vi lager objekter i main()- metoden og tester callAnotherUser()- metoden:
AbstractPhone firstPhone = new ThomasEdisonPhone(1879);
AbstractPhone phone = new Phone(1984);
AbstractPhone videoPhone=new VideoPhone(2018);
User user = new User("Jason");
user.callAnotherUser(224466, firstPhone);
// Crank the handle
// What number would you like to connect to?
user.callAnotherUser(224466, phone);
// Calling 224466
user.callAnotherUser(224466, videoPhone);
// Connecting video call to 224466
Å kalle den samme metoden på brukerobjektet gir forskjellige resultater. En spesifikk implementering av kallemetoden velges dynamisk inne i callAnotherUser()- metoden basert på den spesifikke typen objekt som sendes når programmet kjører. Dette er polymorfis viktigste fordel – muligheten til å velge en implementering under kjøring. I eksemplene på telefonklasser gitt ovenfor, brukte vi metodeoverstyring - et triks der vi endrer implementeringen av en metode definert i basisklassen uten å endre metodesignaturen. Dette erstatter i hovedsak metoden: den nye metoden definert i underklassen kalles når programmet kjøres. Vanligvis, når vi overstyrer en metode, vil @Overridemerknad brukes. Den ber kompilatoren sjekke signaturene til de overstyrte og overstyrende metodene. Til slutt, for å sikre at Java-programmene dine er i samsvar med prinsippene for OOP, følg disse tipsene:
  • identifisere et objekts hovedegenskaper;
  • identifisere vanlige egenskaper og atferd og bruke arv når du oppretter klasser;
  • bruke abstrakte typer for å beskrive objekter;
  • prøv å alltid skjule metoder og felt relatert til en klasses interne implementering.
Kommentarer
  • Populær
  • Ny
  • Gammel
Du må være pålogget for å legge igjen en kommentar
Denne siden har ingen kommentarer ennå