I have a child (extended) class with a protected attribute height.
I want to access it in the main program:
while(line != null)
{
String[] field = line.split("#");
int height = Integer.parseInt(field[0]);
if (field.length ==1)
{
forest[cnt] = new Trees(height);
}
else
{
forest[cnt] = new Shrub(height, field[1]);
}
cnt++;
line = inS.readLine();
}
inS.close();
String s = JOptionPane.showInputDialog("Enter Name to search for");
for(int i = 0; i<forest.length; i++)
{
if (forest[i] instanceof Shrub)
{
String a = forest[i].getName();
System.out.println ("Found");
}
}
}
However I get an error saying that it cannot find the method getName, however when i run the lol Shrub it works fine?
Thanks.
Private access modifier methods are not accessible in child class. Make them Public or Protected.
Related
I'm writing a simple script in Java that is calling another class that holds all my information.
I am holding my information in the called class in Object[] Arrays and I am planning on calling the script to fetch that array.
Right now the function looks like this.
public void tradeShop() {
/*
*Variables must be initialized in order to call shopTrader
*The values are just non-null placeholders and they are
*replaced with the same values in the tradeValues Object array.
*/
String targetName = "NPC Name";
String itemName = "Item Name";
int itemQuantity = 1;
int minCoins = 1;
int minBuy = 1;
boolean stackable = false;
Object[] tradeValues = shop.defaultValues;
for (int i = 0; i < tradeValues.length; i++) {
if(String.class.isInstance(tradeValues[i])) {//String check
if(i==0) { //0 is NPC Name
targetName = (String) tradeValues[i];
} else if (i==1) { //1 is Item Name
itemName = (String) tradeValues[i];
}
} else if (Integer.class.isInstance(tradeValues[i])) { //Int check
if(i==2) { //2 is Item Quantity
itemQuantity = (Integer) tradeValues[i];
} else if (i==3) { //3 is Minimum coins
minCoins = (Integer) tradeValues[i];
} else if (i==4) { //4 is the Minimum Buy limit
minBuy = (Integer) tradeValues[i];
}
} else if (Boolean.class.isInstance(tradeValues[i])) { //Bool check
stackable = (Boolean) tradeValues[i]; //5 is the item Stackable
} else {
//TODO: Implement exception
}
}
//Calls ShopTrader() method shopTrader
ShopTrader trade = new ShopTrader();
trade.shopTrader(targetName, itemName, itemQuantity, minCoins, minBuy, worldHop, stackable);
}
I feel like using a for loop like this is not the correct way for me to be looping through these Objects, I shouldn't have to check i== for each variable.
Also it hinders me from adding overloads to the shopTrader method as I would have to write an entirely new for loop for each overload.
Does anyone have a more elegant solution for getting the variables from this array?
I think that instead of storing all of your information in Object[], you may want to create a new class to act as a data structure i.e.
public class TradeValue {
String targetName;
int itemQuantity;
// etc.
String getTargetName() {
return targetName;
}
String getItemQuantity() {
return itemQuantity;
}
// etc
}
You can then just access the information directly
TradeValue defaultValues = shop.defaultValues;
String targetName = defaultValues.getTargetName();
int itemQuantity = defaultValues. getItemQuantity();
...
I have a very stupid problem that's giving me a major headache.
I defined a method which searches an ArrayList to find a zipcode:
public ZipCode findZip (int zip) {
ZipCode aZip = new ZipCode(0);
for(int i = 0; i < zips.size(); i++) {
if(zips.get(i).getZipCode() == zip)
aZip = zips.get(i);
else
aZip = null; }
return aZip; }
...But, I cannot call it for the life of me. It gives me the "cannot find symbol" error every time I call it, no matter what object I use or parameter I input.
The entire program so far (it can't be finished until I figure this out):
import java.util.*;
import java.io.*;
import java.lang.Math;
public class ZipCodeDatabase {
//Field
private ArrayList<ZipCode> zips;
//Constructor
public ZipCodeDatabase () {
zips = new ArrayList<ZipCode> ();
}
//Mutator Method
public void readZipCodeData(String filename) {
Scanner inFS = null;
FileInputStream fileByteStream = null;
try{
// open the File and set delimiters
fileByteStream = new FileInputStream("zipcodes.txt");
inFS = new Scanner(fileByteStream);
inFS.useDelimiter("[,\r\n]+");
// continue while there is more data to read
while(inFS.hasNext()) {
//read in all input
int aZip = inFS.nextInt();
String aCity = inFS.next();
String aState = inFS.next();
double aLat = inFS.nextDouble();
double aLon = inFS.nextDouble();
//Create and add new zipcode
ZipCode newZip = new ZipCode(aZip, aCity, aState, aLat, aLon);
zips.add(newZip);
}
fileByteStream.close();
// Could not find file
}catch(FileNotFoundException error1) {
System.out.println("Failed to read the data file: " + filename);
// error while reading the file
}catch(IOException error2) {
System.out.println("Oops! Error related to: " + filename);
}
}
//Accessor Methods
public ZipCode findZip (int zip) {
ZipCode aZip = new ZipCode(0);
for(int i = 0; i < zips.size(); i++) {
if(zips.get(i).getZipCode() == zip)
aZip = zips.get(i);
else
aZip = null;
}
return aZip;
}
public int distance(int zip1, int zip2) {
int dist = 0;
double p1 = 0.0;
double p2 = 0.0;
double p3 = 0.0;
if(zips.findZip(zip1) == null || zips.findZip(zip2) == null)
dist = -1;
...
The error itself is:
cannot find symbol - Method findZip(int)
You are using a symbol here which has not been declared in any visible scope.
Using ZipCodeDatabase.findZip(int); gives the following compiler error:
non-static method findZip(int) cannot be referenced from a static context
You are trying to reference an instance field or instance method from a static method.
I'm currently working through this, get back with more updates if needed. Thank you for all given help.
ZipCode itself isn't really in play for this issue, its just a bunch of set and get methods for the zips.
The problem comes from this line:
if(zips.findZip(zip1) == null || zips.findZip(zip2) == null)
Going up to the top of your class, we find the declaration of zips, which is
private ArrayList<ZipCode> zips;
This is a problem, because your findZip method is on the ZipCodeDatabase class, not on ArrayList. Since that call is happening from inside of a non-static method of ZipCodeDatabase, you can simply remove the object you're calling it on.
if(findZip(zip1) == null || findZip(zip2) == null)
This is equivalent to using
if(this.findZip(zip1) == null || this.findZip(zip2) == null)
which calls the method on the current instance of the ZipCodeDatabase class.
Try this and see if it works.
ZipCodeDatabase database = new ZipCodeDatabase();
database.readZipCodeData("SomeFilename.txt"); // hardcoded in code as zipcodes.txt
ZipCode myZip = database.findZip(1234);
in the first line you instantiate the class and in the second you load it with data, and in the third you use the same instance to find the code.
The first two methods are chunks out of my GUI programme. There are various text fields that allow me input data and then buttons on the GUI take this data and call different methods.
public String getTenant()
{
String theTenant = (tenantsNameText.getText());
return theTenant;
public int getPropertyNumber()
{
int propertyNumber = -1;
try{
propertyNumber = Integer.parseInt(propertyNumberText.getText());
if (properties.size() == 0){
propertyNumber = -1;
}
if (propertyNumber < 0 && propertyNumber >= properties.size()){
propertyNumber = -1;
}
}
catch(NumberFormatException exception){
}
return propertyNumber;
}
In this method I to take the data from the text field of "getTenant" and the data from the text field of "getPropertyNumber". What I'm not sure how to do is check if the property number is -1 or not, and this needs to be verified in the method "addTenant".
public void addTenant()
{
}
I possibly didn't ask the question right, but i figured it out with some help from a colleague.
public void addTenant()
{
int index = getPropertyNumber();
String newTenant = getTenant();
if(index != -1){
Property property = properties.get(index);
if(property instanceof PropertyToLet){
PropertyToLet propertyToLet = (PropertyToLet) property;
propertyToLet.addTenant(newTenant);
}
}
}
I have a constructor ID3 and I need to start by executing it from the main. Is it possible?
I tried doing this:
public class ID3
{
public static void main(String[] args) throws Exception
{
System.out.print("\f"); //clears the screen
ID3 instance = new ID3("data.txt", 5 , 14 , "", 5);
instance.ID3("data.txt", 3 , 5 , " ", 2); //error given here since this line had to be removed
}
public ID3(String fName, int numAttributes, int testCases, String delimiter, int limitSplits) throws IOException, FileNotFoundException
{
fileName = fName;
n = numAttributes;
t = testCases;
numSplits = limitSplits;
FileInputStream fstream = new FileInputStream(fileName);
DataInputStream in = new DataInputStream(fstream);
//Parse the first line to see if continuous or discrete attributes.
firstLine = new String[n];
firstLine = in.readLine().split(delimiter);
int i, j, lineCount = 0;
for(i=0; i<n; i++)
unusedAttr.add(new Integer(i));
input = new String[t][n+1];
String line;
int invalidLines = 0;
while((lineCount + invalidLines)<t)
{
try
{
input[lineCount] = (in.readLine()).split(delimiter);
}
catch(NullPointerException e)
{
invalidLines++;continue;
}
if (Array.getLength(input[lineCount]) != n+1 || (Array.get(input[lineCount],n).toString().compareTo("?") == 0)) //number of attributes provided in the line is incorrect.
{
invalidLines++;continue;
}
lineCount++;
}
if(invalidLines == t)
{
System.out.println("All lines invalid - Check the supplied attribute number");
System.exit(0);
}
if (invalidLines > 0)
System.out.println("Not Considering "+invalidLines+" invalid training cases");
if(numSplits > maxSplits || numSplits > (t/2))
{
System.out.println("numSplits should be less than or equal to "+Math.min(t/2,limitSplits));
System.exit(1);
}
t = testCases - invalidLines;
thresholdVal = new String[n][numSplits - 1];
boolean allCont = false;
if(Array.getLength(firstLine) == 1)
{
if(firstLine[0].compareTo("c") == 0)
allCont = true;
else if(firstLine[0].compareTo("d") == 0)
return;
else
{
System.out.println("Invalid first line - it should be c or d");
System.exit(1);
}
}
for(i=0; i<n; i++)
{
if(allCont || firstLine[i].compareTo("c") == 0) //Continuous Attribute
{
for(j=0; j<numSplits-1; j++)
thresholdVal[i][j] = calculateThreshold(i,j);
}
else if(firstLine[i].compareTo("d") != 0)
{
System.out.println("Invalid first line - Training data (it should specify if the attributes are c or d)");
System.exit(1);
}
}
for(i=0; i<t; i++)
{
for(j=0; j<n; j++)
{
if(allCont || firstLine[j].compareTo("c") == 0)
input[i][j] = makeContinuous(input[i][j], j);
}
}
}
The code for the constructor is shown above, however it finds the file but doesn't process the data and prints the errors out. How should the file be exactly?
Used text file has:
d
Span Shape Slab
long square waffle
long rectangle waffle
short square two-way
short rectangle one-way
You are already calling the constructor here - ID3 instance = new ID3("data.txt", 5 , 14 , "", 5);. You can't call it as a regular method. Just remove the instance.ID3("data.txt", 5 , 14 , "", 5); line.
You cannot call constructors like regular methods. The constructor is automatically called when you create an instance of a class,i.e,when you do
ID3 instance = new ID3("data.txt", 5 , 14 , "", 5);
Contructors are not methods. One of the key feature of a method is that it should have a return type (event if it is 'void').
Here, you do not need to explicitly call the constructor again. The functionality you implement in the constructor will be executed at instantiation itself. However, this is not recommended and is bug-prone. You should only be instantiating any variables. The actual functionality should be defined in another method.
I wrote the following, this is a toString of a Country class that has City class in same package, and _cities is an array represents the cities within my Country:
**EDITED:**
public String toString(){
String allCitiesData = ""; //must be initialized
for(int i=0;this._cities[i] != null;i++)//run all over the cities until reach the end(null cell)
{ //concat new city to the string and adds a new line between
allCitiesData = allCitiesData.concat(this._cities[i].toString()+"\n\n");
}
return allCitiesData;
}//toString method
public String citiesNorthOf(String cityName){
String allCitiesNorthOf = "";// must be initialized
for(int i=0; this._cities[i] != null ; i++)
{
if (this._cities[i].getCityName() == cityName)
{
Point referenceCityCenter = new Point(this._cities[i].getCityCenter());
}
}
for(int i=0; this._cities[i] != null ; i++)//we don't need to exclude the comparable city itself because it will give a false
{
if (this._cities[i].getCityCenter().isAbove(referenceCityCenter))
{
allCitiesNorthOf = allCitiesNorthOf.concat(this._cities[i].toString()+"\n\n");
}
}
}//citiesNorthOf method
But, when I run it, it shows a single error only on this line:
if (this._cities[i].getCityCenter().isAbove(referenceCityCenter))
And the Eclipse says: "referenceCityCenter cannot be resolved to a variable".. any suggestions ?
Thanks !!
You have declared referenceCityCenter in a scope which is not visible to that line of your code. Try declaring it at the beginning of the method (and control too if it is null when it arrives to your validation .isAbove()! :P )
referenceCityCenter is out of scope. Put it outside of your if statement and make sure you check for null afterwards like follows:
public String citiesNorthOf(String cityName){
String allCitiesNorthOf = "";// must be initialized
Point referenceCityCenter = null;
for(int i=0; this._cities[i] != null ; i++)
{
if (this._cities[i].getCityName() == cityName)
{
referenceCityCenter = new Point(this._cities[i].getCityCenter());
}
}
for(int i=0; this._cities[i] != null ; i++)//we don't need to exclude the comparable city itself because it will give a false
{
if (referenceCityCenter !- null && this._cities[i].getCityCenter().isAbove(referenceCityCenter))
{
allCitiesNorthOf = allCitiesNorthOf.concat(this._cities[i].toString()+"\n\n");
}
}
}