Till KTH:s startsida Till KTH:s startsida

Extentor

Lärare Christian Smith skapade sidan 17 oktober 2013

Christian Smith flyttade sidan från Objektorienterad programkonstruktion (DD1346) 17 oktober 2013

kommenterade 18 mars 2014

I lösningsförslaget 6.c till tentan från 2012-03-13 står det

"Om (den icke-abstrakta) klassen A ärver från (den icke-abstrakta) klassen B , så kommer ett anrop av en argumentlös konstruktor i A alltid att anropa den argumentlösa konstruktorn i B. Sant"

Men det förutsätter väl att jag inte har deklarerat en argumentlös konstruktor till A i vilken jag anropar super med något argument?

T.ex. ger följande program utskiften "Konstruktor med argument i B":

public class A extends B {
    public A() {
        super(17);
    }
    public static void main(String[] args) {
        A a = new A();
    }
}

public class B {
    public B() {
         System.out.println("Argumentlös konstruktur i B");
    }
    public B(int myArg) {
        System.out.println("Konstruktor med argument i B");
    }
}

Är det något i formuleringen av frågan jag missar?

Lärare kommenterade 18 mars 2014

Du har rätt, strikt sett borde det förtydligats till:

"Om (den icke-abstrakta) klassen A ärver från (den icke-abstrakta) klassen B, så kommer ett anrop av en argumentlös konstruktor i A alltid att anropa den argumentlösa konstruktorn i B, om A:s argumentlösa konstruktor inte explicit anropar en annan konstruktor i B ."

Det här felet uppmärksammades när den kursomgången gick, och vi beslöt att tillåta båda svarsalternativen, även om det senare visade sig inte påverka tentabetyget för någon enda student. Tack för att du pekade ut det, jag ska uppdatera facitfilen för att undvika förvirring mitt i tentapluggandet.

kommenterade 19 mars 2014

Haha, härligt när ens fråga redan har ställts och besvarats!

Men jag undrar ändå, kan jag inte överskugga konstruktorn (eller vad man nu säger) typ enligt:

public class A extends B {

    int extraField aInt;
    public A() {
        this.aInt = 17;
    }
    public static void main(String[] args) {
        A a = new A();
    }
}

Det vill säga, explicit definiera en ny, argumentlös konstruktor i subklassen och undvika att anropa "super". Anropar detta ändå en argumentlös konstruktor i B, så att säga "innan" min int aInt sätts till 17?

kommenterade 19 mars 2014

Ja, det gör det. Det kallas constructor chaining och innebär att ingen av superklasserna kommer skapas utan att en konstruktor körs (det är ju ganska rimligt att få en chans att definera alla privata fält i min klass t.ex., även om någon skapar en instans av en underklass). Sista stycket här: http://docs.oracle.com/javase/tutorial/java/IandI/super.html beskriver lite mer vad som händer.

kommenterade 19 mars 2014

Aha!

Tackar :)

kommenterade 19 mars 2014

En fråga om 4c på 2012-06-11.
Om man tolkar frågan som att man går in i en try-catch är väl svaret sant?


"The finally block always executes when the try block exits. This ensures that the finally block is executed even if an unexpected exception occurs."


Eller ska man ta hänsyn till: "f the JVM exits while the try or catch code is being executed, then the finally block may not execute. Likewise, if the thread executing the try or catch code is interrupted or killed, the finally block may not execute even though the application as a whole continues."

Saxat från: http://docs.oracle.com/javase/tutorial/essential/exceptions/finally.html

kommenterade 19 mars 2014

I.o.m. att det står "alltid helt garanterad" så tycker jag att det är rimligt att man ska ta hänsyn till sådana saker. Det kan vara vettigt att vara medveten om att satser i finally inte helt nödvändigtvis körs, om man t.ex. gör nätverksprogrammering mellan klient och server och någon drar ut kontakten ur datorn mitt i ett meddelande kan det vara så att man ändå inte kan sluta snyggt, så man kan inte alltid räkna med det (kopplingen till en klient kan alltså brytas plötsligt om man ser det från serverns perspektiv). Tror det är den (måhända självklara) insikten som efterfrågas.

Lärare kommenterade 19 mars 2014

Just det, man är alltså inte garanterad att finally-blocket körs. Det är viktigt att vara medveten om det om man t.ex vill vara säker på att inte korrumpera logfiler, mm.