Kihagyás

6. elóadás

Fájlok írása

import java.io.*;
// ...

try( FileWriter out = new FileWriter(fname) ){
    out.write("Árvíztűrő tükörfúrógép", 0, 21);
}

Karakterkódolás megadás:

try ( OutputStreamWriter out = new OutputStreamWriter( new FileOutputStream(fname), "Cp1250" ) ){
    out.write("Amogustűrő ütvefúrósus");
}

Szövegfájlok olvasása

try( BufferedReader in = new BufferedReader( new InputStreamReader( new FileInputStream(fname), "Cp1250" ) ) ){
    String line;
    while( (line=in.readLine()) != null ){/*...*/}
}

Műveletek

Racionális számok

package numbers;
public class Rational{
    private int numerator, denominator;

    public Rational( int numerator, int denominator )    {
        if (denominator <= 0) throw new IllegalArgumentException();
        this.numerator = numerator;
        this.denominator = denominator;
    }
}

Getter-Setter

public class Rational{
    // ...
    public void setDenominator(int denominator){
        if (denominator <= 0) throw new IllegalArgumentException();
        this.denominator = denominator;
    }
    public int getDenominator(){return denominator;}
}

Tervezett használat

import numbers.Rational;
public class Main{
    public static void main(String[] args){
        Rational p = new Rational(1, 3);
        Rational q = new Rational(1, 2);
        p.multiplyWith(q);
        println(p);
        println(q);
    }

    private static void println( Rational r ){
        System.out.println(r.getNumerator() + "/" + r.getDenominator());
    }
}

Aritmetika

/**
 * Set {@code this} to {@code this} * {@code that}
 * @param that Non-null reference to another number.
 *             It will not be changed by this method
 * @throws NullPointerException When {@code that} is null
 */
public void multiplyWith(Rational that){
    this.numerator *= that.numerator;
    this.denominator *= that.denominator;
}

Műveletek sorozása

Ha a művelet végén visszaadjuk az objektumot, akkor lehet őket sorozni.

public Rational multiplyWith(Rational that){
    this.numerator *= that.numerator;
    this.denominator *= that.denominator;
    return this;
}

Használat:

p.multiplyWith(q).multiplyWith(q).multiplyWith(q)

Túlterhelés

Több metódus ugyanazzal a névvel

public Rational multiplyWith(Rational that){
    this.numerator *= that.numerator;
    this.denominator *= that.denominator;
    return this;
}

public Rational multiplyWith(int that){ // A metódus neve ugyanaz, de más a szignatúra. Ezt hívjuk túlterhelésnek
    this.numerator *= that;
    return this;
}

Használatra példa:

p.multiplyWith(q);
p.multiplyWith(2);

Mókás szabályok: "jobban illeszkedő"

static void m( long n ){...}
static void m( float n ){...}
public static void main(String[] args){
    m(3); // a 3 az int típusú, tehát se nem long, se nem float. What now? A long típusa "közelebb áll" az inthez, úgyhogy azt fogja használni.
    m(3L); // Egyértelműen long
    m(3.0f); // Egyértelműen float
}
static void m( long n, float m){...}
static void m( float n, long n){...}
public static void main(String[] args){
    m(4, 3); // Compile hiba. Nem lehet feloldani kétértelműséget
}

Több konstruktor ugyanabban az osztályban

public class Rational{
    public Rational(int numerator, int denominator){ /*... */}
    public Rational(int value){ /*... */}
}

Hibás túlterhelés példa

public class Rational {
    public void multiplyWith(Rational that) {/*...*/}
    public Rational multiplyWith(Rational that) {/*...*/}
}

Fordítási hiba: a visszatérési típus nem elég arra, hogy két metódust megkülönböztessen.

Alapértelmezett érték?

public class Rational {
    public void set(int numerator, int denominator) {/*...*/}
    public void set(int value){
        set(value, 1);
    }
    public void set(){
        set(0);
    }
}

Konstruktorok esetén

Konstruktorban meg lehet hívni egy másik konstruktort

public class Rational {
    public Rational(int numerator, int denominator) {/*...*/}
    public Rational(int value){
        this(value, 1); // a másik konstruktor meghívásának a legelső utasításnak kell lennie
    }
    public Rational(){
        this(0);
    }
}

The Expert


Konstruktorok helyett gyártóművek

public class Rational{
    public Rational(int numerator, int denominator){
        this.numerator = numerator;
        this.denominator = denominator;
    }

    public static Rational valueOf(int val){return Rational(val, 1);}
    public static Rational oneOver(int val){return Rational(1, val);}
    public static Rational zero(){return Rational(0, 1);}
}

Funkcionális OOP stílus

Metódusok, amelyek nem változtatják a belső állapotot

package numbers;
public class Rational{
    public Rational(...){...};
    public Rational times(Rational that){
        return new Rational(this.numerator*that.numerator, this.denominator*that.denominator);
    }
}

Sosem módosuló belső állapot

package numbers;
public class Rational{
    //`final`: csak constructorban lehet az értéket megadni
    private final int numerator, denominator;
    public Rational(int numerator, int denominator){
        this.numerator = numerator;
        this.denominator = denominator;
    }
    public int getNumerator(){return this.numerator};
    public int getDenominator(){return this.denominator};
    public Rational times(Rational that){...};
    public Rational plus(Rational that){...};

}

Globális konstans

public static final int WIDTH = 80;
  • Osztályszintű
  • Olyan, mint C-ben a #define, const

Módosíthatatlan lokális változó

public void simplify(){
    final int gcd = gcd(numerator, denominator);
    numerator /= gcd;
    denominator /= gcd;
}