I have been working very hard to attempt and figure out these lines of code, but I can never seem to get it to come out right. I get several errors on lines 86, 91, 100, 110 and 118 and I have absolutely no idea why. Anyway, here it is:
public class lab21composition
{
public static void main(String args[])
{
CarFactory factory = new CarFactory ("Ford");
Garage myGarage = new Garage();
Car c = factory.produceCar("Fusion");
Truck t = factory.produceTruck("F150");
System.out.println(myGarage);
myGarage.addVehicle(c);
System.out.println(myGarage);
myGarage.addVehicle(t);
System.out.println(myGarage);
Vehicle v = myGarage.removeVehicle();
if (null !=v)
{
System.out.println(v.toString() + " was removed from garage.");
System.out.println(myGarage);
}
else
{
System.out.println("There was no vehicle in the garage to remove.");
}
myGarage.addVehicle(t);
System.out.println(myGarage);
CarFactory factory2 = new CarFactory ("Honda");
Garage myGarage2 = new Garage();
Car d = factory.produceCar("Odyssy");
myGarage.addVehicle(d);
System.out.println(myGarage2);
}
}
class CarFactory
{
private String name;
public CarFactory(String n)
{
name = n;
}
public Car produceCar(String model)
{
return name;
}
public Truck produceTruck(String model)
{
return name;
}
}
class Vehicle
{
private String make, model;
public Vehicle()
{
make = "Undefined";
model = "Undefined";
}
public Vehicle(String _make, String _model)
{
make = _make;
model = _model;
}
public String toString()
{
return make+" "+model;
}
}
class Car extends Vehicle
{
super (_make,_model); //I get a illegal start of type and identifier expected error here
}
class Truck extends Vehicle
{
super (_make,_model); //I get a illegal start of type and identifier expected error here
}
class Garage
{
//define a private variable that holds a Vehicle object. This will represent
private String Veh;
// the vehicle being stored in the Garage. If the garage is empty, then this variable should be null
}
public void addVehicle(Vehicle v)
{
if(v==Veh) /* replace FALSE with code to check if v is the same as vehicle */
{
//HINT: use a function inherited from the Object class!
System.out.println(v.toString() + " is already parked in this garage")
}
else if (hasVehicle())
{
System.out.println("This garage is full!");
}
else
{
//store the vehicle that was passed to this function
//in this class vehicle attribute
}
}
class removeVehicle()
{
public Vehicle removeVehicle()
{
//store this class vehicle attribute in a temporary variable
// set this class vehicle attribute to null
// return the vehicle stored in the temporary variable
return null;
}
public boolean hasVehicle()
{
//change this return statement so that it
//returns an appropriate boolean value
return false;
}
public String toString()
{
if (hasVehicle())
{
//replace ??? with the toString() method of the vehicle
// that is in this garage
return "This garage has a ??? in it!";
}
else
{
return "This garage is empty.";
}
}
}
class Car extends Vehicle
{
super (_make,_model);
}
The above super call appears outside a constructor. This is syntactically invalid code.
Solution 1: delete this code.
Solution 2: write a constructor.
Related
I need to use a class, which has an ArrayList of a LibraryItem type. I need to store the field values of the superclass LibraryItem and of its subclasses Book and Periodical in this ArrayList (the program reads a data file and stores each word in the approrpriate field accordingly). How can I do that?
Class - Library (class with ArrayList of LibraryItem)
public class Library
{
private ArrayList<LibraryItem> itemList; // it declares an ArrayList of LibraryItem type
public Library()
{
itemList = new ArrayList<>(); // it initalises the ArrayList of LibraryItem type
}
public void storeItem(LibraryItem libraryItem)
{
itemList.add(libraryItem);
}
// other codes omitted
if (typeOfData.equals("Book"))
{
System.out.println(lineOfText);
Scanner scanner2 = new Scanner(lineOfText);
LibraryItem libraryItem = new Book();
scanner2.useDelimiter("[,\n]");
libraryItem.readData(scanner2);
storeItem(libraryItem);
scanner2.close(); // ends scanner2
}
else if (typeOfData.equals("Periodical"))
{
System.out.println(lineOfText);
Scanner scanner2 = new Scanner(lineOfText);
LibraryItem libraryItem = new Periodical();
scanner2.useDelimiter("[,\n]");
libraryItem.readData(scanner2);
storeItem(libraryItem);
scanner2.close(); // ends scanner2
}
// other codes omitted
}
Class - LibraryItem (superclass)
public class LibraryItem
{
// fields omitted
public LibraryItem()
{
}
/**
* Mutator method used to read and store each data in the appropriate field
* #param <code>scanner2</code> Scanner is used to pass a Scanner object
* containg matching values with the field datatypes
*/
public void readData(Scanner scanner2)
{
scanner2.useDelimiter("\\s?,\\s?");
noOfPages = scanner2.nextInt();
publisher = scanner2.next();
title = scanner2.next();
itemCode = scanner2.next();
cost = scanner2.nextInt();
timesBorrowed = scanner2.nextInt();
onLoan = scanner2.nextBoolean();
}
// other codes omitted
}
Class - Book (subclass)
public class Book extends LibraryItem
{
private String author;
private String isbn;
public Book(String author, String isbn, int noOfPages, String publisher)
{
super();
this.author = author;
this.isbn = isbn;
}
public Book()
{
}
#Override
public void readData(Scanner scanner2)
{
scanner2.useDelimiter("[,\n]");
author = scanner2.next();
isbn = scanner2.next().trim();
super.readData(scanner2);
}
// other codes omitted
}
Class - Periodical (subclass)
public class Periodical extends LibraryItem
{
private String publicationDate;
public Periodical(String publicationDate)
{
super();
this.publicationDate = publicationDate;
}
public Periodical()
{
}
#Override
public void readData(Scanner scanner2)
{
scanner2.useDelimiter("[,\n]");
publicationDate = scanner2.next();
super.readData(scanner2);
}
The solution was that this code did not have any issue calling the subclasses' fields along with the subclasses. I needed to create an overridden method in the subclasses Book and Periodical:
Class - Library
LibraryItem is a polymorphic variable
public void printAllItems()
{
for (LibraryItem call : itemList)
{
call.printDetails(); // it will call the overridden method of each subclass
}
}
Abstract Class - LibraryItem
public void printDetails() // main method called by overridden methods
{
String notOnLoan = "";
if (onLoan == false)
notOnLoan = "not on";
else
notOnLoan = "on";
// these fields are used from both Book class and Periodical class
System.out.println(noOfPages + publisher);
System.out.println(title + itemCode + timesBorrowed);
System.out.println(notOnLoan + cost);
System.out.println();
}
Subclass - Book (inherits from LibraryItem)
#Override
public void printDetails()
{
System.out.println(author + isbn);
super.printDetails(); // it will run the method of subclass
}
Subclass - Periodical (inherits from LibraryItem)
#Override
public void printDetails()
{
System.out.println(publicationDate);
super.printDetails(); // it will run the method of subclass
}
Long story short, main class consist of
List<Vehicle> vehicles = new ArrayList<Vehicle>();
Car r1 = new Car(1000, true); ...
Cars class is subClass of Vehicles superclass and objects are added to vehicles list. Lastly, the main class calls out
System.out.println(Car.findMostExpensive4x4(vehicles).getPrice());
SubClass "Car" constructor takes in 2 parameters - price and the 4x4 (boolean)
public Car(double pPrice, boolean pfourByFour) {
super(pPrice);
this.fourByFour = pfourByFour;
}
The method that is called out in main has to parse data from object list and return that object. But how is this implemented ?
public static Car findMostExpensive4x4(List<Vehicle> vehicles) {
}
Then, the returned Car object price is found by getPrice method somehow.
public double getPrice() {
return 0;
}
Thank you
The list passed as argument cannot be a Vehicles list, since a Vehicle doesn't know if is 4x4 or not. Cars knows it.
You can create a Vehicle interface:
interface Vehicle {
double getPrice();
boolean is4x4();
}
class Car implements Vehicle {
private double price;
private boolean is4x4;
public Car(double price, boolean is4x4) {
this.price = price;
this.is4x4 = is4x4;
}
#Override
public double getPrice() {
return price;
}
#Override
public double is4x4() {
return is4x4;
}
public static Car findMostExpensive4x4(List<Vehicle> vehicles) {
if (vehicles == null) return null; //or throw exception
if (vehicles.isEmpty()) return null; // or throw exception
double mostExpensivePrice = 0d;
Vehicle mostExpensive = null;
for (Vehicle v : vehicles) {
if (v.is4x4() && v.getPrice() > mostExpensivePrice) {
mostExpensive = v;
mostExpensivePrice = v.getPrice();
}
}
return mostExpensive != null? (Car)mostExpensive : null;
}
}
It is supposed that price cannot be less than 0. In another case, this solution is not valid.
return (Car)mostExpensive; will fail if vehicle is not a Car.
findMostExpensive4x4 method shouldn't be placed in Car class.
This is a fast-thought solution and very ugly, too. You should consider to re-think the design.
I am trying to develop a program that can sort an array of objects that are of different class types, but in the same hierarchy as one another. All of the objects are listed within the same array that I am trying to sort, and while I can alphabetically sort an array of objects that are of the same type easily enough, I cannot figure out how to sort everything all at once with the same Arrays.sort() method. Any help that anyone could provide would be greatly appreciated.
import java.util.Arrays;
public class Driver {
public static void main(String[] args) {
Vehicle[] machines = new Vehicle[3];//Example of an array that I can sort
machines[0] = new Vehicle("Giant Robot");
machines[1] = new Vehicle("Time Machine");
machines[2] = new Vehicle("Airplane");
Arrays.sort(machines);
for (int i = 0; i < machines.length; i++)
System.out.println(machines[i].getName());
Vehicle[] vehicles = new Vehicle[7];//example of an array that I cannot sort
vehicles[0] = new Car("Batmobile", 10);
vehicles[1] = new Helicopter("Batcopter", "x");
vehicles[2] = new Car("Jaguar", 6);
vehicles[3] = new Helicopter("RC Copter", "t");
vehicles[4] = new Car("Accelerator", 6);
vehicles[5] = new Helicopter("Stormshadow", "z");
vehicles[6] = new Car("Batmobile", 11);
}
}
**
public class Vehicle implements Comparable {
private String name;
public Vehicle(){
name = "no name";
}
public Vehicle(String newName){
name = newName;
}
public String getName(){
return name;
}
public int compareTo(Object o)
{
if ((o != null) &&
(o instanceof Vehicle))
{
Vehicle otherVehicle = (Vehicle) o;
return (name.compareTo(otherVehicle.name));
}
return -1;
}
}
**
public class Car extends Vehicle {
private int tireSize;
public Car(){
super();
tireSize = 0;
}
public Car(String newName, int newTireSize){
super(newName);
tireSize = newTireSize;
}
public int getSize(){
return tireSize;
}
}
**
public class Helicopter extends Vehicle {
private String bladeType;
public Helicopter(){
super();
bladeType = "none";
}
public Helicopter(String newName, String newBlade){
super(newName);
bladeType = newBlade;
}
public String getType(){
return bladeType;
}
}
Goal: You need to be able to compare a Vehicle to other of Vehicle.
To achieve that goal:
public class Vehicle implements Comparable<? extends Vehicle> {
....
public int compareTo(Object o) {
// Now, that the Comparable is for the type Vehicle
// you know that o is some kind of vehicle
// check vehicle related things
// number of seats, dogs, whatever
return -1;
}
}
You just need to adjust your code to:
class Vehicle implements Comparable<Vehicle> {
private String name;
/* ... */
#Override
public int compareTo(Vehicle vehicle) {
return name.compareTo(vehicle.getName());
}
}
In most cases, your classes should not implement Comparable, unless there is one and only one ordering that is always the correct one, like with numbers. Your vehicles can be sorted by name, by age, and probably by more criteria, so they should not implement Comparable.
Instead, you can pass the ordering function as a lambda function, at the time where you actually sort your vehicles:
Arrays.sort(machines, (left, right) -> left.getName().compareTo(right.getName()));
Or, equivalently:
Arrays.sort(machines, Comparator.comparing(Vehicle::getName));
This way you don’t need the implements Comparable anymore.
If you want to sort by vehicle type then you need to take class type into consideration, while sorting the element. Modify the compareTo() method as shown below:
public int compareTo(Object o){
if ((o != null) &&
(o instanceof Vehicle)){
Vehicle otherVehicle = (Vehicle) o;
return (otherVehicle.getClass().getSimpleName().equals(this.getClass().getSimpleName()) ?
name.compareTo(otherVehicle.name)
: otherVehicle.getClass().getSimpleName().compareTo(this.getClass().getSimpleName()));
}
return -1;
}
Sorry if this is a little confusing, First time using this site so I dont know if I entered my code in right or not. So my question is, when I run this program in class driver I get this:
name: No Name Yet
Manufacturer: no name yet
Engine Cyclinders: 0
Load: 0.0
Towing: 0.0
Which is the default, now I am trying to be able to put a input in the class driver that will change say the name to whatever I set it as from class Person for example. I have tried doing p.setName("Tim") but it will only show the name as tim if I call the writeouput method from class Person. If I call the writeoutput from class Truck then it says no name yet. I put super in the writeoutput but I'm not sure what i'm doing wrong. any help would be appreciated
public class Person {
private String name;
public Person()
{
name = "No Name Yet";
}
public Person(String initialName)
{
name = initialName;
}
public void setName(String newName)
{
newName = "tim";
name = newName;
}
public String getName()
{
return name;
}
public void writeOutput()
{
System.out.println("name: " + name);
}
public boolean hasSameName(Person otherPerson)
{
return this.name.equalsIgnoreCase(otherPerson.name);
}
}
public class Vehicle extends Person {
String manufactName;
int engine;
public Vehicle()
{
manufactName = "no name yet";
engine = 0;
}
public Vehicle(String initialManufactName, int initialEngine)
{
manufactName = initialManufactName;
engine = initialEngine;
}
public void setManufactName(String newManufactName)
{
manufactName = newManufactName;
}
public void setEngine(int newEngine)
{
engine = newEngine;
}
public String getManufactName()
{
return manufactName;
}
public double getEngine()
{
return engine;
}
public void writeOutput()
{
super.writeOutput();
System.out.println("Manufacturer: " + manufactName);
System.out.println("Engine Cyclinders: " + engine);
}
public boolean hasSameManufactName(Vehicle otherVehicle)
{
return this.manufactName.equalsIgnoreCase(otherVehicle.manufactName);
}
public boolean hasSameEngine(Vehicle otherVehicle)
{
return this.engine == (otherVehicle.engine);
}
}
public class Truck extends Vehicle {
private double load;
private double towing;
public Truck()
{
load = 0;
towing = 0;
}
public Truck(double initialLoad, double initialTowing)
{
load = initialLoad;
towing = initialTowing;
}
public void setLoad(double newLoad)
{
load = newLoad;
}
public void setTowing(double newTowing)
{
towing = newTowing;
}
public double getLoad()
{
return load;
}
public double getTowing()
{
return towing;
}
public void writeOutput()
{
super.writeOutput();
System.out.println("Load: " + load);
System.out.println("Towing: " + towing);
}
public boolean hasSameLoad(Truck otherTruck)
{
return this.load == (otherTruck.load);
}
public boolean hasSameTowing(Truck otherTruck)
{
return this.towing == (otherTruck.towing);
}
}
public class Driver extends Truck{
public static void main(String[] args){
Person p = new Person();
Vehicle v = new Vehicle();
Truck t = new Truck();
t.writeOutput();
}
}
You don't need to create an instance of each class in the hierachy.
Try:
Truck t = new Truck();
t.setName("tim");
t.writeOutput();
Also, your design is odd: Vehicles wouldn't normally subclass a Person, and a Driver wouldn't normally subclass a Truck. A Driver would be a subclass of a Person. A Truck would be a subclass of a vehicle and a Vehicle would "have" a Driver.
The two methods need to consider the boolean onLoan from the a second class named car for them to be able to be applied, what I mean is that only cars which onLoan == false should be considered. I got to the base of them tried what it came to my mind about getting this solved but nothing for me seems to work at the moment some suggestions? Thank you!
/**
* Constructor for objects of class RentalCompany
*/
public void showAllCarsNotOnloan ()
{
for ( Car car:cars) {
if (cars.size()>0 ) {
int i = 0;
System.out.println(car.getDescription());
i++;
}
else if ( cars.size() < 0 ){
System.out.println ("Add cars first");
}
}
}
and the second method
public Car searchCar(String description)
{
for (Car car : cars) {
if (car.getDescription() == description) {
return car;
}
else {
System.out.println("This car is not listed. Retry!!");
}
}
return null;
}
The following will do the work:
The Car class:
public class Car {
private boolean onLoan;
// Other variables...
public boolean isOnLoan() {
return onLoan;
}
// Other methods....
}
Now, the showAllCarsNotOnloan method
public void showAllCarsNotOnloan() {
if (cars.size() == 0) {
System.out.println("Add cars first!");
return;
}
for (Car car : cars) {
if (!car.isOnLoan()) {
System.out.println(car.getDescription());
}
}
}
and the searchCar method
public Car searchCar(String description) {
for (Car car : cars) {
if (car.getDescription().equals(description)) {
return car;
}
}
System.out.println("This car not listed. Retry!!");
return null;
}