Getter/Setter (composition, Java, HW)
I have one class called Person that basically looks like:
public class Person
{
String firstName;
String lastName;
String telephone;
String email;
public Person()
{
firstName = "";
lastName = "";
telephone = "";
email = "";
}
public Person(String firstName, String lastName, String telephone, String email)
{
this.firstName = firstName;
this.lastName = lastName;
this.telephone = telephone;
this.email = email;
}
public String getFirstName()
{
return firstName;
}
public void setFirstName(String firstName)
{
this.firstName = firstName;
}
....
Using that class, I setup an abstract class called Loan that looks like:
public abstract class Loan
{
public void setClient(Person client)
{
this.client = client;
}
public Person getClient()
{
return client;
}
public void setLoanId(int nextId)
{
loanId = nextId;
nextId++;
}
public int getLoanId()
{
return loanId;
}
public void setInterestRate(double interestRate)
{
this.interestRate = interestRate;
}
public double getInterestRate()
{
return interestRate;
}
public void setLoanLength(int loanLength)
{
this.loanLength = loanLength;
}
public int getLoanLength()
{
return loanLength;
}
public void setLoanAmount(double loanAmount)
{
this.loanAmount = loanAmount;
}
public double getLoanAmount(double loanAmount)
{
return loanAmount;
}
private Person client;
private int loanId;
private double interestRate;
private int loanLength;
private double loanAmount;
private static int nextId = 1;
}
I have to extend the Loan class with CarLoan and it looks like:
public class CarLoan extends Loan
{
public CarLoan(Person client, double vehiclePrice, double downPayment, double salesTax,
double interestRate, CAR_LOAN_TERMS length)
{
super.setClient(client);
super.setInterestRate(interestRate);
this.client = client;
this.vehiclePrice = vehiclePrice;
this.downPayment = downPayment;
this.salesTax = salesTax;
this.length = length;
}
public void setVehiclePrice(double vehiclePrice)
{
this.vehiclePrice = vehiclePrice;
}
public double getVehiclePrice()
{
return vehiclePrice;
}
public void setDownPayment(double downPayment)
{
this.downPayment = downPayment;
}
public double getDownPayment()
{
return downPayment;
}
public void setSalesTax(double salesTax)
{
this.salesTax = salesTax;
}
public double getSalesTax()
{
return salesTax;
}
public String toString()
{
return getClass().getName() + "[vehiclePrice = " + vehiclePrice + '\n'
+ "downPayment = " + downPayment + '\n'
+ "salesTax = " + salesTax
+ "]";
}
public enum CAR_LOAN_TERMS {TWO_YEAR, THREE_YEAR, SIX_YEAR};
private double vehiclePrice;
private double downPayment;
private double salesTax;
Few questions.
(a) Is what I did in the Loan class to setClient correct given what I have in the Person class? (e.g.this.开发者_高级运维client = client)
(b) Can I call super twice in a method? I have to set two attributes from the Loan class from the constructor in the CarLoan class and I thought that would be a way to do it.
(c) Do you have to set attributes for enumeration types differently in a constructor or getter/setter methods? I get an error for (this.length = length) in my CarLoan class and I was unsure of how enumeration values should be set. Thanks!
OK, in order:
setClient
Looks perfectly fine. Nothing wrong with it. However, you want to avoid settingthis.client
directly in theCarLoan
constructor—you're already callingsetClient
(thanks to @Gabriel and @Aeth).- Sure, you can use
super
to access the parent class methods as much as you want. What you need to be careful with is calling the superclass' constructor, which you can only do once and at the beginning of the subclass' constructor.super != super()
. - Nope,
this.length = length
is fine. The problem is that you don't have a field calledlength
. You might want to add one of those.
1) It is conventional to put the declarations of the attributes of a class before the constructors and methods.
2) The statement this.client = client;
in the CarLoan
class will give you a compilation error because the client
field is declared as private in the Loan
class. (And that statement is redundant anyway because you just initialized the same field using the setter ... though expect you already knew that.)
3) A better way to initialize the fields of a superclass is to pass the arguments to the superclass constructor. For example:
public abstract class Loan
{
private Person client;
private double interestRate;
public Loan(Person client, double interestRate) {
this.client = client;
this.interestRate = interestRate;
}
...
}
public class CarLoan extends Loan
{
...
public CarLoan(Person client, double vehiclePrice, double downPayment, double salesTax,
double interestRate, CAR_LOAN_TERMS length)
{
super(client, interestRate);
this.vehiclePrice = vehiclePrice;
...
}
}
The reason this approach is better is that the Loan
class takes responsibility for its initialization, and doesn't rely on the various subclass constructors doing the job. (If you add an extra field to Loan
and add the corresponding parameter to the Loan
constructor, the compiler reminds you to modify all of the subclass constructors to provide the initial value in the super
constructor chaining. If the subclasses are responsible for setting fields in the base class during initialization, then the compiler won't notice that you forgot to add the new setter call.)
4) If you do call methods in a constructor, it is good practice to ensure that they cannot be overridden in a subclass. (No ... it is not entirely wrong for the methods to be overridden, but there are things that can go horribly wrong. Calling potentially overridable methods in a constructor makes your code fragile.)
5) If this was production code, use of float
or double
to represent currency values would be a big no-no!
Answering question (c), I think you're getting the error because you need to define length down there along with the variables you've already defined.
精彩评论