10 svar
190 visningar
Hmowed 63
Postad: 10 dec 2021 21:27 Redigerad: 10 dec 2021 21:35

Implementation of Classes!

Hej! 

Jag håller på med en uppgift som går ut på att implementera Klasser: Vehicle, Car och Van. Uppgiftens text är som följer: 

 

Implement classes Vehicle, Car and Van to make program TestCarVan
print the below. Let Car and Van inherit from Vehicle and override the toString()-method.
All data should be set in constructors. All data should be private. There should be NO
redundant code.

Description of classes:
- A Car has an id, a top speed and an owner (a Person).
- A Van has an owner (a Person), a max cargo and an id.

A run of the program TestCarVan should look like (use toString() for the output):

Car{topSpeed=160.0{owner=Person{id='123', name='olle'}, id='abc'}}
Van{maxCargo=400.0{owner=Person{id='456', name='fia'}, id='def'}}
Car{topSpeed=210.0{owner=Person{id='456', name='fia'}, id='ghi'}}
Van{maxCargo=800.0{owner=Person{id='123', name='olle'}, id='jkl'}}

TIP: Possible for IntelliJ to generate constructors and toString()

 

 

Så har har jag gjort hittills: (Obs Klassen Person är given)

Klassen Vehicle :

public abstract class Vehicle {

    private final String id;
    private final Person p;

    public Vehicle(String id, Person p) {
        this.id = id;
        this.p = p;
    }
    public String getId() {return id;}
    public Person getP() {return p;}

    public Vehicle(Vehicle other) {   // Will create copy of other.
        this(other.getId(), other.getP());
    }

    //.......Abstract methods........
    
    public abstract void vehicle();

    @Override
    public String toString() {
        return "Vehicle{" +
                "id='" + id + '\'' +
                ", p=" + p +
                '}';
    }
}

Klassen Car:

 

public class Car extends Vehicle {

    private final double topSpeed;

    public Car(Person p, String id, double topSpeed) {
        super(id, p);
        this.topSpeed = topSpeed;
    }

    public double getTopSpeed() {
        return topSpeed;
    }


    @Override
    public void vehicle() {
        Car car = new Car(getP(),getId(),getTopSpeed());
    }

    @Override
    public String toString() {
        return "Car{" +
                "topSpeed=" + topSpeed +
                '}';
    }
    
}

Klassen Van:

public class Van  extends Vehicle{

   private final double maxCargo;


   public Van(Person p, String id, double maxCargo) {
      super(id, p);
      this.maxCargo = maxCargo;
   }

   public double getMaxCargo() {
      return maxCargo;
   }


   @Override
   public void vehicle() {
      Van van = new Van(getP(),getId(),getMaxCargo());
   }
   
   @Override
      public String toString () {
         return "Van{" +
                 "maxCargo=" + maxCargo +
                 '}';
      }
}

Program (TestCarVan):

public class TestCarVan {

    public static void main(String[] args) {
        new TestCarVan().program(); //Rad 37
    }

    private void program() {
        Person p1 = new Person("123", "olle");
        Person p2 = new Person("456", "fia");
        List<Vehicle> vehicles = null;  List.of(new Car(p1, "abc", 160),
                new Van(p2, "def", 400),
                new Car(p2, "ghi", 210),
                new Van(p1, "jkl", 800)
        );

        for (Vehicle v : vehicles) { //Rad 49
            out.println(v);   // Each vehicle should know what to print!
        }
    }
}

Problemet är att när jag kör testet (TestCarVan) som får jag följande :

Exception in thread "main" java.lang.NullPointerException
	at ex1inheritance.TestCarVan.program(TestCarVan.java:49)
	at ex1inheritance.TestCarVan.main(TestCarVan.java:37)

Process finished with exit code 1

Jag har markerat Raderna 49 och 37 i TestCarVan. Är implementationer av Klasser Vehicle, Car och Van fel?

CurtJ 1148
Postad: 11 dec 2021 05:51

Till att börja med så skapar du en variabel vehicles men du skapar inget innehåll i den. Du skapar en lista (List.of) men den hänger i luften så du måste koppla ihop variabeln med listan.

Några andra tips är att använda mer beskrivande namn på metoder och variabler, t ex getP() i klassen Vehicle. Sen undrar jag vad metoden vehicle() har för syfte? Den skapar något som inte används. Kanske för test?

Titta också på String.format() för att formattera strängar. Det brukar bli lättare att underhålla då.

Programmeraren 3387
Postad: 11 dec 2021 10:08

public Vehicle(Vehicle other) { // Will create copy of other.
Det är return som saknas men som CurtJ sa, inte uppenbart vad den är till för.

F ö: Jag tycker inte tipset "Possible for IntelliJ to generate constructors and toString()" hör hemma på nivån när man gör sina första klasser, bättre att undvika "magi" tills dess att visa typer av metoder är så självklara att de känns som rent kroppsarbete att skriva. Men du kanske är där redan!

Hmowed 63
Postad: 11 dec 2021 10:32
CurtJ skrev:

Till att börja med så skapar du en variabel vehicles men du skapar inget innehåll i den. Du skapar en lista (List.of) men den hänger i luften så du måste koppla ihop variabeln med listan.

Några andra tips är att använda mer beskrivande namn på metoder och variabler, t ex getP() i klassen Vehicle. Sen undrar jag vad metoden vehicle() har för syfte? Den skapar något som inte används. Kanske för test?

Titta också på String.format() för att formattera strängar. Det brukar bli lättare att underhålla då.

Klassen Vehicle är abstrakt, så tanken är att vi ska träna på att använda abstrakta metoder.

Metoden vehicle() är en abstrakt metod som saknar implementation i klassen Vehicle. Däremot så försökte jag att implementera Vehicle() i klasser Car och Van som ärver från Klassen Vehicle. 

Metoden vehicle() skall returnera en string  med innehållet som given i testet, men jag lyckas inte med det. 

Hmowed 63
Postad: 11 dec 2021 10:40
Programmeraren skrev:

public Vehicle(Vehicle other) { // Will create copy of other.
Det är return som saknas men som CurtJ sa, inte uppenbart vad den är till för.

F ö: Jag tycker inte tipset "Possible for IntelliJ to generate constructors and toString()" hör hemma på nivån när man gör sina första klasser, bättre att undvika "magi" tills dess att visa typer av metoder är så självklara att de känns som rent kroppsarbete att skriva. Men du kanske är där redan!

Stämmer bra, det är första gången jag gör en uppgifter som har och göra med super/sub klasser.

public vehicle (vehicle other) Den saknar användning ja, hade en ide att använde den som inte riktigt funkat. 

Så här långt så har jag koll på metoder så som constructors, getters/setters och toString. 

Programmeraren 3387
Postad: 11 dec 2021 10:59 Redigerad: 11 dec 2021 10:59

Du säger två saker som inte riktigt går ihop:
Metoden vehicle() skall returnera en string  med innehållet som given i testet, men jag lyckas inte med det. 
public vehicle (vehicle other) Den saknar användning ja, hade en ide att använde den som inte riktigt funkat. 

Om den ska returnera en sträng så låter det som exakt samma som det du implementerat i toString().
Om den ska skapa en kopia låter det mer som en constructor:
Du har bra grund med att alla klasser kan skapa object med sina argument och du använder super() korrekt.
I Vehicle har du också en constructor som skapar en kopia. Om du vill ha en sån så bör du ha motsvarande i Car och Van, alltså
public Car(Car car)

Hmowed 63
Postad: 11 dec 2021 11:21
Programmeraren skrev:

Du säger två saker som inte riktigt går ihop:
Metoden vehicle() skall returnera en string  med innehållet som given i testet, men jag lyckas inte med det. 
public vehicle (vehicle other) Den saknar användning ja, hade en ide att använde den som inte riktigt funkat. 

Om den ska returnera en sträng så låter det som exakt samma som det du implementerat i toString().
Om den ska skapa en kopia låter det mer som en constructor:
Du har bra grund med att alla klasser kan skapa object med sina argument och du använder super() korrekt.
I Vehicle har du också en constructor som skapar en kopia. Om du vill ha en sån så bör du ha motsvarande i Car och Van, alltså
public Car(Car car)

Har adderat lite till i toString nu, klasser följer som:

public abstract class Vehicle {

    private final String id;
    private final Person p;

    public Vehicle(String id, Person p) {
        this.id = id;
        this.p = p;
    }

    public String getId() {
        return id;
    }

    public Person getP() {
        return p;
    }

    @Override
    public String toString() {
        return "Vehicle{" +
                "id='" + id + '\'' +
                ", p=" + p +
                '}';
    }
}

public class Car extends Vehicle {

    private final double topSpeed;

    public Car(Person p, String id, double topSpeed) {
        super(id, p);
        this.topSpeed = topSpeed;
    }


    @Override
    public String toString() {
        return "Car{" +
                "topSpeed=" + topSpeed +
                "{" + "owner=" + getP() + ", " +  "id=" + getId() + "}}";
    }

}

public class Van  extends Vehicle{

   private final double maxCargo;


   public Van(Person p, String id, double maxCargo) {
      super(id, p);
      this.maxCargo = maxCargo;
   }

   
   @Override
   public String toString() {
      return "Van{" +
              "maxCargo=" + maxCargo +
              '{' + "owner=" + getP() +  ", " +  "id=" + getId() + "}}";
   }
}

Kör jag testet nu så för jag följande:

Car{topSpeed=160.0{owner=Person{id='123', name='olle'}, id=abc}}
Van{maxCargo=400.0{owner=Person{id='456', name='fia'}, id=def}}
Car{topSpeed=210.0{owner=Person{id='456', name='fia'}, id=ghi}}
Van{maxCargo=800.0{owner=Person{id='123', name='olle'}, id=jkl}}

Process finished with exit code 0

Så man ska bara implementera i toString metoden ?, kan det finnas ett annat sätt att göra detta på ? 

Programmeraren 3387
Postad: 11 dec 2021 11:40

Eftersom du får TestCarVan och den gör print på dina objekt så MÅSTE det vara toString() som returnerar den beskrivande strängen. Precis so toString() är tänkt att göra. Så det ser bra ut.

"There should be NO redundant code" betyder att du nog måste optimera toString() lite, 

"{" + "owner=" + getP() + ", " + "id=" + getId() + "}}";

förekommer i alla tre klasserna (i något olika format). Eftersom Vehicle är abstract klass kan du låta dess toString() endast returnera den gemensamma beskrivningen för alla vehicles och använda den i subklasserna.

Hmowed 63
Postad: 11 dec 2021 12:25
Programmeraren skrev:

Eftersom du får TestCarVan och den gör print på dina objekt så MÅSTE det vara toString() som returnerar den beskrivande strängen. Precis so toString() är tänkt att göra. Så det ser bra ut.

"There should be NO redundant code" betyder att du nog måste optimera toString() lite, 

"{" + "owner=" + getP() + ", " + "id=" + getId() + "}}";

förekommer i alla tre klasserna (i något olika format). Eftersom Vehicle är abstract klass kan du låta dess toString() endast returnera den gemensamma beskrivningen för alla vehicles och använda den i subklasserna.

Använder man super() på något sätt för att använda den gemensamma beskrivningen toString() i subklasserna ?

Programmeraren 3387
Postad: 11 dec 2021 12:45

Ja exakt så, du kan göra super.toString()

Hmowed 63
Postad: 11 dec 2021 12:46
Programmeraren skrev:

Ja exakt så, du kan göra super.toString()

Toppen, nu funkar det. Tack för hjälpen :)

Svara Avbryt
Close