Every time I create an object of the class it returns the same value every time, even if the object is different with different values. How can I make sure that this doesn't happen?
class Something{
protected String name;
protected static double price; // need the value later
public Something(String xName, double xPrice){
name = xName;
price = xPrice;
}
public String returnName(){
return name;
}
public static returnPrice(){
return price;
}
}
If you need the value of price as unique to object, you should not declare it as static. If you declare as static, it will be accessible within all objects of given class and it won't belong to object.
Related
I created a new class "Lecturer" which extends another class "Person", i wanted to make 2 constructors for Lecturer and one would accept a name and a stipend (just a constant to say how much pay is), the other just accepts the name and uses the default stipend set in the code. i included appropriate getters and setters. I then wrote a writeOutput method to print an output similar to this
Name: (name) which gets the name and prints it
Stipend: (stipend) same process ^
heres what i have so far
Lecturer.java
public class Lecturer extends Person{
private static String name;
static double stipend;
public Lecturer(String name) {
super(name);
}
public Lecturer(String name, double stipend) {
super(name);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getStipend() {
return stipend;
}
public void setStipend(double stipend) {
this.stipend = stipend;
}
public static void writeOutput() {
System.out.println("Name: " + name);
System.out.println("Stipend: " + stipend);
}
}
Person.java
public class Person {
/** Every Person has a name */
private String name;
/** Person requires a name */
public Person(String n) {
this.name = n;
}
/** return this Person's name */
public String getName() {
return this.name;
}
/** Change this Person's name */
public void setName(String nn) {
this.name = nn;
}
Main file (Inheritance.java)
Lines 41-53
Lecturer l1 = new Lecturer("Zachary");
Lecturer l2 = new Lecturer("Wilhelmina", 11017.00);
l1.writeOutput();
l2.writeOutput();
pause();
l1.setName("Zack");
l1.setStipend(10800.00);
l1.writeOutput();
pause();
System.out.printf("%s's stipend is $%,4.2f.\n",
l1.getName(), l1.getStipend());
System.out.printf("%s's stipend is $%,4.2f.\n",
l2.getName(), l2.getStipend());
This is the output
Name: null
Stipend: 0.0
Name: null
Stipend: 0.0
press enter...
Name: Zack
Stipend: 10800.0
The 2nd part works as it should but the first one isnt and i tried to change the code but nothing is working properly.
In Lecturer you are declaring another name variable. This variable is separate from the name variable declared in Person. The call to the superclass constructor is setting the name variable in Person, not in Lecturer. But you don't need the second variable; remove it. You can access the name in Person via the getName method you've already declared. This means that you also don't need to re-declare getName and setName in Lecturer, so the Lecturer class can inherit them.
Also, in Lecturer, the two variables you've declared shouldn't be static. Per the above reasoning, name shouldn't even be there, but even if it should be there, it shouldn't be static. The variable stipend should be there, but it shouldn't be static. When you declare a member variable static, then there is only one variable for the entire class, no matter how many instances you create, which doesn't sound like what you want.
Your constructors should initialize stipend.
You have a static variable inside Lecturer which has the same name as the inherited one from Person and your getter is referring to that static one - are you sure you want these static variables? For completeness if you really want to keep the static one and the inherited one with the same name then change your getter to read return this.name; which will return the inherited name instance variable.... But that method can be inherited from Person class...
There are two name fields in your program , one is private static String name; in Lecturer.java and another is private String name; in person.java .
The thing is that you are just calling Lecturer javs's name field but not setting it.
Fixed the project based on rgettman answer.
Lecturer class should look like this:
public class Lecturer extends Person {
double stipend = 9144;
public Lecturer(String n) {
super(n);
}
public Lecturer(String n, double stipend) {
super(n);
this.stipend = stipend;
}
public double getStipend() {
return stipend;
}
public void setStipend(double stipend) {
this.stipend = stipend;
}
public void writeOutput() {
System.out.println("Name: " + this.getName());
System.out.println("Stipend: " + getStipend());
}
}
public class EmpRecord {
private String name;
private int id;
public EmpRecord(String name, int id) {
this.name = name;
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
In above Class, Setters are there to set the value for those two Private variables, but what is the purpose of doing the same inside the Constructor? What is difference between those two - assigning global variables to local inside a Constructor and also in Setter?
In constructor, you are initiating the field.
In the setter, you are overwriting the field.
For a single instance, you can initiate it only once, while you can set multiple times.
That is not case of global and local variable.(It's parameterized constructor).
Whenever you're creating instance of class at same time you're assigning values to it's fields.
If you don't do that then you have to call setter methods of field through instance variable.
public EmpRecord(String name, int id) {
this.name = name;
this.id = id;
}
explanation:
whenever you create instance of class EmpRecord like:
EmpRecord obj = new EmpRecord("foo", 111);
Here you're directly assigning value foo to EmpRecord.name and and 111 to EmpRecord.id.
If you don't do this then if you wish the assign value then you've to do:
obj.setId(111);
obj.setName("foo");
So it's nothing more than assigning values to fields at instance creation time.
If you initialise in the constructor, then once the object is created, you won't be able to change the variables' values. What if you want to override the initial values at some later point of time? You'll need setters for that since the variables are private.
Here's are two classes, Passenger and Car. Instead of initializing all private members of the Car class in all constructors, I thought of setting default values for them and overwriting specific members' values if provided by the instance creator.
import java.util.ArrayList;
class Passenger {
private String name;
Passenger(String name) {
this.name = name;
}
}
class Car {
private String color = "red";
private int numberOfWheels = 4;
private ArrayList<Passenger> passengers = new ArrayList<Passenger>();
Car() {}
Car(String color) {
this.color = color;
}
Car(int numberOfWheels) {
this.numberOfWheels = numberOfWheels;
}
public void addPassenger(Passenger p) {
this.passengers.add(p);
}
}
Is it safe to set default values to class members like this? Any pitfalls to avoid for any particular data types (even other than the ones I have used)?
Yes, it is safe.
Personally I prefer initialize where is declaration if is a common value for all constructors. If I have more constructor is not very pleasure to write that thing multiple times. And for me is more clear what value have.
Finding Java an overly complicated language. I can't figure out this association thing if my life depended on it. I'm specifically stuck on the Cab object +pickup(rider:Passenger): String. I know it will return a String and here's the code I have so far.
UML Diagram
package cabsimulation;
public class Cab {
private double companyTotalFare;
private double rate;
private double taxiTotalFare;
private int tripCounter;
private int cabID;
public Cab(int cabID){}
public double dropOff(int minutes){
return minutes*rate;
}
public double endOfShift(){
double sumOfFares = taxiTotalFare + companyTotalFare;
return sumOfFares;
}
//public String report();
public double getRate(){
return rate;
}
public void setRate(double cabRate){
this.rate = cabRate;
}
}
and
public class Passenger {
private final double weight;
private final boolean inFrontSeat;
public Passenger (double weight, boolean front){
this.weight = weight;
this.inFrontSeat = front;
}
public double getWeight(){
return weight;
}
public boolean isInFrontSeat(){
return inFrontSeat;
}
}
How do I write (program) an association between these two objects?
As written in your instructions: define a typed attribute
private Passenger passenger;
or the like (I'm no Java guy).
When you want to have an association between two classes, you will normally use an instance variable. In this case, a Cab can contain a Passenger. So you want to have an instance variable in the Cab class which is able to hold a Passenger. This can be done like that:
public class Cab {
Passenger passenger;
//...
}
In the pickUp method shown in the UML, you want to fill this variable, e. g. like that (unfortunately, there is no specification what String the method should return):
public class Cab {
Passenger passenger;
//...
public String pickUp(Passenger rider) {
this.passenger = rider;
return "something";
}
}
After you called the method pickUp, you can access the passenger in the cab via its instance variable.
I hope I could help you!
usually, if you have an attribute, you have the getter/setter which are dedicated to set and to get the attribute.
If you have a method (other than a setter) with a parameter of the type of an attribute, it does not mean that the parameter will set the attribute.
So for me, it could be easier to remove the method pickup and to define a getter and setter on passenger.
I want to make my immutable class EmployeeDetails which has Employee object in it. I have followed conditions to make class immutable:
1. class is final
2. class members are final
3. no setters
If EmployeeDetails is immutable, I should not be able to change content in it. Still, I can change employee name or id.
What I am missing here?
public class TestImmutable{
public static void main(String args[]){
EmployeeDetails empd1 = new EmployeeDetails("ABC", new Employee(1, "n1"));
System.out.println("Id : " + empd1.getEmployee().getId());
System.out.println("Name : " + empd1.getEmployee().getName());
System.out.println("Empr : " + empd1.getEmployer());
empd1.getEmployee().setId(2);
empd1.getEmployee().setName("n2");
System.out.println("\nId : " + empd1.getEmployee().getId());
System.out.println("Name : " + empd1.getEmployee().getName());
System.out.println("Empr : " + empd1.getEmployer());
}
}
final class EmployeeDetails{
private final String employer;
private final Employee emp1;
public EmployeeDetails(String employer, Employee emp1){
this.employer = employer;
this.emp1 = emp1;
}
public String getEmployer(){
return this.employer;
}
public Employee getEmployee(){
return this.emp1;
}
}
class Employee{
public int id;
public String name;
public Employee(int id, String name){
this.id = id;
this.name = name;
}
public int getId(){
return this.id;
}
public String getName(){
return this.name;
}
public void setId(int id){
this.id = id;
}
public void setName(String name){
this.name = name;
}
}
Get rid of getEmployee(). You shouldn't be able to reach Employee emp1 outside EmployeeDetails. If you need access to the fields in Employee emp1, then provide public methods that return them.
For example:
final class EmployeeDetails{
private final String employer;
private final Employee emp1;
public EmployeeDetails(String employer, Employee emp1){
this.employer = employer;
this.emp1 = emp1;
}
public String getEmployer(){
return this.employer;
}
public String getEmployeeName() {
return this.emp1.getName();
}
...
}
I have followed conditions to make class immutable: 1. class is final
2. class members are final 3. no setters
The conditions you have laid out are necessary but not sufficient to make a class immutable. Confused?
Immutability is about preserving the state of class instances for all time. Once an instance of a class is created, then all the attributes that comprise the state of that instance must remain forever unchanged.
What happens if 1 through 3 above are satisfied, but one of your instance fields is a mutable class? In this case, returning the reference to that instance field to a client makes it possible for the client to mutate the state of your supposedly immutable class.
One solution is to perform defensive copying upon all instance fields of the immutable class that are, themselves, mutable. Instead of...
public Employee getEmployee(){
return this.emp1;
}
change this code so that a new copy of the Employee object is returned to the client. This assures that clients can not get a reference to the internal state of the instances of your immutable class:
public Employee getEmployee(){
return this.emp1.clone(); // this solution assumes that Employee
// is safely cloneable, which requires some
// care on your part. An alternative is
// to define a copy constructor in the
// Employee class and: return new Employee(emp1);
}
Defensive copying is necessary for all mutable components of an immutable class, and this rule must be applied during both construction and field access. Otherwise, you make it possible for client code to retain a reference to the mutable internal state of your class.
Making a variable final means that you cannot assign it again to some other object. You can still modify the state of the object whose reference it holds.
In this case :
final class EmployeeDetails{
private final String employer;
**private final Employee emp1;**
}
You cannot assign emp1 to a new object but you can still change the state of the employee object as it is not immutable. You can make Employee objects immutable by removing all the setters.
The EmployeeDetails class is not immutable. You have followed the usual rules for immutability except one. In Joshua Bloch's Effective Java this rule is stated as follows:
Ensure exclusive access to any mutable componenent.
In your case, since the class Employee is mutable, you need to copy Employee instances in the getter and the constructor.
public Employee getEmployee() {
return new Employee(emp1.getId(), empl.getName()); // Copy
}
public EmployeeDetails(String employer, Employee emp1){
this.employer = employer;
this.emp1 = new Employee(emp1.getId(), empl.getName()); // Copy
}
Since this version uses copies, it is not possible to modify the internals of the EmployeeDetails class.
This solution is very common. For example, the String class is immutable. Both the constructor String(char[] value) and the method char[] toCharArray() make copies of the array. This is necessary because arrays are mutable.
Another solution, which may be more appropriate for your situation, is to make Employee immutable as well.
You could even get rid of the Employee class completely and just use two fields in the EmployeeDetails class.