# OOP modeling of a boat rental system

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;
}

}

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");
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");
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");
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());
}

}

• 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. Aug 25, 2017 at 5:33
• @RolandIllig I'm using netbeans, how are the commands for it? Aug 25, 2017 at 5:34
• I don't know, just search for the word Format in the main menu. Aug 25, 2017 at 5:39
• @Michelle Source/Format Aug 25, 2017 at 6:18
• @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.) Aug 25, 2017 at 6:38

OK, Hello again.

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;
}
}

• why fields shouldn't be static? Aug 25, 2017 at 13:45
• '..and the RentCost method should be kept abstract.' it is already abstract,it is inside the interface. Or what do you mean about it? Aug 25, 2017 at 13:48
• 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.. Aug 25, 2017 at 13:53
• 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. Aug 25, 2017 at 13:58
• @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). Aug 28, 2017 at 5:54