Göm menyn

TDDE10 Objektorienterad programmering i Java

FAQ för TDDE10/725G90

På den här sidan samlar vi ihop en del av frågorna vi får via mail, eventuellt även på föreläsning, samt svar på dem.

Abstrakta klasser: Hur bygger jag dem, och kan jag ha vanliga metoder i dem?

En abstrakt klass kan absolut ha konkreta metoder implementerade. Syftet med abstrakta metoder är att vi vill tvinga våra subklasser att själva implementera önskade metoder, där innehållet i metoden inte är gemensamt och således inte kan eller bör implementeras i basklassen.

Exempel:

      Animal.java:
      public abstract class Animal { 
          private String name;
      
          public Animal(String n) {
              name = n;
          }
            
          public void sayHello() { // Denna metod kommer att finnas för alla djur som ärver från Animal
              System.out.println("Hello, my name is " + name);
          }

          public String getName() { // Denna metod kommer att finnas för alla djur som ärver från Animal
              return name;
          }
       
          public abstract void showUniqueBehavior(); // Denna metod kommer alla klasser som ärver från Animal tvingas implementera.
      }

      Ferret.java:
      public class Ferret extends Animal {
          public Ferret(String n) {
              super(n);
          }
        
          @Override // Vi överskuggar metoden showUniqueBehavior från Animal
          public void showUniqueBehavior() { 
              System.out.println(getName() + " squeezes under a closed door and sneaks into the kitchen to steal packages of noodles.");
          }
      }
	
	

Om vi skulle glömma att överskugga den (eller de) abstrakta metoden (metoderna) får vi inte kompilera, och Eclipse kommer att säga att vi måste implementera de abstrakta metoderna för att få fortsätta. Vi kan alltså inte råka göra fel eller glömma bort något viktigt. Det finns så klart helt abstrakta klasser (klass med bara abstrakta metoder), men då brukar man inte kalla det klass utan interface.

ConcurrentModificationException. Vad är detta?

Ibland kan vi få problem om vi försöker ändra på en lista medan vi itererar över den.
Exempel:

	for (Item i : itemList) {
	    if (i.isBroken()) {  // Vi hittar elementet vi ska ta bort
                itemList.remove(i); // Vi står inne i loopen som itererar över listan, så vi får concurrent modification.
            }
        }
      
Självfallet kan vi ta bort saker från vår lista.
	Item toRemove;
	for (Item i : itemList) {
            if (i.isBroken()) {  // Vi hittar elementet vi ska ta bort
                toRemove = i; // Vi lagrar det vi ska ta bort
	        break; // Och avbryter loopen
            }
        }
        if (toRemove != null) { // Vi kollar att vi faktiskt har något att ta bort
            itemList.remove(toRemove); // Och tar bort det, utanför loopen, så det är helt lugnt.
        }
      
Vill vi ta bort flera element ur listan kan vi istället ta bort break; och göra toRemove till en ArrayList där vi stoppar allt vi vill ta bort och kör sedan:
	itemList.removeAll(toRemove); // istället för itemList.remove(toRemove); som ovan
      

Vad är en instans, och vad är en konstruktor?

För att svara på frågorna behöver vi veta vad en klass är. En klass är en ritning för hur något ska se ut och fungera i Java (eller objektorienterad programmering generellt). Vi kan jämföra med en ritning på ett hus: ritningen är vår klass. När vi bygger huset skapar vi en instans eller ett objekt av den klassen, något konkret vi kan jobba med. Vi kan bygga flera hus efter samma ritning, på samma sätt kan vi ha flera instanser/objekt av samma klass. Vi kan använda oss av Student-klassen från föreläsning 3 som exempel:

	Student s = new Student("Anna", 21);
      

Vi skapar ovan en variabel av typen/klassen Student, vi kallar den för s. Vi skapar sedan en instans / ett objekt att lagra i variabeln genom nyckelnordet new och att kalla på konstruktorn för klassen. Konstruktorn heter alltid samma som klassen. Ex:

	public class Student {
	    private String name;
	    private int age;

	    public Student(String name, int age) { // konstruktor för klassen Student
                this.name = name;
	        this.age = age;
	    }
	}
      

Det är konstruktorns ansvar att se till att när vår Student, i detta fall, är skapad så kan vi arbeta med den. Alla instansvariabler bör ha fått värden så att det inte blir något galet när vi börjar jobba med den. Det behöver inte nödvändigtvis vara parametrar som dikterar värdena, utan vi kan ha "default-värden" också. Ex:

	public class Student {
            private String name;
            private int age;
            private String catchphrase;

            public Student(String name, int age) { // konstruktor för klassen Student
                this.name = name;
                this.age = age;
                catchphrase = "Det är jätteroligt att plugga!";
            }
        } 
      

Ovan ger vi "catchphrase" ett generiskt startvärde, men eventuellt kanske vi ändrar det under körningen om någon har en annan catchphrase (eller bygger fler konstruktorer).


Sidansvarig: Magnus Nielsen
Senast uppdaterad: 2023-02-16