Calling an inner class in a main method in java - java

So I've already tried looking up what's causing this and comparing my code for any possible errors to others and I have yet to find anything else that would lead to this issue.
I'm trying to call the inner class Pair in order to store data.
Quick info about my project.
Take voting data and determine someone's political stance on it.
Right now I'm just trying to parse the data.
Example data
Rep1[tab]D[tab]-+-+-++---
I'm storing it as...
ArrayList<Pair<String,String>>
So rep1 is the place in the ArrayList and then D and -+-+-++--- are the pair.
But I'm having an issue with trying to instantiate the Pair class " non-static variable this cannot be referenced from a static context"
specifically
C:\Users\Stephanie\Desktop>javac DecisionTree.java
DecisionTree.java:26: error: non-static variable this cannot be referenced from a static context
Pair pair = new Pair();
^
1 error
Code:
public class DecisionTree{
public static void main(String[] args)
{
ArrayList<Pair> data = new ArrayList<Pair>();
FileReader input = new FileReader ("voting-data.tsv");
BufferedReader buff = new BufferedReader(input);
String line = null;
while((line=buff.readLine())!=null)
{
Pair pair = new Pair();
String[] array = line.split("\\t");
pair.setLabel(array[1]);
pair.setRecord(array[2]);
data.add(pair);
}
}
/**
* Private class to handle my inner data
*/
public class Pair
{
private String label;
private String record;
/**
* contructor
*#param String label, the label of the person's party
*#param String record, their voting record
*/
private Pair(String label, String record)
{
this.label = label;
this.record = record;
}
/**
* empty contructor
*/
private Pair()
{
}
/**
* get the label
*#return String label, the label of the person's party
*/
private String getLabel()
{
return label;
}
/**
* get the record
*#return String record, their voting record
*/
private String getRecord()
{
return record;
}
/**
* set the label
*#param String label, the label of the person's party
*/
private void setLabel(String label)
{
this.label=label;
}
/**
* set the record
*#param String record, their voting record
*/
private void setRecord(String record)
{
this.record=record;
}
}
}
Thanks! I feel like I'm missing something really basic, it's just been a long time since I've used Java

Non-static inner classes are associated with an instance of the enclosing class in Java. This means that an instance of class Pair in your example belongs to a specific instance of DecisionTree. You can only create it in the context of an instance of DecisionTree. You can't directly create a Pair using new Pair() in the main() method, because that method is static (so, it's not associated with an instance of DecisionTree).
If you don't want this, make the inner class static:
public class DecisionTree {
// ...
public static class Pair {
// ...
}
}

Make your Pair static, i.e.:
public static class Pair
Otherwise you cannot construct a Pair object in main(), because it is a static method. Inner classes (as opposed to static nested classes) require a surrounding instance.
Also your comment says Pair is private, but the class is marked public. Make it private if that is your intent.

Pair is an inner class. Instances of an inner class are associated with instances of the class they are a member of, and can only be created in the context of a parent instance.
If you declare Pair static it will become a nested class, which is more like a regular class. The enclosing class only contributes its name.

Related

using two classes in java

I am trying to use two classes Member class and Website class to talk to each other. I want to use the code which is in the setloggedInStatus() method in the Member class and be able to use it in the memberLogin() method which is in the Website class. I used the Member memberObject = new setloggedInStatus(); code but its giving me an error.
I Would appreciate any help. Thanks in advance
Website class
public class Website
{
// declaration of vars
private String websiteName;
private int hits;
private double salesTotal;
/**
* Constructor for objects of class Website
*/
public Website(String websiteName)
{
// initialise instance variables
this.websiteName = websiteName;
}
Member memberObject = new setloggedInStatus();
public void memberLogin() {
}
}
Member class
public class Member
{
// varibales declaration
private String email;
private int membershipNumber;
private boolean loggedInStatus;
/**
* Constructor for objects of class Member
*/
public Member(String memberEmail, int newMembershipNumber )
{
// initialise instance variables
email = memberEmail;
membershipNumber = newMembershipNumber;
}
//loggedInStatus method
public void setloggedInStatus() {
if (email != null && membershipNumber != 0) {
loggedInStatus = true;
System.out.println("you are logged in ");
}
else {
loggedInStatus = false;
System.out.println("you are not logged in");
}
}
}
If you wanted to use the functionality of Member inside the class Website, you would need to import it via import Member at the top of the Website file (depending on if they're in the same folder/package). This will make it available inside the file.
You could then create a new Member object via Member member = new Member(params go here);
Then, you could call the methods contained inside your Member class from your created member object, for example member.setLoggedInStatus();
EDIT: Did this answer your question?
if the Website Class and the Member Class are in the same package you have to create an object of Member like this:
String email = "Example#examplemail.com";
int id = 3; //Example id
Member the_member = new Member(email,3);
If you want to call the public void setloggedInStatus() method you can simply do something like this with the previous object created:
the_member.setloggedInStatus();
If the two classes are not in the same package you have to import the class Member with
import Member

Cannot find Symbol error in Java - why?

I am having a hard time understanding the object oriented world. I am working on a homework assignment and I can't understand why I am getting an error here. The issue I am having is in the add method. I am using the Netbeans IDE (per professor requirement) and the problem I am getting is in the add method. There are two errors that both say "Cannot find Symbol"; one is in reference to the variable customers while the other is in reference to the variable numCustomer. I am trying to understand what I am doing wrong, not just how to fix it.
What I have so far:
package homework6;
/**
*
* #author christian
*/
public class Homework6 {
// Declare variables
private int numCustomers = 0;
private Customer customer;
// Constructor
public Homework6() {
Customer[] customers = new Customer[50];
}
/**
* #param args the command line arguments
*/
public void main(String[] args) {
System.out.println("Christian Beckman N00963294");
System.out.println("Homework 6");
System.out.println(); // Prints a blank line
// Create and instance of Homework6
Homework6 homework6 = new Homework6();
homework6.execute(args);
}
private void add(Customer customer) {
int i = 0;
customers[i] = customer;
i++;
numCustomer++;
}
private void displayCustomers() {
}
private void execute(String[] args) {
}
private int getTotal() {
}
private void readFile(String filename) {
}
}
Your variable is numCustomers with an 's' but your method refers to numCustomer++; without an 's'.
It should be:
numCustomers++;
For
private Customer customer;
it should probably be:
private Customer[] customers;
Be very careful in your code where you refer to customer and customers. It looks like you are using the convention "customer" for just one and "customers" for the array. If that is too subtle for you then consider changing to something like oneCustomer and allCustomers.
You create an array of Customer objects in the constructor, then the array is immediately destroyed. Try declaring it like this:
public class Homework6 {
// Declare variables
private int numCustomers = 0;
private int i = 0;
private Customer customer;
private Customer[] customers;
// Constructor
public Homework6() {
customers = new Customer[50];
}
...
The reason for this, is any variables declared inside a method (in this case, the constructor) has something called local scope which means it can ONLY be accessed inside that method. The variables you declare outside the methods have something called global scope, which means that variable can be accessed across all the methods in a class.
For the same reason as above, i will keep resetting to 0 each time you call the add function. To fix that, declare private int i = 0 above the constructor with the other variables. Then write the method like so:
private void add(Customer customer) {
customers[i] = customer;
i++;
numCustomers++;
}
Also, whenever you do numCustomer++ in the add method, you should put numCustomers++ like above because you declared numCustomers with an 's' at the end. Has to match EXACTLY.

How affect class who have static attributes

I want to know how deserilize a class who contain staic attributes from file because when I create an instance from project , I can't affect it to the global class
My Code : ( deserialize method doesn't work )
public class Project implements Serializable{
private static String name;
private static String site;
private static Table table;
public static String getName() {
return Project.name;
}
public static void setName(String name) {
Project.name = name;
}
public static String getSite() {
return Project.site;
}
public static void setSite(String site) {
Project.site = site;
}
public static Table getTable() {
return Project.table;
}
public static void setTable(Table table) {
Project.table = table;
}
// Serialize
public static boolean serialize(String path){
try{
FileOutputStream fout = new FileOutputStream(path);
Crypto.encrypt(Project.class, fout);
return true;
}catch(Exception ex){
return false;
}
}
public static boolean deserialze(String path){
try{
FileInputStream fin = new FileInputStream(path);
Project project = (Project) Crypto.decrypt(fin);// decrypt file
Project.name = project.getName();
Project.site = project.getSite();
Project.table = project.getTable();
return true;
}catch(Exception ex){
return false;
}
Serialization works with objects — instances of classes. But static fields aren't part of an instance. So serialization doesn't touch them.
You're not actually serializing an instance of your Project class, though. You're serializing the class object itself, which is an instance of the java.lang.Class class. I can see why you'd think that might store your static fields, but it doesn't: a class object is for reflection, getting information about the class. It doesn't actually hold the class's data; the static fields in the class are not fields of the Project.class object. AFAIK, serializing a class object is generally not a useful thing to do.
Your fields look like they probably shouldn't be static anyway, because they hold information that should be different for each project. Right now, you have a single name that's shared across all projects, and a single site, and a single table. You could run new Project() fifty times and have fifty distinct objects, but there's no way to make them different from each other. Your program has no way to represent two projects with different names.
My advice: take out all the static keywords, change your static field references (e.g. Project.name) to instance field references (e.g. this.name), create an instance of your class (e.g. Project project = new Project()) and set its fields, and serialize that.
If you're going to implement java.io.Serializable interface remember that when you deserializing transient or static fields they most likely gonna have default value (null for Object types).
Static field also get default value if there are no objects in the scope (otherwise it get initialized with the value that is defined for an existing object).

return value from method without creating an object

Ok so I have a large structure of classes that looks something like THIS
Its for school and my instructor likes Starcraft, so lets just go with it.
Anyway I have a method in the GeneratorBuilding Class that is supposed to be able to instantiate a new Marine Object. However I need to know how many resources a Marine object costs.
I have an abstract int method in the abstract Unit class called unitCost(). Then the Marine class overrides this method and returns a value like 50.
I am looking for a way to have my GeneratorBuilding class get the return value for the unitCost() method in the Marine class without calling any specific Marine object.
I know that I could probably create a marine object and then ask how much it costs and then if I dont have the resources I would delete the object instead of pushing it into an ArrayList. But this seems almost like a workaround.
EDIT: The whole point is to be able to let ALL of my concrete classes inherit and override the UnitCost() method. So I could make it static but that ruins the whole point of an inheritance structure...
EDIT2: Since there was a request for example code (not exactly hard to imagine)
public void makeMarine(){
//uses resources and throws exception etc if there are not enough resources
Game.useResources(Marine.unitCost());
//creates a marine
Game.addMarine();
}
You can do this by declaring a specifically named static field in each class, and getting it through reflection}.
Suppose your classes look like this:
class ClassNumber1 {
public static final int cost = 123;
}
class ClassNumber2 {
public static final int cost = 321;
}
Then you can obtain their cost fields like this:
public static <T> int getCost(Class<T> cl) throws Exception {
// This is oversimplified: you need to check that the class
// indeed has a field called "cost" by null-checking the return value
// of getField(), verifying your cast, catching exceptions, and so on.
// But this will work in a "closed" system, when you know for sure
// that an int constant field does exist:
return (int)cl.getField("cost").get(null);
}
You call the method as follows:
System.out.println(getCost(ClassNumber1.class));
System.out.println(getCost(ClassNumber2.class));
Here is a demo on ideone.
If you really want a good, abstract OO solution to this problem, you should use the Abstract Factory Pattern.
Basically, this means you create a "factory" class whose only job is to create a specific type of unit. The nice thing about factory classes is that you can create an interface to represent your entire set of factories, and then pass around instances of the factories—which isn't really something you can do with normal class constructors.
A common pattern (which I would recommend here) is to use Anonymous Inner Classes with your abstract factory class or interface to create single instances of the "factory" for each unit type.
Here's a bit of example code to get you started:
/**
* Abstract class for Starcraft units
*/
public abstract class AUnit {
// . . .
}
/**
* Abstract factory for creating Starcraft units
*/
public abstract class AUnitFactory {
public abstract int unitCost();
public abstract AUnit createUnit();
}
public class Marine extends AUnit {
public static final int COST = 50;
/**
* Using an anonymous inner class to create an
* AUnitFactory instance for Marines
*/
public static final FACTORY = new AUnitFactory() {
public int unitCost() { return COST; }
public AUnit createUnit() { return new Marine(); }
}
// . . .
}
public class Zergling extends AUnit {
public static final int COST = 25;
/**
* Using an anonymous inner class to create an
* AUnitFactory instance for Zerglings
*/
public static final FACTORY = new AUnitFactory() {
public int unitCost() { return COST; }
public AUnit createUnit() { return new Zergling(); }
}
// . . .
}
/**
* Starcraft game!
*/
public class Game {
public addUnit(Player player, AUnitFactory unitFactory) {
// Get unit's cost
int cost = unitFactory.unitCost();
// Now deduct it from the player's resources
// . . .
// Create the unit
AUnit unit = unitFactory.createUnit();
// Now add the unit to the game for the given player
// . . .
}
// . . .
}
Now you could do something like Game.addUnit(player1, Zergling.FACTORY) or Game.addUnit(player2, Marine.FACTORY).
The nice thing is that you can pass the FACTORY instances around since they're just objects of type AUnitFactory. This means you could do something like have a combo box to select a unit type, and then a button which creates one of whichever unit type is currently selected in the combo box when clicked.
This is exactly what class methods are for. In a class method, unitCost() is a method of the Marine class itself (i.e. static public int UnitCost()), so you can call Marine.unitCost(), rather than m =new Marine() and then m.UnitCost().
Cool instructor. Wish I had one when I was taking OO.

Accessing data from a data class returning null

OK, I'm not super new to java but for some odd reason I can't figure out why this is not working for me. Basically I have 3 classes in my applet.
My main, my string constructor, and my data class.
The main class calls the string constructor, the string constructor stores its final product into the data class. Last, I'm trying to access the data class using my Main class.
The returned value to the main is always null and I can't figure out why. My suspicion is I'm somehow creating 2 separate data class objects but Ive looked at examples of code and it all seems correct. Here are the classes..
main.
public class LaneGUI extends javax.swing.JApplet {
private laneData laneData;
Timer timer;
/** Initializes the applet LaneGUI */
public void init() {
laneData = new laneData();
xmlParser.parseInputString(connection.getFinalXMLString());
System.out.println(laneData.getLaneID());
string contructor...
public class XMLParser {
private laneData laneData;
public void parseInputString(String input){
try{
/*some xmlparsing*/
laneData = new laneData();
laneData.setLaneID(string);
data class
public class laneData {
private String laneID;
public String getLaneID() {
return laneID;
}
public void setLaneID(String laneID) {
this.laneID = laneID;
}
}
There is a lot of editing here, like in the string class I took out all of the xml parsing and string editing.
Basically, when i check the getLaneID after i set it in the string constructor the value is correct. But when i call a get from the main, its null.
XMLParser and LaneGUI are referring to two different instances of laneData.
Instead of your final line in LaneGUI, which says this:
System.out.println(laneData.getLaneID());
You need something like this:
System.out.println(xmlParser.getLaneData().getLaneID());
You'll also, of couse, need to add a getLaneData() to XMLParser that returns it's laneData instance (or a deep copy thereof.)
As you rightly speculated, you have two different instances of laneData. The XMLParser class has a local instance of laneData different from the instance referenced by LaneGUI.

Categories

Resources