You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 5 Next »

Det meste er likt, men forskjellig...

Det meste av det du kan om programmering med Python er nyttig når du skal lære Java. F.eks. har Java også variabler, tall- og tekstverdier, funksjoner (kalles metoder i Java), og kontrollstrukturer (nøkkelord som styrer programmet) som if, while og for. Samtidig er veldig mange av detaljene i et Java-program forskjellig fra et tilsvarende Python-program. F.eks. så bruker Python : (kolon) etter if og else og innrykk i hver gren, mens Java bruker ( ) rundt if-betingelsen og { } rundt koden i hver gren (hvis en trenger mer enn én setning) og innrykket spiller ingen rolle. Det er også noen mer vesentlige forskjeller, som at Java krever at en deklarerer variabler og hvilken type verdi de kan ha, før de brukes, og generelt har strengere regler for hva slags kode som kan være hvor i en programfil.

Vi skal her gå gjennom de viktigste forskjellene, med utgangspunkt i Python-leksjonen om koding av tekst. Dersom du ikke husker hva det dreide seg om så finner du hele denne leksjonen her: lesson03.pdf

Fra Python til Java

Versjon 1
alphabet = "abcdefghijklmnopqrstuvwxyz"

def encode(letter, secret):
    pos = alphabet.find(letter)
    newpos = (pos + secret)
    if newpos >= 26:
        newpos = newpos - 26
    return alphabet[newpos]

def decode(letter, secret):
    pos = alphabet.find(letter)
    newpos = (pos - secret)
    if newpos < 0:
        newpos = newpos + 26
    return alphabet[newpos]

secret = 17
message = "hello world"
output = ""
for character in message:
    if character in alphabet:
        output = output + encode(character, secret)
    else:
        output = output + character
    print(output)

secret = 17
message = "yvccf nficu"
output = ""
for character in message:
    if character in alphabet:
        output = output + decode(character, secret)
    else:
        output = output + character
    print(output)
Versjon 2
# alphabet-variablen ligger utenfor funksjonene,
# slik at den kan brukes av dem alle
alphabet = "abcdefghijklmnopqrstuvwxyz"

def encode(letter, secret):
    pos = alphabet.find(letter)
    newpos = (pos + secret)
    if newpos >= 26:
        newpos = newpos - 26
    return alphabet[newpos]

def decode(letter, secret):
    pos = alphabet.find(letter)
    newpos = (pos - secret)
    if newpos < 0:
        newpos = newpos + 26
    return alphabet[newpos]

# run()-funksjonen samler koden som tidligere lå utenfor funksjonene
def run():
    message = "hello world"
    secret= 17
    output = ""
    for character in message:
        if character in alphabet:
            output = output + encode(character, secret)
        else:
            output = output + character
        print(output)
    message = "yvccf nficu"
    output = ""
    for character in message:
        if character in alphabet:
            output = output + decode(character, secret)
        else:
            output = output + character
        print(output)

# her kalles samlefunksjonen, som vi vil kalle "hovedprogramfunksjonen"
run()

For å gjøre det litt lettere å "oversette" Python-koden til Java, så gjør vi først en liten omstrukturering av Python-koden. Versjon 1 over til venstre er originalkoden fra pdf-filen, mens vi i versjon 2 har samlet (det meste av) koden som ikke allerede er inni en funksjon, i en run()-funksjon. Den eneste koden utenfor funksjonene er 1) variabler som er greit at alle funksjonene bruker og 2) et kall til "hovedprogrammetoden", dvs. funksjonen vi samlet vi samlet koden i.

Under til venstre er Java-versjonen av samme program. Til høyre går vi gjennom de viktigste forskjellene mellom Python og Java, omtrent slik de dukker opp i kode-eksemplet.

Java-versjon
package trinn1;

class EncodeDecode {
    String alphabet = "abcdefghijklmnopqrstuvwxyz";
    char encode(char letter, int secret) {
        int pos = alphabet.indexOf(letter);
        int newpos = (pos + secret);
        if (newpos >= 26) {
            newpos = newpos - 26;
        }
        return alphabet.charAt(newpos);
    }
    
    char decode(char letter, int secret) {
        int pos = alphabet.indexOf(letter);
        int newpos = (pos - secret);
        if (newpos < 0) {
            newpos = newpos + 26;
        }
        return alphabet.charAt(newpos);
    }
    void run() {
        String message = "hello world";
        int secret = 17;
        String output = "";
        for (int i = 0; i < message.length(); i++) {
            char character = message.charAt(i);
            if (alphabet.indexOf(character) >= 0)
                output = output + encode(character, secret);
            else
                output = output + character;
            System.out.println(output);
        }
        message = "yvccf nficu";
        output = "";
        for (int i = 0; i < message.length(); i++) {
            char character = message.charAt(i);
            if (alphabet.indexOf(character) >= 0)
                output = output + decode(character, secret);
            else
                output = output + character;
            System.out.println(output);
        }
    }
    
    public static void main(String[] args) {
        new EncodeDecode().run();
    }
}
Klasser og navngiving

All kode i et Java-program ligger i såkalte klasser, altså inni en class-blokk. Klasser må ha et navn, og her har vi valgt EnodeDecode. I tillegg ligger klasser gjerne i en slags mapper som kalles pakke, og den angis med package-nøkkelordet. Her har vi valgt pakkenavnet trinn1. Sammen utgjør pakke- og klassenavnet det fulle navnet til klassen, som her er trinn1.EncodeDecode.

Typer må deklareres

Java krever at alle variabler deklareres (og gjerne initialiseres) før de brukes. Når vi her skriver String alphabet, så betyr det variablen alphabet bare kan ha verdier som er av type String. Her intialiseres samtidig alphabet til en bestemt String bestående av alle bokstaver i (det engelske) alfabetet. Fordelen med å angi typen er at Java kan sjekke at vi bare gjør lovlige ting med variablen. F.eks. kan vi finne lengden til den ved å skrive alphabet.length(), men vi kan ikke dele den med 2 som i alphabet / 2.

Bruk av semikolon

Variabel-deklarasjonen avsluttes med ; (semikolon), og dette er typisk for Java, hvor nesten alle setninger avsluttes med semikolon. Sammen med kravet om typer overalt, er dette det som irriterer Python-programmerere mest, fordi det virker så unødvendig og er så lett å glemme.

Metoder

Funksjoner kalles metoder i Java, og som med variabler, så må en deklarere hva slags type verdi den returnerer ("regner ut") og hvilke typer parametrene har. Vi ser at encode-metoden tar inn en char, som er typen for tegn, og en int, som er typen for heltall, og returnerer en char. Igjen er poenget at når typene er angitt slik, så kan Java sjekke at vi ikke prøver å kalle encode med gale (typer) verdier og at vi ikke prøver å bruke resultatet feil. Denne sjekken kan gjøres mens vi skriver koden, altså lange før den kjøres, og tanken er at selv om det blir litt mer å tenke på og skrive, så sparer en tid ved å unngå feil.

Kodeblokker og { }

Mens en i Python bruker : og innrykk for å angi koden som hører til inni funksjoner (også i if og for), så bruker en i Java { } (kalt krøllparenteser) rundt koden. Hvis det blir rot med krøllparentesene så blir Java fort forvirret, så det må en være nøye med. Java bryr seg ikke om innrykk, men det er viktig for å gjøre koden mer lettlest for oss, og de fleste Java-editorer ordner det for oss, basert på krøllparentesene.

Kalle metoder med dott-notasjonen

Som i Python, så bruker Java . (punktum eller dott) for å kalle funksjoner på en verdi.

String-metoder

alphabet.indexOf(letter) finner posisjonen til letter i alphabet og gjør i praksis det samme som alphabet.find(letter) i Python. Dette er egentlig nokså typisk: Python og Java har mange av de samme funksjonene, men har valgt forskjellig navn. Når indexOf-metoden kan kalles på denne måten, så er det fordi String-typen på en måte har metoden "inni" seg. En sier gjerne at en "ber" String utføre metoden. Her er noen andre nyttige String-metoder:

  • charAt(pos)charAt returnerer tegnet på posisjonen angitt av argumentet, som må være et heltall. Denne metoden brukes i return-setningen til både encode og decode.
  • , mens length returnerer lengden (antall tegn i String-en).
Prosedyrer og void-typen

Hensikten med run-metoden er å skrive ut informasjon, ikke å beregne en verdi. Den kalles derfor en prosedyre, og da bruker en void som retur-type. Dette er typisk for slike hovedprogram-metoder.

  
  • No labels