9
\$\begingroup\$

I have some question about this exercise, did I model the problem correctly (the code works)?. If I did it correctly, Is there anything that can improve the code?. For example, how could I avoid the repeated attribute private double enginePower; I have in class LuxuryYacht and class Embarkation? or can not be avoided? And so will finally be the code.

Exercise: In a port, moorings are aquilan (parking space) for boats. For each rental, the name, the customer number, the number of days of the rental, the position of the mooring and the boat that occupy it are stored. A boat is characterized by its registration, its eslova (in meters) and the year of manufacture. The boats differ according to their type and characteristics in:

  • Sailboats: number of masts.
  • Sports boats: power in the engine.
  • Luxury yachts: power in engine and number of cabins.

The cost of rent is calculated by multiplying the number of days of occupancy by the daily cost, which varies according to the type of each boat:

  • For sailboats it is calculated by multiplying the number of masts by $ 15.
  • For boats it is calculated by multiplying the meters of eslova by $ 35.
  • For yachts it is calculated by multiplying the number of cabins by $ 17.
    1. Use inheritance to implement classes and their relationships.
    2. Generate a test class that:

A) Enter the information for each type of boat.

B) Using polymorphism calculate the rent paid by the client.

C) Using an interface display the data of each of the types of boats.

interface Additional{
String ShowData();
double RentCost();
}

class Rental 
{
private static String name,position;
private static int numDays,numClient;
Ship b[];
Rental(){}
Rental(String name,String position,int numDays,int numClient,int 
enrollment,int year,double slovak)
{
    this.name=name;
    this.position=position;
    this.numDays=numDays;
    this.numClient=numClient;
    b[0]=new Ship(enrollment,year,slovak);
    b[1]=new Ship(enrollment,year,slovak);
    b[2]=new Ship(enrollment,year,slovak);
}

static String getName(){
    return name;
}
static String getPosition(){
    return position;
}
static int getNumDays(){
    return numDays;
}
static int getNumClient(){
    return numClient;
}
void setName(String n){
    name=n;
}
  void setPosition(String p){
      position=p;
  }  
  void setNumDays(int n){
      numDays=n;
  }
      void setNumClient(int n){
          numClient=n;
      }    



}

class Ship implements Additional{

private int enrollment,year;
static double slovak;//in meters

Ship(int enrollment,int year,double slovak)
{
    this.enrollment=enrollment;
    this.year=year;
    this.slovak=slovak;//ship length

}

public String ShowData(){
  //Rental t=new Rental(); t.getPosition() implies null as output..
  return enrollment+" "+year+" "+slovak+" "+Rental.getName()+" 
"+Rental.getNumClient()+" "+Rental.getPosition()+" 
"+Rental.getNumDays();
}

public  double RentCost(){

  return Rental.getNumDays();
}

}

class Sailing extends Ship {
private int numMast;

Sailing(int enrollment,int year,double slovak,int numMast){
    super(enrollment,year,slovak);
            this.numMast=numMast;
}

public String ShowData(){
   return super.ShowData()+" "+numMast;
}
public  double RentCost(){
 return super.RentCost()*15*numMast;

}

}
class Embarkation extends Ship{
private double enginePower;

Embarkation(int enrollment,int year,double slovak,double enginePower){
    super(enrollment,year,slovak);

            this.enginePower=enginePower;
}

public String ShowData(){
   return super.ShowData()+" "+enginePower;
}
public  double RentCost(){
 return super.RentCost()*35*Ship.slovak; //use of static
}
}

class LuxuryYacht extends Ship{
private double enginePower;//repeated attribute in Embarkation class
private int numCabins;

LuxuryYacht(int enrollment,int year,double slovak,double 
enginePower,int 
numCabins){
    super(enrollment,year,slovak);

            this.enginePower=enginePower;
            this.numCabins=numCabins;
}
public String ShowData(){
   return super.ShowData()+" "+enginePower+" "+numCabins;
}
public  double RentCost(){
 return super.RentCost()*numCabins*17;
}
}




public class Ship24th {

public static void main(String[] args) {
    Scanner r=new Scanner(System.in);

    Rental s=new Rental();
    Ship b[]=new Ship[3];

    System.out.println("Enter information about the sailing ship \n");
    System.out.println("Enter the name of the client");
    String nam=r.nextLine();
    s.setName(nam);
    System.out.println("Enter the number of the client");
    int n=r.nextInt();
    s.setNumClient(n);
    System.out.println("Enter the number of days of the rental");
    int m=r.nextInt();
    s.setNumDays(m);
    System.out.println("Enter the mooring position");
    r.nextLine(); //to avoid non-read lines
    String p=r.nextLine();
     s.setPosition(p);
    System.out.println("Enter the enrollment");
    int q=r.nextInt();
    System.out.println("Enter the slovak");
    double w=r.nextDouble();
    System.out.println("Enter the year of fabrication");
    int k=r.nextInt();
    System.out.println("Enter the number of masts");
    int v=r.nextInt();


    b[0]=new Sailing(q,k,w,v);
    System.out.println(b[0].ShowData()+" "+b[0].RentCost());

    System.out.println("Enter information about the Luxury Yacht ship 
     \n");
    System.out.println("Enter the name of the client");
    r.nextLine();
    String a=r.nextLine();
    s.setName(a);
    System.out.println("Enter the number of the client");
    int c=r.nextInt();
    s.setNumClient(c);
    System.out.println("Enter the number of days of the rental");
    int d=r.nextInt();
    s.setNumDays(d);
    System.out.println("Enter the mooring position");
    r.nextLine(); //to avoid non-read lines
    String e=r.nextLine();
     s.setPosition(e);
    System.out.println("Enter the enrollment");
    int f=r.nextInt();
    System.out.println("Enter the slovak");
    double g=r.nextDouble();
    System.out.println("Enter the year of fabrication");
    int h=r.nextInt();
    System.out.println("Enter the number of engine power");
    double i=r.nextInt();
    System.out.println("Enter the number of cabins");
    int j=r.nextInt();
    b[1]=new LuxuryYacht(f,h,g,i,j);
    System.out.println(b[1].ShowData()+" "+b[1].RentCost());


    System.out.println("Enter information about the Embarkation ship 
     \n");
    System.out.println("Enter the name of the client");
    r.nextLine();
    String l=r.nextLine();
    s.setName(l);
    System.out.println("Enter the number of the client");
    int o=r.nextInt();
    s.setNumClient(o);
    System.out.println("Enter the number of days of the rental");
    int t=r.nextInt();
    s.setNumDays(t);
    System.out.println("Enter the mooring position");
    r.nextLine(); //to avoid non-read lines
    String u=r.nextLine();
     s.setPosition(u);
    System.out.println("Enter the enrollment");
    int x=r.nextInt();
    System.out.println("Enter the slovak");
    double y=r.nextDouble();
    System.out.println("Enter the year of fabrication");
    int z=r.nextInt();
    System.out.println("Enter the number of engine power");
    double aa=r.nextInt();

    b[2]=new Embarkation(x,z,y,aa);

    System.out.println(b[2].ShowData()+" "+b[2].RentCost());
 }

 }
\$\endgroup\$
  • \$\begingroup\$ Before posting it here, you should format the code properly. If your are using Eclipse, press Ctrl+Shift+F, in IntelliJ it's Ctrl+Alt+L. As it is now, it's hard to read. \$\endgroup\$ – Roland Illig Aug 25 '17 at 5:33
  • \$\begingroup\$ @RolandIllig I'm using netbeans, how are the commands for it? \$\endgroup\$ – user178403 Aug 25 '17 at 5:34
  • \$\begingroup\$ I don't know, just search for the word Format in the main menu. \$\endgroup\$ – Roland Illig Aug 25 '17 at 5:39
  • 1
    \$\begingroup\$ @Michelle Source/Format \$\endgroup\$ – Maurice Perry Aug 25 '17 at 6:18
  • \$\begingroup\$ @Michelle You can still edit the question, for example to add missing tags (but based on the exercise, it is perfectly clear you are a beginner). In my opinion, it would even be acceptable to reformat the code, since none of the existing answers would be invalidated by that edit. (There is a general agreement on this site that edits to the question must not invalidate answers.) \$\endgroup\$ – Roland Illig Aug 25 '17 at 6:38
7
\$\begingroup\$

OK, Hello again.

So here are my comments:

  1. You should not have an array of boats in class Rental, but just a reference to a single boat. That boat should be given in the constructor, and a getter and a setter should be added:
  2. The fields should not be static

Here's a new version of the Rental class:

class Rental {
    private String name, position;
    private int numDays, numClient;
    private Ship ship;

    Rental() {
    }

    Rental(String name, String position, int numDays, int numClient, Ship ship) 
    {
        this.name = name;
        this.position = position;
        this.numDays = numDays;
        this.numClient = numClient;
        this.ship = ship;
    }

    String getName() {
        return name;
    }

    String getPosition() {
        return position;
    }

    int getNumDays() {
        return numDays;
    }

    int getNumClient() {
        return numClient;
    }

    Ship getShip() {
        return ship;
    }

    void setName(String n) {
        name = n;
    }

    void setPosition(String p) {
        position = p;
    }

    void setNumDays(int n) {
        numDays = n;
    }

    void setNumClient(int n) {
        numClient = n;
    }

    void setShip(Ship ship) {
        this.ship = ship;
    }
}

The Ship class should be abstract because you don't know what would be the daily cost (and the RentCost method should be kept abstract, BTW, method names usually start with a lowercase letter).

The field slovak (???) should be protected instead of private (not static!!!) so that it can be used in subclasses. You could also have added a getter.

The ship cannot access the fields of a Rental (which Rental BTW).

abstract class Ship implements Additional {
    private int enrollment, year;
    protected double slovak;//in meters

    Ship(int enrollment, int year, double slovak) {
        this.enrollment = enrollment;
        this.year = year;
        this.slovak = slovak;//ship length

    }

    @Override
    public String showData() {
        //Rental t=new Rental(); t.getPosition() implies null as output..
        return enrollment + " " + year + " " + slovak;
    }
}

BTW, I still don't get the Additional interface.

For the Sailing boat, you just need to add the number of masts, and implement the abstract methods:

class Sailing extends Ship {
    private int numMast;

    Sailing(int enrollment, int year, double slovak, int numMast) {
        super(enrollment, year, slovak);
        this.numMast = numMast;
    }

    @Override
    public String showData() {
        return super.ShowData() + " " + numMast;
    }

    @Override
    public double rentCost() {
        return 15 * numMast;
    }
}

Now, as you have noted, the two other types of boat need an engine power. You have two ways to avoid declaring the field in each class: declare it in Ship, or introduce a new abstract class, say MotorShip:

abstract class MotorShip extends Ship {
    protected double enginePower;

    MotorShip (int enrollment, int year, double slovak, double enginePower) {
        super(enrollment, year, slovak);
        this.enginePower= enginePower;
    }

    @Override
    public String showData() {
        return super.ShowData() + " " + enginePower;
    }
}

Note that the field enginePower is protected, not private, because you will need it in the subclasses (you could also have added a getter).

Here are your two last concrete classes:

class SportBoat extends MotorShip {

    SportBoat(int enrollment, int year, double slovak, double enginePower) {
        super(enrollment, year, slovak, enginePower);
    }

    @Override
    public double rentCost() {
        return 35 * slovak;
    }
}


class LuxuryYacht extends MotorShip {

    private int numCabins;

    LuxuryYacht(int enrollment, int year, double slovak, double enginePower, int numCabins) {
        super(enrollment, year, slovak, enginePower);
        this.numCabins = numCabins;
    }

    @Override
    public String showData() {
        return super.ShowData() + " " + numCabins;
    }

    @Override
    public double rentCost() {
        return numCabins * 17;
    }
}
\$\endgroup\$
  • \$\begingroup\$ why fields shouldn't be static? \$\endgroup\$ – user178403 Aug 25 '17 at 13:45
  • \$\begingroup\$ '..and the RentCost method should be kept abstract.' it is already abstract,it is inside the interface. Or what do you mean about it? \$\endgroup\$ – user178403 Aug 25 '17 at 13:48
  • \$\begingroup\$ I don't get the Additional interface neither but in the exercise says: 'Using an interface display the data of each of the types of boats.' so I have to declare an interface such that.. \$\endgroup\$ – user178403 Aug 25 '17 at 13:53
  • \$\begingroup\$ About your solution of avoiding the repeated attribute enginePower, I think the only choice I have is the second one, because If I choose the first one, then the Sailing class would be able to use the enginePower attribute and we don't want that. \$\endgroup\$ – user178403 Aug 25 '17 at 13:58
  • 1
    \$\begingroup\$ @Michelle name, position, numDaysand numClient are attributes of the rental, not of the ship (a ship have a life of it's own). You can add a method showData in class Rental that returns a string with the value of these attributes as well of those of the ship involved in the rental (by calling the showData method of the ship). \$\endgroup\$ – Maurice Perry Aug 28 '17 at 5:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.