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?
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å.
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!
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.
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.
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)
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å ?
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.
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 ?
Ja exakt så, du kan göra super.toString()
Programmeraren skrev:Ja exakt så, du kan göra super.toString()
Toppen, nu funkar det. Tack för hjälpen :)