Arvutiteaduse instituut
  1. Kursused
  2. 2024/25 kevad
  3. Objektorienteeritud programmeerimine (LTAT.03.003)
EN
Logi sisse

Objektorienteeritud programmeerimine 2024/25 kevad

  • Kodutööd ja praktikumid
  • Loengud
  • Kursuse korraldus
  • IDE juhend
  • Süvendusrühm
  • Silumisest

Lisamaterjalid 6

Võtmesõna sealed

Javas saab teiste klasside omadusi pärida. Klassi pärimise täielikuks keelamiseks eksisteerib võtmesõna final. Samas võib tekkida olukord, kus mõned alamklassid on vajalikud. Sellises situatsioonis kasutatakse võtmesõna sealed, mis lubab alamklassideks ainult võtmesõna permits abil välja toodud klasse. Kõik sellised klassid peavad pärima sealed klassi ja asuma sellega samas moodulis ning on, kas final, sealed või non-sealed, mis tühistab ülemklassidelt tulenevad alamklasside pärimise piirangud. Kui sealed klass ja selle alamklassid asuvad samas failis, pole vaja lubatud klasse välja kirjutada. Võtmesõna sealed töötab ka liidestega.

Loome sealed liidese Taim abstraktse meetodiga kasva. Selle ainus lubatud alamklass on Puu, mis on omakorda sealed ja lubab alamklassideks Kask ja Tamm. Klassil Puu on isendiväljad kõrgus ja onHaige ning realiseeritud meetod kasva, mis lisab kõrgusele argumendiks antud arvu. Lisaks on defineeritud mõlema isendivälja get-meetodid ning klassi informatsiooni väljastamiseks toString.

sealed interface Taim permits Puu {
    void kasva(double juurdeKõrgus);
}

sealed class Puu implements Taim permits Kask, Tamm {
    private double kõrgus;
    private boolean onHaige;

    public Puu(double kõrgus) {
        this.kõrgus = kõrgus;
        this.onHaige = false;
    }

    @Override
    public void kasva(double juurdeKõrgus) {
        kõrgus += juurdeKõrgus;
    }

    public double getKõrgus() {
        return kõrgus;
    }

    public boolean getOnHaige() {
        return onHaige;
    }

    @Override
    public String toString() {
        if (onHaige) {
            return "Puu kõrgus on " + kõrgus + " m ja see on haige";
        }
        else {
            return "Puu kõrgus on " + kõrgus + " m ja see on terve";
        }
    }
}

Loome klassi Puu isendi puu:

Puu puu = new Puu(3);
System.out.println(puu);

Selle väljund:

Puu kõrgus on 3.0 m ja see on terve

Kasvatame puud nelja meetri võrra:

puu.kasva(4);
System.out.println(puu);

Väljund:

Puu kõrgus on 7.0 m ja see on terve

Klass Tamm, mis pärib klassi Puu on final ehk seda ei saa edasi pärida. Sellel on ülekaetud meetod toString, mis täpsustab, et tegemist on tammega. See kasutab tingimuslause lühemat vormi (ternary operator), mis on kujul: tingimus ? tõeneAvaldis : väärAvaldis.

final class Tamm extends Puu {
    public Tamm(double kõrgus) {
        super(kõrgus);
    }

    @Override
    public String toString() {
        return "Tamme kõrgus on " + getKõrgus() + " m ja on see " 
                + (getOnHaige() ? "haige" : "terve");
    }
}

Näide tammest:

Tamm tamm = new Tamm(10);
System.out.println(tamm);

Väljund:

Tamme kõrgus on 10.0 m ja on see terve

Suurendame tamme pikkust:

tamm.kasva(4);
System.out.println(tamm);

Väljund:

Tamme kõrgus on 14.0 m ja on see terve

Klass Tulp ei saa pärida Puu omadusi, sest Puu lubab enda pärijateks ainult klasse Kask ja Tamm. Selle loogika eiramine annab kompileerides veateate: class is not allowed to extend sealed class: Puu (as it is not listed in its 'permits' clause).

final class Tulp extends Puu { //keelatud
    public Tulp(double kõrgus) {
        super(kõrgus);
    }
}

Puu alamklass Kask on non-sealed ehk sellel pole edasi pärimise piiranguid. Seetõttu saab seda pärida klass Lamp, mis pole päriselus kuidagi taime, puu või kasega seotud. Klassil Kask on uus isendiväli lehtedeArv ja get-meetod getLehtedeArv, mida kasutab ka Lamp.

non-sealed class Kask extends Puu {
    private int lehtedeArv;

    public Kask(double kõrgus, int lehtedeArv) {
        super(kõrgus);
        this.lehtedeArv = lehtedeArv;
    }

    public int getLehtedeArv() {
        return lehtedeArv;
    }
}

class Lamp extends Kask {
    public Lamp(double kõrgus, int lehtedeArv) {
        super(kõrgus, lehtedeArv);
    }
}

Loome kase:

Kask kask = new Kask(20, 200000);
System.out.println(kask.getLehtedeArv());

Kase lehtede arv väljundis:

200000

Lambi isend ja lehtede arvu väljatrükk:

Lamp lamp = new Lamp(0.4, 0);
System.out.println(lamp.getLehtedeArv());

Lambi lehtede arv väljundis:

0

sealed liidese alamklass saab olla ka eelmise nädala lisamaterjalides käsitletud record:

sealed interface Värv {
    String getVärv();
}

record Kollane() implements Värv {
    @Override
    public String getVärv() {
        return "kollane";
    }
}

Loome uue isendi kollane ja väljastame selle värvi:

Kollane kollane = new Kollane();
System.out.println(kollane.getVärv());

Väljund:

kollane

Enesekontroll

  • Arvutiteaduse instituut
  • Loodus- ja täppisteaduste valdkond
  • Tartu Ülikool
Tehniliste probleemide või küsimuste korral kirjuta:

Kursuse sisu ja korralduslike küsimustega pöörduge kursuse korraldajate poole.
Õppematerjalide varalised autoriõigused kuuluvad Tartu Ülikoolile. Õppematerjalide kasutamine on lubatud autoriõiguse seaduses ettenähtud teose vaba kasutamise eesmärkidel ja tingimustel. Õppematerjalide kasutamisel on kasutaja kohustatud viitama õppematerjalide autorile.
Õppematerjalide kasutamine muudel eesmärkidel on lubatud ainult Tartu Ülikooli eelneval kirjalikul nõusolekul.
Courses’i keskkonna kasutustingimused