I have a student object that can hold name and mark.
public class Student{
Public String name;
Public int mark;
public Student (int argMark, String argName)
{ mark=argMark; name=argName;}
}
when I create a student as :
Student john = new Student(70, "John");
I need to change the mark later while keeping the previous marks
Student temp = john;
temp.mark = 60;
when I print them out they both have 60 marks
System.out.println(temp.mark);
System.out.println(john.mark);
the system shows the answer of : 60 for both of them
I know I can extend a class and have a method for get, set methods and override it, but this is not acceptable for my assignment. Is there any other way to do this?
You can create copy constructor and by doing that you can have new reference with the same attribute values in your temp. Currently John and Temp have same reference and change in one will get reflected in other.
public Student (Student student) {
this.mark = student.getMark();
this.name = student.getName();
}
Few suggestions,
Use getter and setter methods instead of accessing variables directly.
Follow naming conventions. i.e. start variable name with lower case.
When you say
Student Temp = John; // <-- typo for John
you assign a reference to the same instance that Jhon references. Based on your question, you expect a second instance. Something like
Student Temp = new Student(John.Mark, John.Name);
Also, by convention Java variable names start with a lower case letter.
Related
I am learning Java at University but I am struggling to understand why you would assign a variable to itself inside a constructor.
This is example code:
private String name;
private int age;
private boolean student;
private char gender;
public Person(String name, int age, boolean student, char gender)
{
this.setName(name);
this.age = age;
this.student = student;
}
I am struggling to understand the purpose of 'this.age = age' and 'this.student = student'. These values are already assigned to whatever they hold so why would you need to do that? My only theory is that it is to initialize the variable but I'm not sure.
You are not assigning the variable to itself, this.VAR and VAR are different variables.
When using a class in Java, you can refer to your attributes by using the this prefix. In many methods the this prefix is optional because there is not any method parameter with the same name. However, when a method has variables that have the same name than the class attributes, it is mandatory to use the this prefix to differentiate between the class attribute and the method parameters (otherwise the most local variable - the method parameter - hides the most global one - the class attribute).
So when you are using:
this.age = age
you are initializing your class attribute to the value of the method parameter called age.
Notice that you can avoid using the this prefix if the method parameters have always different names than the class attributes:
private String name;
private int age;
private boolean student;
private char gender;
public Person(String name, int ageParam, boolean studentParam, char genderParam){
setName(name);
age = ageParam;
student = studentParam;
gender = genderParam;
}
Personally, I think that using the this prefix is more polite because you can quickly look if you are modifying your class attributes and the method parameters preserve its useful name (which is better to document and understand the code).
The critical point here is that there are two variables called age. The first is the local variable which is a parameter to the constructor; the second is the instance variable of the Person class.
Inside the constructor, the parameter hides the instance variable, so just writing age will always refer to the parameter. However, if you write this.age, you must be referring to the instance variable. Thus:
this.age = age
assigns the value of the constructor parameter to the instance variable.
This is only because of naming conventions that you have this, in fact this is 100% the same :
private String name;
private int age;
private boolean student;
private char gender;
public Person(String nnn, int aaa, boolean sss, char ggg){
this.setName(nnn);
this.age = aaa;
this.student = sss;
this.gender = ggg;
}
But with this, this. becomes useless, because age = a; is ok, that's why when there is a misunderstand possible you use this. to precise that it's the attribute of the class, different of the parameter of the constructor.
this.age = age , this.age is the variable associated with class Person's object (this keyword refers to the class' object reference) , and age is a local variable (it's scope is just within constructor definition) whose value that you are passing in the constructor to be assigned to the object's variable.
So when you call class's constructor when creating object :
Person p = new Person("name",22,true,'M');
the p object's age will be set as 22 .
If you would have used :
public Person(String name, int yearsOld, boolean student, char gender)
{
this.setName(name);
age = yearsOld;
//here you could avoid using this since local variable name is different and age will refer to class level's age .
this.student = student;
}
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I am fairly new to Java proramming, as I have already stated in the title I want to pass some parameters that could or could not exist as instances of a class. If it does not exist, I want to create it. My code so far:
public class TestClass {
public static void main(String[] args) {
Person Ted = new Person();
Person Jack = new Person();
Item it = new Item(Ted);
Item itSec = new Item (Pierce); //Person Pierce doesn't exist => should be created
}
}
public class Person {
public Person(){
//some code
}
}
public class Item {
public Item(Person name){
if(!(name instanceof Person)){
Person name = new Person(); //create that missing instance
}
else{
//some code
}
void getItem(Person name){
System.out.println(name);
}
}
You misunderstand some things.
You can't use an identifier before it's been declared. The following is not correct in your code:
Item itSec = new Item (Pierce);
That's because you didn't declare Pierce before this line. You don't have to create an instance of the class, but you need a valid identifier. You should have declared it before this way:
Person Pierce;
At this moment the identifier, or the reference, is empty, so to say, or it is equal null. All object references which are not local are initiated this way, or they are equal false or 0, whichever is correct for their type. The result is the same as if you declared explicitly:
Person Pierce = null;
But let's move on. Say the reference has been declared. (Btw, Java uses camelCaseNotation for variables, so pierce would be correct.) Let's say we're at a point when Pierce is null or refers to some object, we don't know. Now we call this:
Item itSec = new Item (Pierce);
new Item(Pierce) calls the constructor public Item(Person name){...} in the class Item, which you should know. But now, in that constructor there's the line:
if(!(name instanceof Person)){
which you misuse. What this line is checking is not if the variable name equals null or an existing object, but variable type of name is a subtype of Person. Which will always return true in this place, as the function heading public Item(Person name){...} says this: the function is public, is a constructor, and the argument is of type Person (so Person or a subtype).
What you want to say here is this:
public Item(Person name){
if(name==null)){ //if the reference is empty
this.name = new Person(); //I'll explain this below
}
else{
this.name = name; //otherwise the local "name" will stay null
}
}
I used this.name and it was a jump ahead. Why? In your code that is Person name = ..., which is not correct as that name wouldn't last once the constructor's finished. You need a field in the Item class object, which will hold this value. So the Item class might be defined this way:
public class Item {
Person name;
//...
}
And now the field name holds the value assigned in the line:
this.name = new Person();
You need to use this to disambiguate which name you means. One is the Item class field, the other one is Person name the constructor parameter.
Now, we go back to the main function. If you want the variable Pierce to reference the newly created Person, this still needs to be done. The assignment can take place here, but first you'd have to create a function in the class Item that returns the value of its field name. So:
getName() {
return name;
}
And now call it from the main function:
Pierce = itSec.getName();
That's it. Finally, this function doesn't make sense:
void getItem(Person name){
System.out.println(name);
}
}
It doesn't get any Item. It only prints what you pass to it. And this doesn't mean that if you call it with getItem(Pierce), you will see "Pierce" on the screen. It will call the toString function in the object Pierce denotes, and as it is, you will get a standard object identifier. But if you define a function:
void printItem() {
System.out.println(name);
}
Then you can call it this way. For an existing object itSec:
itSec.printItem();
As for a getter function, it should return what you ask for, but that's another story.
What do you expect without instancing?
Person Pierce = new Person();
Item itSec = new Item (Pierce);
You cannot use a variable that does not exist...
Item itSec = new Item (Pierce);
The snippet above will never work because Pierce is undefined.
The code:
if(!(name instanceof Person)){
Person name = new Person(); //create that missing instance
}
Does not really make any sense, because that is the same as calling
Person Ted = new Person();
Person Jack = new Person();
Wherein the Person instance does not actually contain any data (unless you have some magic going on when instantiating the Person!)
I assume what you really want to pass is not an object whose variable is the name of a person, but rather a Person object that contains the name of the person.
If so, your code should be like this:
Person p1 = new Person("Ted");
Person p2 = new Person("Jack");
If you really want to do some instantiation if something does not exist, you might be able to do something like this:
Item(String personName) {
if(isExisting(personName)) {
getPerson(personName);
} else {
Person p = new Person(personName);
}
boolean isExisting(String personName) {
// Check if person exists somewhere
}
Person getPerson(String personName) {
// Retrieve the Person instance with the same person name.
}
if(!(name instanceof Person)){
Person name = new Person();
}
is meaning less because 'name' is always object is instance of person in this situation..
Item itSec = new Item (Pierce);
Pierce is not an object.. We can pass only Person object to constructor of Item class.. There is no any method to create an object of any class by just passing unkown variable..
Item itSec = new Item (Pierce); //Person Pierce doesn't exist => should be created
If it does not exist, I want to create it.
There's no "if" about it. The code never declared that variable, so it will never exist. (And never compile in its current state. Surely your Java compiler is telling you this.) Given that it always needs to be created, just create it:
Person Pierce = new Person();
Item itSec = new Item(Pierce);
Edit: Based on ongoing comments, it sounds like you want to have something more like a Map. Consider an example:
Map<String,Person> people = new HashMap<String,Person>();
people.put("Pierce", new Person());
The Map would basically be a collection of key/value pairs where the name is the key and the Person is the value. You can dynamically add/edit/remove elements to the collection as you see fit.
Then to use it, you'd call another operation on the map:
Item itSec = new Item(people.get("Pierce"));
You could use various operations to check if a value exists in the collection, add it, etc. You might even extend the class to add your own operations which create one if it doesn't exist when trying to get it.
Java won't dynamically create variables for you if a variable doesn't exist, but operations on a Map (or potentially other similar structures) can check if an element exists, add it, remove it, etc.
I know there are standard way by add a constructors to the class. But for classes with object superclass (has no-argument constructor) I tend to find using a temporary object simpler. Is there any down side for such an act.
import java.util.ArrayList;
public class Main {
public static void main(String[] args){
// data available in two separated arrays
String[] dName = {"Sam","Ben","Joye","Sarah","Tim","Lucy","Jack"} ;
int[] dAge= {10,52,53,15,12,60,21};
// Array list to put the data in
ArrayList<Person> personList =new ArrayList<Person>(7);
for (int i=0;i<dName.length;i++){
Person tempPerson = new Person();
tempPerson.name= dName[i];
tempPerson.age= dAge[i];
personList.add(new Person());
personList.set(i,tempPerson);
tempPerson=null; //removes the reference
}
for (int j=0 ; j<personList.size();j++){
System.out.println(personList.get(j).name+" age is "+personList.get(j).age );
}
}
}
class Person{
String name;
int age;
}
the output
Sam age is 10
Ben age is 52
Joye age is 53
Sarah age is 15
Tim age is 12
Lucy age is 60
Jack age is 21
You should avoid statements that do nothing - an optimization would be to do
for (int i=0;i<dName.length;i++){
Person tempPerson = new Person();
tempPerson.name= dName[i];
tempPerson.age= dAge[i];
personList.add(tempPerson);
}
No need to first add the person to later replace it
No need to null the reference - the list will keep the reference to the temp object in any case.
Instead of setting values directly you could use setters (setName() instead of .name = )
If you'd use setters, you could implement a Builder pattern:
like this:
public Person setName(String aName) {
name = aName;
return this;
}
Resulting in something like
personList.add(new Person().setName(dName[i]).setAge(dAge[i]));
Then again - the two value constructor will probably be the easiest of all - and it don't matter that the super class doesn't have a constructor:
public Person(String aName, int aAge) {
name = aName;
age = aAge;
}
//You can have more than one constructor
public Person() {
}
and then
personList.add(new Person(dName[i], sAge[i]));
You should use a constructor for Person. Then you have just one call in your for-loop:
personList.add(new Person(dName[i], dAge[i])
Also, in your implementation, you are doing the necessary work twice, because you call personList.add(new Person()) and then you call personList.set(i, temPerson). If you don't want a constructor in your Person-class, a call of personList.add(tempPerson) for example would be enough.
Not really,
you could maybe make use of java8 streams, but why make your life harder, it wouldnt add anything new
First it starts off with the class College tester, it askes the user for a command.
The first command will be to add. what adding does is it askes the user to enter a name ( with at least 2 words by identifying a space) and an address.
Then it creates a student object with it. and I add the student object to a arraylist.
Issue #1: How would i add the collegetester input and create a student object out of it
Issue #2: after how would i add it to the array College
Collegetester (where i get user input)
import java.util.Scanner;
public class CollegeTester {
Scanner input = new Scanner(System. in );
private String command;
public String name;
public static void main(String[] args) {
CollegeTester collegeTester = new CollegeTester(); //creates object
collegeTester.getCommand(); //goes to command
}
//Ask user for a command
public void getCommand() {
System.out.println("Enter a command: ");
command = input.nextLine();
if (command.equals("add"))
addCommand(); //If command is add go to addcommand
}
//Add name and address to student object
public void addCommand() {
String name = "";
do {
System.out.println("Enter a Name: ");
name = input.nextLine();
} while (!(name.contains(Character.toString(' ')))); //To check if the name has at least 2 words
System.out.println("Enter an Address: ");
String address = input.nextLine();
Student student = new Student(name, address);
getCommand(); //repeat to see if user wishes to add another
}
}
Student object (The student object)
public Student(String name, String address) {
if (name == null)
name = "";
if (address == null)
address = "";
this.name = name;
this.address = address;
lastAssignedNumber++;
studentNum = lastAssignedNumber;
}
and the arraylist (In a different file)
import java.util.ArrayList;
public class College {
private ArrayList <College> entries = new ArrayList<College>();
}
Let's do a quick analysis of your code:
Your Student object looks like a constructor for the Student class object type which is most likely in this case an inner class of the CollegeTester class.
So here's the deal, your addCommand() already connects your CollegeTester class with your Student class, by executing this command after you provide the input for name and address it creates a new instance of the Student object.
This means that at this point, you need to add this newly created Student object to your College list.
However if you take a good look at your College list you will see that:
It's marked private (meaning it can be accessed only from within itself)
It is a list of College type objects (but you need a list of Student type objects)
So your options at this point are:
Make the list public
Create a public setter method that will do the adding
You will also need to change the list object type to Student if you wish to store Student objects in the list.
Also unless you want to have multiple colleges you might consider declaring your list as static otherwise you will have to declare an instance of it to add the Student objects to it.
Hopefully this is enough information to get you started in the right direction.
Also an advice is to not look at classes as actual objects, instead look at them as blueprints that can be used to construct those real objects.
The main method should call a constructor in the Object array class that create's the Object CollegeTester ct.
ct = new CollegeTester();
Then a method to insert new students, that calls the Student constructor in the student class to create a new student Object.
ct.insert("input1", "input2");
write an insert method that calls to create a new student and adds that object to College.
Constructor to add values to the new student object:
String studentName;
String studentAddress;
public Student(String name, String address) {
studentName = name;
studentAddress = address;
}
note: with ArrayList you could simply use the method add of ArrayList.
Hi everyone once again thanks for taking the time to look at my issue.
I am trying to create a program that keeps track of employees and the diffrent departments that they are working in.
The program first reads from a text file all the initial data to get the program going. The program then has a while loop within a while loop. The first loop will read the department details and then create the department
in then the next (inner) while loop it reads all the employees accosiated with this department,It then after reading the details of the employee creates the employee and adds it to the previously created department to say this is the department I work in.
after adding all the employees to the department, it then exits that inner loop and sends the department with the employees inside it to the mainDriver for storage. It does this for the remaining departments again adding their associated employees and so on.
The problem Is: it seems to create each department okay and add it to the mainDriver, but all the employees are added to the first department and the remaining department are left empty. Which is not the way it should work as their are several employees in each department.
Why is it not moving on to the next department as the new Department is instantiated??
Could I please have some help to see where I may be going wrong.
this is the code that read in the data.
while (index < numberOfDepartmentsToRead )
{
String depName1 = inFile.nextLine();
String location1 = inFile.nextLine();
String numberOfEmps = inFile.nextLine();
int numberOfEmps1 = Integer.parseInt(numberOfEmps);
Department newDepartment = new Department(depName1 , location1);
while (i < numberOfEmps1 )
{
String fName = inFile.nextLine();
String lName = inFile.nextLine();
String gender = inFile.nextLine();
String address = inFile.nextLine();
String payLevel = inFile.nextLine();
int dPayLevel = Integer.parseInt(payLevel);
Employee employeesFromList = new Employee(randomIDno, fName, lName, gender, dPayLevel);
newDepartment.setAddEmp(employeesFromList, randomIDno);
i++;
}
i = 0;
index++;
MainDriver.setDepartmentToSystem(newDepartment);
}
the employee is passed to this method in the departments class
public static void setAddEmp(Employee theEmp, int idNumber)
{
employeesInThisDepartment.add(theEmp);
employeeMap.put(idNumber, theEmp);
}
the department is added to the mainDriver classes storage method which is this
public static void setDepartmentToSystem(Department theDepartment)
{
allDepartments.add(theDepartment);
}
public static void setAddEmp(Employee theEmp, int idNumber)
Why is it static? Make it instance method.
Make employeesInThisDepartment instance variable instead of static.
You might want to check your use of static. It is difficult to know without seeing all your code but I wonder if setAddEmp should not be a static method.
Your employeesInThisDepartment is a static variable, whereas you need one per-Department.
Each Department should have its own instance, with an employees property, to which the department's employees are added. Similarly, the method to add an employee to the department should be an instance method, not static.
Binyomin, i think your inner while controller makes wrong...
while (i < numberOfEmps1 ){ i++; }
I think this loop will traverse all the employees in the file. Then the next iteration of the inner loop will return EOF...
Try posting your file structure..