Svar till tentamen i DD1385 2020-01-10

1)    A: Iterator   B: Facade   C: Proxy    D: Template Method   E: Decorator


2)  Se pdf med UML-diagram, filen UML-200110.pdf finns bredvid.


3)
a) Composite

b) super(d); är ett anrop av superklassens (dvs Deps) konstruktor.

c) private innebär att variabeln endast är åtkomlig i den klass där den definieras och inte i subklasser. I detta exempel används variabeln data i en subklass vilket inte kommer att fungera när den är private .


4)   
Antag att objekten i myList tillhör klassen A. Klassen A måste implementera interfacet Comparable eller ännu hellre Comparable<A>. Klassen måste ha en metod (som man skriver själv) som anger ordningen mellan två A-objekt genom att returnera ett heltal som är negativt, noll (vid likhet) eller positivt.
    class A implements Comparable<A>{
        public int compareTo(A other) {
            // returnerar heltal beroende på
            // ordningen mellan this och other
        }
    }
  


5)
Alla Java-klasser ärver från klassen Object utan att det anges explicit. En av metoderna som ärvs är equals(). Anrop görs t.ex. med p.equals(q) som ger true om p och q är lika enligt aktuell definition av equals(). Om en klass har en naturlig ordning, dvs implementerar Comparable, så är det nödvändigt att se till att equals() och compareTo() är konsistenta, dvs när x.compareTo(y) ger heltalsvärdet 0 så måste x.equals(y) ge true (och om compareTo() ger ett tal som är skilt från 0 så ska equals() ge false). Basdefinitionen av equals() ger true endast för samma objekt (p==q) och detta är vanligen inte konsistent med compareTo().


6)
a)  GÅR EJ att kompilera då RoundedShape är en abstrakt klass och sådana kan inte instansieras. Typmässigt stämmer det, typen Shape får referera till objekt av typ RoundedShape.

b)  GÅR att kompilera då Shape är ovanför Circle i klasshierarkin och Circle kan instansieras.

c)  GÅR EJ att kompiera då Ellipse inte är ovanför Circle i hierarkin, de är på samma nivå med en gemensam superklass RoundedShape.


7)
Variabeln name är en instansvariabel i klassen Hello och existerar bara om man skapat objekt av klassen Hello, vilket inte har skett här. name är alltså inte tillgänglig i den statiska metoden main. Två enkla lösningar är (1) att deklararera name som statisk, dvs skriva static String name; högst upp i Hello eller (2) att flytta deklarationen av name och lägga den först i metoden main. Då blir name en lokal variabel i metoden istället för en instansvariabel i klassen.


8)
Det finns åtta primitiva typer i Java int,long,short,byte,float,double,char,boolean.
Referenstyper är alla klasser, interface och arrayer. Några exempel på referenstyper är String, Object, JButton, Integer, int[], Double[][], Comparable. Data av primitiv typ lagras direkt i det minnesutrymme som reserverats för dem medan för referenstyper lagras en referens till objektet i motsvarande minnesutrymme för variabeln.
Till varje primitiv typ hör en omslagsklass. Dessa behövs för att kunna representera datat av primitiv typ som ett objekt, t.ex. om man vill använda bibliotekens metoder för objektsamlingar på primitiva datatyper. Typen int har omslagsklassen Integer och double har omslagsklassen Double. Omslagsklassernas namn börjar alltid på stor bokstav och namnet är mycket likt motsvarande namn på primitiv typ.


9)   Rätta svar är B och C.


10)
a)  En fabriksmetod måste vara static.

b) För att omöjliggöra instansiering av klassen Person, gör den abstrakt, dvs inled klassen med public abstract class Person. Att ge klassen en privat konstruktor räcker inte för att göra instansiering helt omöjlig. Vid privat konstruktor kan ju instansiering ske inuti klassen.

c) Det viktiga här är att klassen får en privat konstruktor.

      class Human {
          private Human () {}

          // Objekt av Human kan skapas här med new Human()
          // new Human() fungerar inte utanför klassen Human
      }
      


11)
a)    Objektet som refereras med cObject ska vara av typen Comparator, helst med en typparameter, Comparator<T>, där T anger typen av objekt i listan som ska sorteras. Comparator är ett interface med en enda metod compare(obj1,obj2), där två objekt jämförs och ett heltal returneras. Heltalet anger ordningen mellan elementen enligt samma princip som för metoden compareTo() i interfacet Comparable. Klassen för cObject kan se ut så här. Antag att objekten i listan är av typen A.
    class CompareA implements Comparator<A> {
        public int compare(A obj1, A obj2) {
            // om obj1 och obj2 är lika så returneras 0
            // om obj1 kommer före obj2 returneras heltal < 0
	    // om obj1 kommer efter obj2 returneras heltal > 0
        }
    }
b)   Mönstret är Strategy


12)   
class B extends A implements Runnable {

    B (int start, int max) {
        super(start,max);
        new Thread(this).start();
    }

    public static void main (String[] u) { 
        new B(1013,1020);
        new B(1,8);
    }
}
Några kommentarer:
Eftersom klass B ska ärva från A så kan den inte också ärva från Thread, därför måste Runnable användas för att få klassen att fungera som en tråd.

Tråden ska starta då objekt av B skapas, därför måste starten ske i konstruktorn till B. Det går förstås bra att först skapa trådobjektet i en sats och därefter starta tråden:

	  Thread t = new Thread(this);
	  t.start(); 
	

main behöver inte vara med i tentalösningen.


13)

a)   Se pdf-dokument här bredvid. Det finns väldigt många metoder i klassen Observable. Dessa har inte tagits med i diagrammet. Metoden update() är med därför att det är helt nödvändigt för mönstret att den skrivs i de klasser som implementerar interfacet Observer.

b)   Metoden update() definieras i interfacet Observer, det interface som ska implementeras av de klasser vars objekt ska agera som just Observers i mönstret. Metoden ska ges konkret definition i implementerande klasser och innehålla den uppdatering av ett Observerobjekt som ska göras då subjektet (Observable i Java) ändras. I detta exempel är det TableView, QHistory och SoundAlert som är Observer-klasser och ska ha update().

c)   Anropet av update() görs i klassen Observable som är en klass i Java-API:n. Där finns metoden notifyObservers() som ser ut ungefär så här. Listan med observers administreras av biblioteksklassen Observable. Andvändaren anropar notifyObservers().

    public void notifyObservers(() {
      for (Observer obs : listOfObservers)
        obs.update();
    }
  
I Java-API:n har update() två parametrar och notifyObservers har en parameter. Dessa krävs inte i tentalösningen.