I have just started coding in java and am trying to wrap my head around classes.
I seem to be having trouble using a public attribute in another class. I have 3 classes: one contains the main method; and the other 2 are input and output. I am using non-static variables and methods and I don't want to use static.
Even though I have instantiated the input class in the output class, the output class fails to recognize the public attribute. Why is that so?
Here are the 3 classes:
package random;
import java.util.Scanner;
import java.util.Arrays;
public class random
{
public static void main(String[] args)
{
Scanner keyboard = new Scanner(System.in);
System.out.println("Please enter your first name: ");
input inputObject = new input();
inputObject.setFirstName();
output outputObject = new output();
outputObject.getFirstName();
}
}
package random;
import java.util.Scanner;
public class input
{
public String firstName;
public input() {}
public void setFirstName() {
Scanner keyboard = new Scanner(System.in);
this.firstName = keyboard.nextLine();
}
}
package random;
import java.util.Scanner;
public class output
{
public void getFirstName()
{
input inputObject = new input();
System.out.println("Your first name is " + inputObject.firstName);
}
}
The input object created in the getFirstName method in the output class is a separate instance from the one created in your main method. This means essentially you are creating a new instance of input where the input isn't set for firstName yet so when you print out that property there is nothing to print.
In addition the get and set methods for a single property should be inside the same class. The general way of doing this is like this:
class Foo {
private String property = "";
Foo () {}; //empty default constructor
//sets the property to what is passed in as a parameter
public void setProperty(String newProperty) {
this.property = newProperty;
}
//returns the property
public String getProperty() {
return this.property;
}
}
Generally all class properties should be private with public setters and getters. If you are new to programming I suggest reading up on this more.
It's because you're using two different input objects. We can tell this because your program has the following line twice
input inputObject = new input();
The input object you assign a name to is a different object from the one you try to read the name from.
It makes no sense for the class output to exist at all. You should just have a method getFirstName() in the input class.
(Also class names in Java usually begin with a capital letter.)
Related
I have a 2 class, one of which extends the superclass.
when I call the sub-class from the main, I get an error because "the method I call isn't a part of the class", but as my programme goes on, it should work
I had to use it only with the casting of class, but my teacher told me that casting should not be used in such a work, so please I'd like to understand where I'm wrong and where I can do better
(Im providing the code of 3 classes, the sub-class, the super-class, and the main)
Main
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.print("Type in the number");
int number = in.nextInt();
System.out.print("Type in the name");
String name = in.next();
Test testObj = new Test(number);
testObj = new TestSub(number);
testObj.setNameSub(name);
in.close();
}
}
Super class
public class Test {
protected int number;
protected String name;
public Test(int number){
this.number=number;
}
public void setName(String name){
this.name=name;
}
public String toString(){
return "the name is "+name+"the number is "+number;
}
}
Sub Class
public class TestSub extends Test {
public TestSub(int number){
super(number);
}
public void setNameSub(String name){
setName(name);
}
public String toStringSub(){
return toString();
}
}
The error I get is this:
The method setNameSub(String) is undefined for the type Test
In the main where there is this instruction : testObj.setNameSub(name);
The error here is (as indicated in the comments) that you initialize testObj as Test instead of TestSub, causing the error when the compiler isn't able to find setNameSub() between Test's methods.
So the easy solution is clearly to initialize testObj as a TestSub.
The correct solution that takes advantage of the methods inheritance would be to keep the initialization as it is but to call the method testObj.setName(name) instead, and deleting setNameSub() and toString() methods from TestSub class since they don't add any difference from the methods in the Test class.
For my assignment, the our programs are tested by running them through the command line, as they take arguments in the forms of file names, so I have to make sure my program runs when run through the command line. When I compile it without issue through jGrasp and eclipse, but when I attempt to compile it through the command line, this is what I get:
Cleary.java.35: error: cannot access T Collections.sort(studentObjects, idSorter);
class file for T not found
I don't know what T is, and I've never used T as a class in my programs?
Relevant code:
Main Class:
package ClearyAssignment5;
import java.util.Scanner;
import java.util.ArrayList;
import java.io.*;
import java.util.*;
public class Cleary {
public static void main(String[] args) {
//import the input file and add each line to an ArrayList of the students
try{
File input = new File(args[0]);
Scanner source = new Scanner(input);
ArrayList<String> listOfStudents=new ArrayList<String>();
while(source.hasNextLine()){
listOfStudents.add(source.nextLine());
}
ArrayList<Student> studentObjects = new ArrayList<Student>();
StudentIDComparator idSorter = new StudentIDComparator();
Collections.sort(studentObjects, idSorter);
FileWriter writer = new FileWriter(args[1]);
PrintWriter printWriter = new PrintWriter(writer);
for(int i=0;i<listOfStudents.size();i++){
(studentObjects.get(i)).printStudent(printWriter);
}
printWriter.close();
} catch(Exception e) {
System.out.println("Usage: ClearyAssignment4.Cleary input_file output_file");
}
}
}
Student Class:
package ClearyAssignment5;
import java.io.*;
import java.util.ArrayList;
import java.lang.*;
import jva.util.*;
public class Student {
//Initialize varaibles
String name;
int ID;
float GPA;
public Student(String studentName, int studentID, float studentGPA){
//Take the parameters which are passed in, and set them to the variables.
name = studentName;
ID = studentID;
GPA = studentGPA;
}
public int getID() {
return ID;
}
}
Comparator Class:
package ClearyAssignment5;
import java.util.*;
import java.lang.*;
import java.io.*;
class StudentIDComparator implements Comparator<Student> {
public int compare(Student a, Student b) {
return a.ID - b.ID;
}
}
I've removed some of the code which doesn't seem necessary for brevity... any help would be appreciated!
TL;DR: T is a generic type param that javac choked on somehow
T is a conventional name given to a Generic Type Parameter, which is used for Java's Generics system*. I'm not sure why the compiler choked on it, but the generics system in general has some occasional weird hiccups.
*An explanation of Generics (in case you haven't heard of them)
Imagine you are writing a class to hold a list of students. You want to be able to query if a person is on that list, as well as add people to that list. For now, this class will represent a course roster, so that professors can ensure that nobody is sneaking into their classes. Here is what the class will look like:
public class StudentList {
public boolean isOnList(Student s) { ... }
public void addToList(Student s) { ... }
}
Then imagine you need to create a new version of this class for the staff party at the end of the year, because only some staff are eligible (those who passed their performance review).
public class StaffList {
public boolean isOnList(Staff s) { ... }
public void addToList(Staff s) { ... }
}
Next, somebody asks you to create a new version of this class to keep track of the TAs for a course, since you can only pass assignments to grade to eligible TAs. You'd create yet another class:
public class TAList {
public boolean isOnList(TA t) { ... }
public void addToList(TA t) { ... }
}
You eventually get tired of writing such similar classes, so you want to create a single class which can perform all these functions. You would do so using Generics, so that client code can make a PersonList<Student> to hold Students, a PersonList<Staff> to hold Staff, a PersonList<TA> to hold TAs, and any other type of class you want.
public class PersonList<T> {
public boolean isOnList(T t) { ... }
public void addToList(T t) { ... }
}
The T is a generic type parameter here. When creating an instance of the class PersonList, you pass it a type inside the angle brackets. Then that type replaces all instances of T. The convention is to use single letter names, such as T for type, E for element, K for key, V for value, etc.
Well, I rewrote this program in a completely new directory, and it compiled and ran without issues. I don't know why that fixed it, but I guess it did.
I am trying to access the super class variable name from user input.
I am not sure how to have the super class variable name point to the user input. Here is the code for it. Any ideas thank you.
package chapter4;
import java.util.Scanner;
public class VetOffice extends Animal {
public VetOffice(int lifeExpectancy, int weight, String name, Character gender, String type) {
super(lifeExpectancy, weight, name, gender, type);
// TODO Auto-generated constructor stub
}
public static void main(String[] args) {
Scanner console = new Scanner(System.in);
System.out.print("Please enter name of pet");
//super(name);
//= console.next();
//}
}
}
//}
The thing is you cannot access super class variables in main method. Because it is static method. If you want to access in main() you have to make Animal class name variable to static. Then you can assgin a value directly in main().
Like this:
in Animal class,
static String name;
in VetOffice,
name = console.next();
You can try different ways depending on the thing that you are going to achieve you have to decide,
Is this variable can be declare as static or not? Because static variables common for every object.
Another way you can do this is,
Create getters and setters for Animal class member variables. Then also you cannot access in the main method because also you have to make those methods and variable to static.
As a solution without makinng them static or a new methods even getters and setters in super class you can create default constructor for super class and assign values like below:
If your variable in the super class is private you have to create getters and setters.
public static void main(String[] args) {
Scanner console = new Scanner(System.in);
System.out.print("Please enter name of pet");
VetOffice pet = new VetOffice();
pet.name = console.next();
System.out.println(pet.name);
}
Note: create default constructor If it is unnecessary to create object from VetOffice or super class seeing that you have to pass values to constructor.
UPDATE:
According to your comment
If your variable in the super class is private do this:
public static void main(String[] args) {
Scanner console = new Scanner(System.in);
System.out.print("Please enter name of pet");
VetOffice pet = new VetOffice();
pet.setName(console.next());
System.out.println(pet.getName());
}
Another way that you asked for in the comment:
Animal class(partialy implemented to show you)
public class Animal {
int lifeExpectancy;
static int weight;
static String name;
Animal(int lifeExpectancy, int weight, String name, Character gender, String type){
this.weight = weight;
this.name = name;
}
public static String getName() {
return name;
}
public static void setName(String n) {
name = n;
}
}
Then in the main method:
Animal.setName(console.next());
System.out.println(Animal.getName());
Im doing a question that requires you to make a class customers which will later on be added into an array list in the method of another class. However I am getting an error on the line i marked ERROR, that says:
"No enclosing instance of type Question3 is accessible. Must qualify the allocation with an enclosing instance of type Question3 (e.g. x.new A() where x is an instance of Question3)." And I have no clue why.
public class Question3 {
static ArrayList<customers> a= new ArrayList<customers>();
private static Scanner kbd;
public static void main(String[] args)
{
String input="";
double price=1;
String name="";
while(price != 0)
{
System.out.println("Customer Name: ");
name= kbd.nextLine().trim();
System.out.println("Purchase Price: ");
price= Double.parseDouble(kbd.nextLine().trim());
addSale(name,price); //ERROR
}
}
public static void addSale(String name, double price)
{
customers c= new customers(name,price);
a.add(c);
}
public class customers
{
String name;
double price;
public customers(String name, double price)
{
this.name=name;
this.price=price;
}
}
}
You also have to initialize the kbd variable as:
kbd = new Scanner( System.in );
Please review your code using this suggestion and the others above.
A main method is static and thus has static context. No instance of Question3.class is required for a thread to enter that code block. Your class customers is defined inside of Question3. Because it is an inner class, it has implicit access to the fields and methods inside of the Question3 class, but it requires an instance of Question3 to be able to achieve that behavior. You need to move the code you have now in main(String args[]) into a constructor for the class Question3, and create an instance of Question3 in your main method like so :
public static void main(String args[]) {
Question3 myQuestion3 = new Question3();
}
Alternatively as mentioned by others, you could make your customers class static. This will solve the issue by effectively making customers a top level class, but you will lose the ability to implicitly access the fields and methods of its enclosing type, which is the Question3 class.
First off Great job so far. However, there are a couple of errors that I see in the code.
First you class should be a static class. You are trying to use static methods without a static class.
public static class Question3 {
static ArrayList<customers> a= new ArrayList<customers>();
private static Scanner kbd;
public static void main(String[] args)
{
Also, you need to create your scanner for the user to input an object.
private static Scanner kbd = new Scanner(System.In);
Do these and your code will work perfectly!
You should change the declaration your class customers to solve this issue.
Currently its a non-static inner class. You should change it to static inner class.
public static class customers
Non-static inner classes refers implicitly to the instance of the container class. Here you trying to create new instance of customer class in a static function, you don't have Question3 instance there.
Just change your inner class to a public static class:
public static class customers {
And the error disappears :)
There are two problems in your code.
First , you have to initialize scanner object by providing System.in parameter to it.
Second , while creating customer object you have to follow proper syntax.
Here is the working code:
public class Question3 {
static ArrayList<customers> a= new ArrayList<customers>();
private static Scanner kbd=new Scanner(System.in); // <---- Notice this
public static void main(String[] args)
{
String input="";
double price=1;
String name="";
while(price != 0)
{
System.out.println("Customer Name: ");
name= kbd.nextLine().trim();
System.out.println("Purchase Price: ");
price= Double.parseDouble(kbd.nextLine().trim());
addSale(name,price); //ERROR
}
System.out.println(a);
}
public static void addSale(String name, double price)
{
// customers c= new customers(name,price);
Question3.customers c = new Question3().new customers(name, price); // <---Notice this
a.add(c);
}
public class customers
{
String name;
double price;
public customers(String name, double price)
{
this.name=name;
this.price=price;
}
} }
So I'm trying to figure out how can I have 3 classes call one another.
this is the main class.
public class TestStudent {
public static void main(String[] args) {
myStudent mystudent_obj = new myStudent();
mystudent_obj.show_grades();
mystudent_obj.change_grades();
mystudent_obj.show_grades();
}
}
This is the 2nd class that's being called in the class above;
The 2nd class call another 3rd class and try to manipulate it
using two functions. Function show_grades just print out the variables in the 3rd class
and function change_grade try to change the variables in the 3rd class.
public class myStudent {
public void show_grades(){
Student student_obj = new Student();
System.out.println(student_obj.studGrade);
System.out.println(student_obj.studID);
}
public void change_grades(){
Student student_obj = new Student();
student_obj.studGrade='V';
student_obj.studID=10;
}
}
This the 3rd call, which only has two variables.
public class Student {
public int studID = 0;
public char studGrade = 'F';
}
when I run the program it runs without errors and I get an output of:
F
0
F
0
however, I can see that the function show_grades work and it does display the grades, but
the function change_grades does not change the grades:
The end results, should be something like this
F
0
V
10
because the change grade function, should have changed those variables... so what's going on?
In your myStudent class you are creating a new instance of Student in each method, meaning that each method has a local variable of class Student. When you call show_grades the second time, a new instance is created, with the default values of 0 and F.
If you create a variable and use that instead, your change grades will change the variables of the instance variable instead of a local variable in each method. This is due to scoping in programming, which you can read more about at Wikipedia.
public class myStudent {
private Student student_obj = new Student();
public void show_grades() {
System.out.println(student_obj.studGrade);
System.out.println(student_obj.studID);
}
public void change_grades(){
student_obj.studGrade='V';
student_obj.studID=10;
}
}