Good morning, I'm using the following constructor code and for some reason the "position" variable sets to null every time a new object is created.
This is my class code
public class Employee
{
private String name;
private int idNumber;
private String department;
private String position;
public Employee(String nam, String depart, String posi, int id)
{
name = nam;
department = depart;
posi = position;
idNumber = id;
}
}
And this is the line I'm using to create the object.
Employee sMeyers = new Employee("Susan Meyers", "Accounting", "Vice President", 47899);
It should be
position = posi;
and not
posi = position;
You're assigning here a null variable (position) to an immutable parameter (posi).
The other answers already stated that your mistake is
posi = position
Luiggi Mendoza also made a comment stating that you should use "this"!
I just want to give you a complete example on how it should be done.
public class Employee
{
private String name;
private int idNumber;
private String department;
private String position;
public Employee(String name, String department, String position, int idNumber)
{
this.name = name;
this.department = department;
this.position = position;
this.idNumber = idNumber;
}
}
Accessing your class variables explicit by this also spares you the hassle of making up new variable names like "nam" and "pos".
For your constructor argument posi, you want to take that value and assign it to one of the class fields which in this example would be position. Now, what you're doing is assigning position (which is null) to posi. So you're overwriting your argument with null and not really doing anything with it.
What you want to do is the following:
position = posi;
which assigns the constructor argument i.e. "Vice President to the class field position.
Remember the variable on the right is assigned to the variable on the left.
Thats because you of this statement:
posi = position;
Change it to
position =posi;
Use "this" pointer to avoid these errors. Happy Coding !!
Related
This question already has an answer here:
Why Cannot refer to instance fields while explicitly invoking a constructor java
(1 answer)
Closed 3 years ago.
I created my main use constructor with three parameter passed. the parameter above a default parameter. the goal is to set the first field which is name to be default assume user doesnt input a name. the problem come as for creditLimit and email i get the error below. why is this and what is it i do not understand? and what are the fixes.
- Cannot refer to an instance field creditLimit while explicitly invoking a
constructor
- Cannot refer to an instance field email while explicitly invoking a
public class VipCustomer {
private String name;
private int creditLimit;
private String email;
public VipCustomer()
{
this("Default",creditLimit,email);
}
public VipCustomer(String name, int creditLimit, String email) {
// TODO Auto-generated constructor stub
this.name = name;
this.creditLimit = creditLimit;
this.email = email;
}
public String getName()
{
return this.name;
}
public int getCreditLimit()
{
return creditLimit;
}
The Problem
There seems to be an issue with your first constructor which calls with second constructor with the following parameters at runtime:
this ("Default", 0, null);
This is because the values of creditLimit and email are not set.
creditLimit defaults to 0 as that is the default for ints.
email defaults to null because it is an empty object reference.
The Solution
To fix this issue, I recommend having some final fields at the top of your class that define default behavior.
public class VipCostumer {
// Change these values to what you would like.
public static final String DEFAULT_NAME = "Default";
public static final int DEFAULT_CREDIT = 100;
public static final String DEFAULT_EMAIL = "example#abc.com";
public VipCostumer() {
this(DEFAULT_NAME, DEFAULT_CREDIT, DEFAULT_EMAIL);
}
// rest of your code
}
Trade Off
While this may resolve your issue, I would recommend you consider whether or not you want to have defaults for something as specific as a costumer. Depending on your usage, you may want all costumer data to be differentiable, and creating a lot of a default costumers will take that ability away.
There is a problem with your first constructor, because it will call the second constructor (the one with the parameters), but you just try to set undefined variables to themselves.
If your goal is to set the first field which is name to be default assume user doesnt input a name, use this constructor
public VipCustomer()
{
this.name = "Default";
}
if creditLimit and email is a required value while name is not
public VipCustomer(int creditLimit, String email) {
this.name = "Default";
this.creditLimit = creditLimit;
this.email = email;
}
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.
Unsure on how i'm supposed to add to an array, i've been asked to fill the array from a test file but define it in class Patient. Any ideas?
public class Patient
{
private String name;
private int id;
private int current = 1;
public Patient(String name, int id)
{
this.name = name;
this.id = id;
Patient[] patient = new Patient[100];
String[] Observations;
System.out.print(patient[0]);
}
public String addPatient(String name,int id)
{
Patient[current-1] = new Patient(name,id);
}
}
// extract from class PatientRecordSystem
public void addPatient()
{
String name = "James";
int id = 10122;
Patient patient = new Patient(name, id);
}
Your problem is that you are defining that list (or array) to hold Patient objects within the constructor of your Patient class.
That is simply wrong on many levels. First of all - one "Patient" should be exactly that - the representation of a single patient. When you go to the doctor and become a patient ... are you asked to know about 100 other patients around?! Then: that array that you define in the constructor ... just lives during the execution of the constructor. It simply goes away as soon as a call
Patient newPatient = new Patient( ... )
returns.
In other words: you want to think of another class that is responsible for "managing" multiple patients. And then you create "patient objects"; and tell the manager about them. And that "manager" is then using an array (or better some more dynamic List) in order to keep track of "managed" patients.
Whatever Andrew said is correct , just making it easy for you. Use below code
public class Patient
{
private String name;
private int id;
private int current = 1;
private Patient[] patient = new Patient[100];
public Patient(String name, int id)
{
this.name = name;
this.id = id;
String[] Observations;
System.out.print(patient[0]);
}
public String addPatient(String name,int id)
{
patient[current-1] = new Patient(name,id);
}
}
// extract from class PatientRecordSystem
public void addPatient()
{
String name = "James";
int id = 10122;
Patient patient = new Patient(name, id);
}
First you need to declare the array.
You can do something like:
Patient[] patients = new Patient[100];
if you know the size of the array.
If you want to build a dynamic array, because you don't know how many elements you are going to have, you can do something like that.
List<Patient> patients = new ArrayList<Patient>();
Then you can assign values to the array:
If you have declared a fixed array you can do something like that:
patients[0] = new Patient(name, id);
On the other hand, if you have declared a dynamic array, the code would look like:
patients.add(new Patient(name, id));
I've recently started programming with Java and I like to know if there is a way to register(like put in array or something) certain object field values.
In this case, for example all "name" values(private final String name) of created objects.
Any help would be greatly appreciated.
public class Item {
private int amount;
private double price;
private final String name;
private final String type;
private final String madeIn;
Item(int amount, double price, String name, String type, String madeIn){
this.amount=amount;
this.madeIn=madeIn;
this.name=name;
this.type=type;
this.price=price;
}
You have many data structures in Java in the Collection family like List or Set. You also have associative (key/value) collections with Map and its sub-classes.
Trying to read between the lines in your question, you may want to have some collection of Items that you want to access through there name field.
Assuming the name is unique in an Item and you have getters for the properties:
Map<String, Item> itemsByName = new HashMap<>();
// put some items...
itemsByName.put(item1.getName(), item1);
itemsByName.put(item2.getName(), item2);
// etc...
// Looking for an item knowing its name
String key = "Foo";
Item itemFound = itemsByName.get(key);
if (itemFound==null) {
System.out.println("There is no item whose name is " + key);
}
else {
// do something with itemFound
}
There's nothing stopping you from adding some static Set member to your class that would contain all the names of the created instances.
Inside the Item constructor you can add name to this Set.
public class Item {
private int amount;
private double price;
private final String name;
private final String type;
private final String madeIn;
private static Set<String> registeredNames = new HashSet<String>();
Item(int amount, double price, String name, String type, String madeIn)
{
registeredNames.add (name); // you should consider what you want to do
// if the same name is passed to two instances
// perhaps throw an exception
this.amount=amount;
this.madeIn=madeIn;
this.name=name;
this.type=type;
this.price=price;
}
}
Just create a static List of names and keep on adding that in the constructor like:
private final static List<String> names = new LinkedList<String>();
public Item(..) {
names.add(name);
}
I got a obstacle class and there i got this:
public Obstacle(final String name, final String action, final Position position) {
this.name = name;
this.action = action;
this.position = position;
}
In my main class i define an obstacle;
Obstacle trapdoor= new Obstacle("Trapdoor","Open",new Position(3097,3468,0)) ;
How do i retrieve the position from that obstacle? Or more in general how do i get one of those arguments?
You can simply use a getter method, for example :
public Position getPosition()
{
return this.position;
}
In the main class
Obstacle trapdoor= new Obstacle("Trapdoor","Open",new Position(3097,3468,0));
Position pos = trapdoor.getPosition();
You define a method getPosition in the Obstacle class that returns the position. It is called a getter.
You get the position with trapdoor.getPosition().
And you do the same for any member of the class that should be accessible to users of that class.
Like this
public Obstacle(final String name, final String action, final Position position) {
this.name = name;
this.action = action;
this.position = position;
public String getName()
{
return this.name;
}
...
}
In your code:
Obstacle trapdoor= new Obstacle("Trapdoor","Open",new Position(3097,3468,0)) ;
String valueName = trapdoor.getName();