I am "learning Java" using a tutorial. One of the lessons involves constructors calling constructors.
After the lesson I did some playing around doing "strange stuff" and I can't figure out what is happening.
I attached an image file captured from the Eclipse screen. (don't be hating).
I thought that would be better because it shows the output screen.
I would expect "name" to be "Arnie" the first time it is printed in the second constructor.
Why is it "Bertie"?
class Machine {
private String name;
private int code;
public Machine() {
this("Arnie", 0);
System.out.println("First constructor running: " + name);
}
public Machine(String name) {
this("Arnie", 0);
System.out.println("Second constructor running before 'this.name': " + name);
this.name = name;
System.out.println("Second constructor running after 'this.name': " + name);
}
public Machine(String name, int code) {
this.name = name;
this.code = code;
System.out.println("Third constructor running: " + name + " " + code);
}
}
public class Application {
public static void main(String[] args) {
Machine machine1 = new Machine();
Machine machine2 = new Machine("Bertie");
Machine machine3 = new Machine("Chalkie", 7);
}
}
It is printing the name variable that is passed in to the constructor. Leaving everything the same, you would see "Artie" if you were to change name to this.name.
The reason is that the constructor that takes the name argument is shadowing the property String name. Either change constructor argument to something other than name, or change lines 12 and 14 to be this.name.
Related
Besides the get and set method, I created a method called printAllDetails with the purpose to print out details of every registrant. There are 3 registrants with each of their respective names and ages.
public class BASIC_GettersSetters {
String name;
int age;
public static void main(String[] args) {
BASIC_GettersSetters a = new BASIC_GettersSetters(); // Assume BASIC_GettersSetters is Account
a.setName("Kim Hyun Jin");
a.setAge(32);
System.out.println(a.getName());
System.out.println(a.getAge());
a.setName("Kang Jeon Il");
a.setAge(32);
System.out.println(a.getName());
System.out.println(a.getAge());
a.setName("Choi Jin Woo");
a.setAge(30);
System.out.println(a.getName());
System.out.println(a.getAge());
a.printAllDetails();
}
The method is right at the bottom. When I pressed the F6 key to run the program, it only shows the last registrant; Choi Jin Woo, 30. So I'm confused right there. Should I use array? But then, how do I apply it together with get and set methods? Or should I use something else that I don't know of?
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return this.name;
}
public int getAge() {
return this.age;
}
public void printAllDetails () {
System.out.println("Registrants : " + getName() + " // " + getAge());
}
}
Any help is appreciated. Thank you. - Coding noob
You're creating one instance of BASIC_GettersSetters and repeatedly changing the values. So when you call printAllDetails it's printing the last set of values.
You want to create separate instances:
BASIC_GettersSetters a = new BASIC_GettersSetters();
a.setName("Kim Hyun Jin");
a.setAge(32);
System.out.println(a.getName());
System.out.println(a.getAge());
BASIC_GettersSetters b = new BASIC_GettersSetters();
b.setName("Kang Jeon Il");
b.setAge(32);
System.out.println(b.getName());
System.out.println(b.getAge());
BASIC_GettersSetters c = new BASIC_GettersSetters();
c.setName("Choi Jin Woo");
c.setAge(30);
System.out.println(c.getName());
System.out.println(c.getAge());
a.printAllDetails();
b.printAllDetails();
c.printAllDetails();
You should also consider renaming BASIC_GettersSetters() to something more meaningful.
You create only one object (new BASIC_GettersSetters()). If you call the setter on the same object multiple times, you overwrite the previously set value.
First, you should name your classes properly. I suggest renaming your BASIC_GettersSetters to Registrant. Second, you should create as many Registrant objects as needed (in your case, three).
import java.util.ArrayList;
import java.util.Scanner;
public class JavaApplication10Arraylistandobjects {
static Scanner user_input = new Scanner(System.in);
public static void main(String[] args) {
test();
}
public static void test(){
ArrayList<mainclass> me = new ArrayList <> ();
mainclass ob;
for (int i=0;i<2;i++){
ob = new mainclass();
System.out.println("name");
ob.name = user_input.nextLine();
System.out.println("sname");
ob.sname = user_input.nextLine();
me.add(ob);
}
System.out.println("Show List: " + me);
System.out.println("Confirm if is true or false: " + me.get(1).toString().contains("max"));
System.out.println("what is index of: " + me.get(1).toString().indexOf("max"));
}
}
public class mainclass {
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSname() {
return sname;
}
public void setSname(String sname) {
this.sname = sname;
}
#Override
public String toString() {
return "mainclass{" + "name=" + name + ", sname=" + sname + '}';
}
String name;
String sname;
}
My questions is how can I find correctly indexOf string.
For example when I am checking if string "max" exist - it shows me "true"
and when I am trying to find index of string "max" it shows me index 15 which is not correct.
P.S. I found an article with the same problem where it says that I have to override equals and hashcode - I've done it but anyway I got the same problem.
Please point me to the right direction.
What I am doing wrong here, can someone explain me pls.
These are my inputs and output.
run:
name Jony
sname Bravo
name max
sname hitman
Show List:[mainclass{name=Jony, sname=Bravo}, mainclass{name=max, sname=hitman}]
Confirm if is true or false: true
what is index of: 15
BUILD SUCCESSFUL (total time: 11 seconds)
The line:
System.out.println("what is index of: " + me.get(1).toString().indexOf("max"));
has a problem, in that you're getting the object in the me list at index 1, getting its toString(), and looking for "max" in there. What you actually want to do, as I understand it, is look through the me list and find the place in the list with "max" in it.
P.S. I found an article with the same problem where it says that I have to override equals and hashcode - I've done it but anyway I got the same problem.
If you did that, it would allow you to do something like this:
x = new mainclass();
x.setName("Max");
System.out.println("what is index of: " + me.indexOf(x));
However, there's still a potential problem. Unless you set your equals() and hashCode() to only look at the name and not also sname, then it's not going to find anything unless the sname also matches.
There is an error somewhere inside of this code and I do not know how to fix it. When in eclipse it says that the variable is not initialized then I initialize the object with null. When I do this it says only c.courseCode can be initialized with null. Please help me!
class Course {
String courseCode;
String courseName;
int duration;
}
public class CourseTest {
public static void main(){
Course c;
c.courseCode = "C0001";
c.courseName = "Programming in Java";
c.duration = 4;
System.out.println("Course Code + " + c.courseCode);
System.out.println("Course Name + " + c.courseName);
System.out.println("Course Duration in Months: " + c.duration);
}
}
Course c = new Course();
When you create an object, you are creating an "instance" of a class,
therefore "instantiating" a class. The new operator requires a single,
postfix argument: a call to a constructor. The name of the constructor
provides the name of the class to instantiate.
reference
public class CourseTest {
public static void main(){
Course c = new Course(); <----- object is not instantiated in your code
c.courseCode = "C0001";
c.courseName = "Programming in Java";
c.duration = 4;
System.out.println("Course Code + " + c.courseCode);
System.out.println("Course Name + " + c.courseName);
System.out.println("Course Duration in Months: " + c.duration);
}
}
The code doesn't instantiate the object that has to be created for holding the values.
You need to create the Course object with new in order to use it
The main method should receive String[] args in input
Therefore, these are the 2 lines you need to change:
public static void main(String[] args){
Course c = new Course();
I have a problem retrieving a Student's info from a list, or deleting it... Heelp... Code below:
import java.util.*;
public class Directory
{
private TreeMap<String, Student> studentList;
private int numberOfEntries;
public Directory()
{
studentList = new TreeMap<String, Student>();
numberOfEntries = 0;
}
public void addStudent(Student newStudent)
{
studentList.put(newStudent.StudentInfo(), newStudent);
//numberOfEntries++;
}
public void StudentInfo(String StudentInfo)
{
Object obj = studentList.get(StudentInfo);
System.out.println(obj);
}
public void removeStudent(String StudentInfo)
{
Object obj = studentList.remove(StudentInfo);
System.out.println(obj + "Removed");
}
public void printStudentList()
{
System.out.println("List of Students: " + studentList.keySet());
}
}
======= Student class ======== (Persons contains first, last & email)
public class Student extends Persons
{
private String Sclass;
public Student(String Lname, String Fname, String Email, String Sclass)
{
super(Lname, Fname, Email);
this.Sclass = Sclass;
}
public String StudentInfo()
{
return " Full Name " + Lastname + " " + Firstname + "\n" +
"E-Mail: " + Email + "\n" +
"Class Attending: " + Sclass;
}
public String getName()
{
return Lastname;
}
}
I could try and debug this for you, but that would defeat the purpose. (This is your homework ... and the purpose is for you to learn how to do this yourself.)
My advice is as follows:
FIRST fix the style errors:
The names of variables should always start with a lower-case letter ... unless they are static final constants.
The names of methods should always start with a lower-case letter
Method and variable names should also be meaningful and consistent. For instance:
public void removeStudent(String StudentInfo)
Here StudentInfo actually needs to a student name, not a "student info" string as created by the StrudentInfo method ...
Another example: lname and fname are not meaningful. (I can guess what they mean, but that is not good enough.)
Create yourself a tester program that created instances of those classes and performs a sequence of tests on them. Start with simple things, then move on the more complicated ones.
(In the real world, we'd set up a more formal set of "unit tests" ... but you are probably not ready for that yet.
In fact, if you choose more meaningful names, and then look carefully at how those names are used, your error should "leap out and hit you on the nose".
But you will get maximum benefit if you go through the process yourself.
I have a test file and according to it I need to build my program the test file
is below. However, I confused by s1.showDetails(System.out); I have never met
System.out in parameter can anyone help. What to do with it??? when I am trying to write showDetails() the compiler writes mistake. my student code is beneath this Thank you in advance!
import java.util.*;
public class Q2 {
public static void main(String [] args)
{
// Start on section A
System.out.println("Question 2");
System.out.println("Start on part A");
Student s1 = new Student("John", "Smith", 42);
s1.showDetails(System.out);
Course cs = new Course("Computer science");
}
}
public class Student {
private String name;
private String familyName;
private int moduleMark;
private int total;
protected Student(String name, String familyName, int moduleMark)
{
this.name = name;
this.familyName = familyName;
this.moduleMark = moduleMark;
}
public String getName()
{
return name;
}
public String getFamilyName()
{
return familyName;
}
public int getModuleMark()
{
return moduleMark;
}
public String showDetails()
{
return (this.name + " " + this.familyName + " " + moduleMark + total);
//print(name);
}
}
System.out is a variable like every other variable.
System is a class
out is a public static variable inside System of type PrintStream. So you can access it with System.out
So System.out.println(..) is just a call to the println(..) function of a PrintStream
So your function should look like:
public String showDetails(PrintStream stream) {
...
}
The error pretty much describes what the problem is.
The method showDetails() in the type Student is not applicable for the arguments (PrintStream) at Q2.main(Q2.java:9)
The program tries to call your method with System.out which happens to be a PrintStream. So, change your showDetails to
public String showDetails(PrintStream out) {
out.println(this.name + " " + this.familyName + " " + moduleMark + total);
}
This allows the tester (I assume there is a program which tests your assignment for correctness) to give you any PrintStream, either System.out or any other PrintStream.
The error essentially means that the compiler didn't find the method with the name showDetails that takes an argument of type PrintStream. You have no need to pass the System.out to the showDetails() method. The correct way writing the showDetails() is below. Read about System.out.
public void showDetails()
{
System.out.println(this.name + " " + this.familyName + " " + moduleMark + total);
}
Your program can't compile.
Your main is using a method named showDetails that takes a PrintStream as a parameter (System.out). And you are defining only a method named showDetails without parameter.
Look at the doc of System.out. It s a field like any other of the class System. Indeed it's somewhat special as it is static but that doesn't change the game that much...
So write a method with the correct parameter list and you will get closer.
public String showDetails(PrintStream stream) {
//your code here
}
showDetails should write to the stream passed in parameter.
While you are at learning programming. Try to separate query from command. It's a good principle : a method should do one thing : either do something to your current object using a parameter or answer a query about the state of your current object. Not both.
Here you return a string and require a stream... You should better split that into 2 methods : one to get the string and then as second one to call stream.write on that string.
public String toString() {
//your code here
}
public void showDetails(PrintStream stream) {
//your code here
}
Since the print is commented out from your showDetails message there are 2 obvious solutions
The showDetails message is not meant to print out anything (despite the name) and you should just print it out in the main method
System.out.println( s1.showDetails() );
The showDetails message should print the String to any PrintStream, and then you have to adjust both the signature of that method as well as the implementation
public String showDetails(PrintStream stream) {
stream.println( ... );
}