I have a method called setLevel
/**
* Sets the level of this course.
*
* #param newLevel - one of the enumerated levels
*/
public void setLevel(char newLevel)
{
if(newLevel == 7 || newLevel == 1 || newLevel == 9 || newLevel == 8)
{
level = newLevel;
}
else
{
level = DEFAULT_LEVEL;
}
} // end of method setLevel(char newLevel)
when I use this method, I set the Level
I have another method called getLevel
/**
* Returns the level of this course.
*
* #return the level of this course
*/
public char getLevel()
{
return level;
} // end of method getLevel()
but when I call this method, it displays a default level that I have set.
Any ideas as to how to fix it
Here is the full code
public class Course extends Object implements Serializable
{
// instance variables
private int academicYear;
private String code;
private static int counter = 0;
private char level;
private String name;
private int serialNumber;
// class constants
private static final String DATA_FILE = "courses.data";
public static final String DEFAULT_CODE = "Introduction to Computer Science";
public static final char DEFAULT_LEVEL = 7;
public static final String DEFAULT_NAME = "ICS3U";
public static final int DEFAULT_YEAR = 2014;
private static final int ERROR_CLASS_NOT_FOUND_EXCEPTION = -1;
private static final int ERROR_EOF_EXCEPTION = -2;
private static final int ERROR_IO_EXCEPTION = -3;
final char[] LEVEL = {'7', '1', '9', '8'};
/**
* Constructor for objects of class Course
*/
public Course()
{
name = DEFAULT_NAME;
code = DEFAULT_CODE;
level = DEFAULT_LEVEL;
academicYear = DEFAULT_YEAR;
serialNumber = ++counter;
} // end of constructor Course()
public Course(String name, String code, char level, int academicYear)
{
this.name = name;
this.code = code;
if (level == 7 || level == 1 || level == 9 || level == 8)
{
level = level;
}
else
{
level = DEFAULT_LEVEL;
}
if (academicYear > 1900 && academicYear < 2014)
{
this.academicYear = academicYear;
}
else
{
academicYear = DEFAULT_YEAR;
}
} // end of constructor Course(String name, String code, char level, int academicYear)
/**
* Indicates whether another object has a state identical to this object’s state.
*
* #param otherCourse - the object whose state is compared to this object’s
*/
public boolean equals(Object otherCourse)
{
if (otherCourse == null) return false;
if (this.getClass() != otherCourse.getClass()) return false;
if (this == otherCourse) return true;
if(this != otherCourse) return false;
// needed to satisfy the compiler
return true;
} // end of method boolean equals(Object course)
/**
* Compares this Course to another.
*/
public int compareTo(Course otherCourse)
{
int before = -1;
int after = 1;
int equals = 0;
int resultCode = code.compareTo(otherCourse.getCode());
if(otherCourse == null) return before ;
if(serialNumber < otherCourse.getSerialNumber()) return before;
if(serialNumber > otherCourse.getSerialNumber()) return after;
if(code.compareTo(otherCourse.getCode()) != 0) return resultCode;
if(!(sortLevel(level) == -1 || sortLevel(otherCourse.getLevel()) == -1))
{
if(sortLevel(level) < sortLevel(otherCourse.getLevel())) return -1;
if(sortLevel(level) > sortLevel(otherCourse.getLevel())) return 1;
}
return 1;
}
private static int sortLevel(char level)
{
final char[] LEVEL = {'7', '1', '9', '8'};
for (int index = 0; index < LEVEL.length; index++)
{
if(LEVEL[index] == level) return index;
if(LEVEL[index] == level) return DEFAULT_LEVEL;
}
// error code for not found, should not be reached
return -1;
}
/* accessors*/
/**
* Returns the code of this course.
*
* #returns Returns the code of this course
*/
public String getCode()
{
return code;
} // end of method getCode()
/**
* Returns the level of this course.
*
* #return the level of this course
*/
public char getLevel()
{
return level;
} // end of method getLevel()
/**
* Returns the name of this course.
*
* #return the name of this course.
*/
public String getName()
{
return name;
} // end of method getName()
/**
* Returns the unique serial number of this course.
*
* #return the unique serial number of this course.
*/
public int getSerialNumber()
{
return serialNumber;
} // end of method getSerialNumber()
/**
* Returns the academic year of this course.
*
* #return the 4-digit academic year of this course
*/
public int getYear()
{
return academicYear;
} // end of method getYear()
/* mutators */
/**
* Sets the code of this course.
*
* #param newCode - the new code of this course.
*/
public void setCode(String newCode)
{
this.code = newCode;
} // end of method setCode(String newCode)
/**
* Sets the level of this course.
*
* #param newLevel - one of the enumerated levels
*/
public void setLevel(char newLevel)
{
if(newLevel == 7 || newLevel == 1 || newLevel == 9 || newLevel == 8)
{
level = newLevel;
}
else
{
level = DEFAULT_LEVEL;
}
} // end of method setLevel(char newLevel)
/**
* Sets the name of this course.
*
* #param newName - the new name of this course
*/
public void setName(String newName)
{
this.name = newName;
} // end of method setName(String newName)
/**
* Sets the academic year of this course.
*
* #param newYear - the new 4-digit academic year of this course
*/
public void setYear(int newYear)
{
if (newYear >= 1900 && newYear <= 2014)
{
this.academicYear = newYear;
}
else
{
academicYear = DEFAULT_YEAR;
}
} // end of method setYear(int newYear)
/**
* Returns a string representation of this course.
*
* #override toString in class Object
*
* #return a string representation of this course.
*/
public String toString()
{
return
this.getClass().getName()
+"["
+ "Serial Number: " + serialNumber
+ ", name: " + name
+ ", code: " + code
+ ", level: " + level
+ ", academic year: " + academicYear
+"]";
} // end of String toString()
} // end of class Course
You have initialised LEVEL with character values '7', '1', '9', '8' but your setLevel method is comparing them with the integer values 7, 1, 9, 8.
They are not the same thing.
Frankly, if LEVEL values are integers then you should declare them as int. You're not achieving anything by storing it as a char.
When you are comparing the newLevel with values.
You are actually comparing ASCII value of newLevel with integers.
This is why every time it is giving Default_level as answer.
use single quotes to compare eg. '7'.
I think you should add single quote while comparing char values
public void setLevel(char newLevel)
{
if(newLevel == '7' || newLevel == '1' || newLevel == '9' || newLevel == '8')
{
level = newLevel;
}
else
{
level = DEFAULT_LEVEL;
}
}
Related
this is a subclass and am trying to shifts variable to accept only 1 of 3 values, that's morning evening night am a newbie so please forgive me for such a simple question
public class PartTimeStaffHire extends StaffHire
{
// instance variables - replace the example below with your own
private int workingHour
private double wagesPerHour
private String shifts;
private boolean terminated
This is subclass of StaffHire and accept all this variables and the last one am trying to accept only 1 of this 3 values
/**
* Constructor for objects of class PartTimeStaffHire
*/
public PartTimeStaffHire(int vacancy, String designation1, String typeofjob,
String staffName1, String joinDate, String qualification1, String appointed,
boolean joined, int hoursPerDay, double wagePerHour, String shift)
{
super(vacancy, designation1, typeofjob, staffName1, joinDate,
qualification1, appointed, joined);
workingHour = hoursPerDay;
wagesPerHour = wagePerHour;
shifts = shift;
if( shifts == "morning") {
shifts = "morning";
}
else if(shifts == "evening") {
shifts = "evening";
}
else if(shifts == "night") {
shifts = "night";
}
else {
System.out.println("Choose (morning, evening, night)" );
}
//(morning, evening, night)
}
public String shift()
{
if( shifts == "morning") {
shifts = "morning";
}
else if(shifts == "evening") {
shifts = "evening";
}
else if(shifts == "night") {
shifts = "night";
}
else {
System.out.println("Choose (morning, evening, night)" );
}
return shifts;
}
/**
* An example of a method - replace this comment with your own
*
* #param y a sample parameter for a method
* #return the sum of x and y
*/
public void print()
{
super.print();
System.out.println("The yearly salary is " + wagesPerHour);
System.out.println("Weekly working hours are " + workingHour;
System.out.println("##################" + shifts);
}
}
thanks in advance
If you know the possible values of a type, an enum is what you want to use.
So in this case you can create an enum Shift with the three possible constants:
public enum Shift {
MORNING,
EVENING,
NIGHT;
//this lets you convert a String such as `morning` to an enum constant
//if the enum not not one of the 3 constants (ignoring the case), this returns null. So you can use it to also validate the input.
public static Shift getShiftByName(String name) {
for(Shift s:values()) {
if(s.name().equalsIgnoreCase(name)) {
return s;
}
}
return null;
}
//if you want to convert it back to a String (for output), overwrite toString:
#Override
public String toString() {
//name() returns the constant's name as a String, such as "MORNING".
// since you use it as lowercase, overriding toString here makes sense
return name().toLowerCase();
}
}
You can then use it as
String strShiftInput = "morning";
Shift chosenChift = getShiftByName(strShiftInput);
if(chosenShift == null) {
//invalid input, handle accordingly
}
new PartTimeStaffHire(theOtherParameters, chosenShift);
I am currently working on a program where I take information from a text document, then I print it out into another file and from java but halfway through, i'm getting an no such exception error and i'm not sure why.
Tester code:
import java.util.ArrayList;
import java.util.Scanner;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
public class HurricaneSelectorTester
{
public static void main (String [ ] args) throws IOException
{
//File scanner
File fileName = new File("HurricaneData.txt");
Scanner inFile = new Scanner(fileName);
PrintWriter outputFile = new PrintWriter(new File("OutputData.txt"));
Scanner in;
in = new Scanner(System.in);
//construct a Scanner object with one line
//Declare variables
int arrayLength = 156;
int [] years = new int[156];
int index = 0;
int cat1 = 0;
int cat2 = 0;
int cat3 = 0;
int cat4 = 0;
int cat5 = 0;
double windAvg = 0;
double windTotal = 0;
double windMax = Integer.MIN_VALUE;
double windMin = Integer.MAX_VALUE;
double pressureAvg = 0;
double pressureTotal = 0;
int pressureMax = Integer.MIN_VALUE;
int pressureMin = Integer.MAX_VALUE;
double catAvg = 0;
double catTotal = 0;
int catMax = Integer.MIN_VALUE;
int catMin = Integer.MAX_VALUE;
int rangeMax = 0;
int rangeMin = 0;
//Ask for range
System.out.println("Please enter minimum year (1995-2015)");
rangeMin = in.nextInt();
System.out.println("Please enter maximum year (1995-2015)");
rangeMax = in.nextInt();
//Print title info
System.out.println("Hurricanes "+ ""+ rangeMin + "-" + "" + rangeMax);
System.out.println();
System.out.println("Year Hurricane Category Pressure (mb) Wind Speed (mph)");
System.out.println("****************************************************************");
ArrayList<HurricaneSelector> hurricanes = new ArrayList<HurricaneSelector>();
//Load all the info into the arrays
while (inFile.hasNext())
{
hurricanes.add(new HurricaneSelector(inFile.nextInt(),inFile.next(),inFile.nextInt(),inFile.nextInt(),inFile.next()));
}
for(index = 0; index < 156; index++){
years[index] = inFile.nextInt();
}
inFile.close();
HurricaneSelector dataRecord; //Data record for HurricaneSelector
for(index = 0; index < 156; index++)
{if(years[index]>= rangeMin && years[index]<= rangeMax){
dataRecord = hurricanes.get(index);
dataRecord.calcCategoriesAndTotals();
dataRecord.calcNewWind();
dataRecord.calcWindMax();
dataRecord.calcWindMin();
dataRecord.calcPressureMax();
dataRecord.calcPressureMin();
dataRecord.calcCategoryMax();
dataRecord.calcCategoryMin();
}
}
dataRecord = hurricanes.get(index);
dataRecord.calcWindAverage();
dataRecord.calcCategoryAverage();
dataRecord.calcPressureAverage();
//Print out data
outputFile.println("Year Name Category Pressure Wind Speed");
for (index = 0; index < 156; index++){
if(years[index]>= rangeMin && years[index]<= rangeMax){
System.out.println(" "+hurricanes.get(index));
System.out.println();
outputFile.println(" "+hurricanes.get(index));
}
}
outputFile.close();
System.out.println("****************************************************************");
System.out.print(" Average:");
System.out.printf("%15.1f%13.1f%20.2f",catAvg,pressureAvg,windAvg);
System.out.println();
System.out.print(" Maximum:");
System.out.printf("%15d%13d%20.2f",catMax , pressureMax , windMax);
System.out.println();
System.out.print(" Minimum:");
System.out.printf("%15d%13d%20.2f",catMin , pressureMin , windMin);
System.out.println();
System.out.println();
System.out.println("Summary of categories");
System.out.println(" Category 1: " + cat1);
System.out.println(" Category 2: " + cat2);
System.out.println(" Category 3: " + cat3);
System.out.println(" Category 4: " + cat4);
System.out.println(" Category 5: " + cat5);
}
Methods:
public class HurricaneSelector
{
private int myYear, myPressure, myWind, myRangeMin, myRangeMax, myCategory, category1, category2,category3, category4, category5;
private String myMonth, myName;
private double myNewWind;
public double myWindAverage, myPressureAverage, myCategoryAverage, myWindMax = Integer.MIN_VALUE,
myWindMin = Integer.MAX_VALUE, myPressureMax = Integer.MIN_VALUE, myPressureMin = Integer.MAX_VALUE,
myCatMax = Integer.MIN_VALUE,myCatMin = Integer.MAX_VALUE;
public int total;
/**
* Constructor for objects of type HurricaneSelector
* #param year is the year of the hurricane
* #param month is the month of the hurricane
* #param pressure is the pressure of the hurricane
* #param wind is the wind speed of the hurricane
* #param name is the name of the hurricane
*/
HurricaneSelector(int year, String month, int pressure, int wind, String name)
{
myYear = year;
myMonth = month;
myPressure = pressure;
myWind = wind;
myName = name;
}
/**
* Mutator method to calculate the wind speed in mph (no parameters)
*/
public void calcNewWind()
{
myNewWind = (myWind* 1.15);
}
/**
* Mutator method to calculate if the value is the new Maximum (no parameters)
*/
public void calcWindMax()
{
if (myNewWind > myWindMax){
myWindMax = myNewWind;
}
}
/**
* Mutator method to calculate if the value is the new Minimum (no parameters)
*/
public void calcWindMin()
{
if (myNewWind > myWindMin){
myWindMin = myNewWind;
}
}
/**
* Mutator method to calculate if the value is the new Maximum (no parameters)
*/
public void calcPressureMax()
{
if (myPressure > myPressureMax){
myPressureMax = myPressure;
}
}
/**
* Mutator method to calculate if the value is the new Minimum (no parameters)
*/
public void calcPressureMin()
{
if (myPressure > myPressureMin){
myPressureMin = myPressure;
}
}
/**
* Mutator method to calculate if the value is the new Maximum (no parameters)
*/
public void calcCategoryMax()
{
if (myCategory > myCatMax){
myCatMax = myCategory;
}
}
/**
* Mutator method to calculate if the value is the new Minimum (no parameters)
*/
public void calcCategoryMin()
{
if (myCategory > myCatMin){
myCatMin = myCategory;
}
}
/**
* Mutator method to calculate which category the Hurricane fits into and get the totals(no parameters)
*/
public void calcCategoriesAndTotals()
{
myWindAverage += myNewWind;
myPressureAverage += myPressure;
if (myNewWind > 74 && myNewWind < 95)
{
myCategory = 1;
myCategoryAverage += myCategory;
category1++;
}
else if(myNewWind > 96 && myNewWind < 110)
{
myCategory = 2;
myCategoryAverage += myCategory;
category2++;
}
else if(myNewWind > 111 && myNewWind < 129)
{
myCategory = 3;
myCategoryAverage += myCategory;
category3++;
}
else if(myNewWind > 130 && myNewWind < 156)
{
myCategory = 4;
myCategoryAverage += myCategory;
category4++;
}
else if(myNewWind > 157)
{
myCategory = 5;
myCategoryAverage += myCategory;
category5++;
}
total++;
}
/**
* Mutator method to calculate the wind speed average (no parameters)
*/
public void calcWindAverage()
{
myWindAverage = myWindAverage/total;
}
/**
* Mutator method to calculate the category average (no parameters)
*/
public void calcCategoryAverage()
{
myCategoryAverage = myCategoryAverage/total;
}
/**
* Mutator method to calculate the pressure average (no parameters)
*/
public void calcPressureAverage()
{
myPressureAverage = myPressureAverage/total;
}
/**
* Getter method to return the year of the hurricane (no parameters)
*/
public int getYear()
{
return myYear;
}
/**
* Getter method to return the month of the hurricane (no parameters)
*/
public String getMonth()
{
return myMonth;
}
/**
* Getter method to return the pressure of the hurricane (no parameters)
*/
public int getPressure()
{
return myPressure;
}
/**
* Getter method to return the wind speed of the hurricane (no parameters)
*/
public double getNewWind()
{
return myNewWind;
}
/**
* Getter method to return the name of the hurricane (no parameters)
*/
public String getName()
{
return myName;
}
/**
* Getter method to return the wind average (no parameters)
*/
public Double getWindAverage()
{
return myWindAverage;
}
/**
* Getter method to return the pressure average (no parameters)
*/
public Double getPressureAverage()
{
return myPressureAverage;
}
/**
* Getter method to return the category average (no parameters)
*/
public Double getCategoryAverage()
{
return myCategoryAverage;
}
/**
* Getter method to return the category maximum (no parameters)
*/
public Double getWindMax()
{
return myWindMax;
}
/**
* Getter method to return the category minimum (no parameters)
*/
public Double getWindMin()
{
return myWindMin;
}
/**
* Getter method to return the category maximum (no parameters)
*/
public Double getPressureMax()
{
return myPressureMax;
}
/**
* Getter method to return the category minimum (no parameters)
*/
public Double getPressureMin()
{
return myPressureMin;
}
/**
* Getter method to return the category maximum (no parameters)
*/
public Double getCategoryMax()
{
return myCatMax;
}
/**
* Getter method to return the category minimum (no parameters)
*/
public Double getCategoryMin()
{
return myCatMax;
}
public String toString(){
return String.format("%10d%10s%10d%10d%10.2f",myYear,myName, myCategory, myPressure, myNewWind);
}
The links to the text files: https://drive.google.com/file/d/1eazHCEwT0Se6hfx2SDilqCqY8ZMi4E9k/view?usp=sharing
https://drive.google.com/file/d/1CN0JnlbMWNEB7B4nomgJ_-6mkwR1wgYc/view?usp=sharing
I know there are other problems with the code such as useless variables, formatting, etc. but right now I need to fix the program so that it can actually run and print out most of the data right now.
You need to reset() the Scanner because you've reached the end in your loop, and you want to start from the beginning for the next set of operations.
From JavaSE docs:
public int nextInt()
Scans the next token of the input as an int.
An invocation of this method of the form nextInt() behaves in exactly the same way as the invocation nextInt(radix), where radix is the default radix of this scanner.
Returns:
the int scanned from the input
Throws:
InputMismatchException - if the next token does not match the Integer regular expression, or is out of range
NoSuchElementException - if input is exhausted
IllegalStateException - if this scanner is closed
Thank you for everyone who got me on my feet. However, My cutSplice method is inefficient. I need to be able to modify it easy so that i can do the reverse method.
developing a single Java class (LinkedDnaStrand) that uses a linked list of nodes to represent a strand of DNA that supports splicing. Each node in the list will contain a string of one or more nucleotides (A, C, G, or T). The class will be responsible for operations such as append() and cutSplice(), which model real-world restriction enzyme processing.
EX. tt will be replaced with cat. (Better LinkedDnaStrandTester)
package dnasplicing;
public class DnaSequenceNode {
public String dnaSequence;
public DnaSequenceNode previous;
public DnaSequenceNode next;
public DnaSequenceNode(String initialDnaSequence) {
dnaSequence = initialDnaSequence;
}
}
package dnasplicing;
public class LinkedDnaStrand implements DnaStrand {
int nodeCount = 0;
int appendCount = 0;
long nucleotideCount = 0;
String sequenceString;
DnaSequenceNode cursor, head, tail;
public LinkedDnaStrand(String dnaSequence) {
DnaSequenceNode newNode = new DnaSequenceNode(dnaSequence);
head = newNode;
cursor = head;
tail = head;
head.previous = null;
tail.previous = null;
sequenceString = dnaSequence;
nodeCount++;
}
public String toString() {
String result = "";
DnaSequenceNode n = head;
while (n != null) {
result += n.dnaSequence;
n = n.next;
}
return result;
}
#Override
public long getNucleotideCount() {
nucleotideCount = sequenceString.length();
return nucleotideCount;
}
#Override
public void append(String dnaSequence) {
if (dnaSequence != null && dnaSequence.length() > 0) {
tail.next = new DnaSequenceNode(dnaSequence);
tail.next.previous = tail;
tail = tail.next;
sequenceString += dnaSequence;
appendCount++;
nodeCount++;
}
}
#Override
public DnaStrand cutSplice(String enzyme, String splicee) {
boolean frontSplice = false;
boolean backSplice = false;
if (sequenceString.startsWith(enzyme)) {
frontSplice = true;
}
if (sequenceString.endsWith(enzyme)) {
backSplice = true;
}
String[] dnaParts = sequenceString.split(enzyme);
LinkedDnaStrand newLinkedStrand = null;
if (frontSplice == true) {
newLinkedStrand = new LinkedDnaStrand(splicee);
// newLinkedStrand.append(dnaParts[0]);
for (int i = 1; i < dnaParts.length; i++) {
newLinkedStrand.append(dnaParts[i]);
if (i < dnaParts.length - 1) {
newLinkedStrand.append(splicee);
}
}
} else {
newLinkedStrand = new LinkedDnaStrand(dnaParts[0]);
for (int index = 1; index < dnaParts.length; index++) {
newLinkedStrand.append(splicee);
newLinkedStrand.append(dnaParts[index]);
}
}
if (backSplice == true) {
newLinkedStrand.append(splicee);
}
// sequenceString = newLinkedStrand.toString();
return newLinkedStrand;
}
#Override
public DnaStrand createReversedDnaStrand() {
// TODO Auto-generated method stub
return null;
}
#Override
public int getAppendCount() {
// TODO Auto-generated method stub
return appendCount;
}
#Override
public DnaSequenceNode getFirstNode() {
return head;
}
#Override
public int getNodeCount() {
return nodeCount;
}
}
package dnasplicing;
public interface DnaStrand {
/**
* NOTE: Your LinkedDnaStrand class must have a constructor that takes one parameter: String dnaSequence. When the
* constructor completes, your linked list should have just one node, and it should contain the passed-in
* dnaSequence. For example, if the following line of code was executed:
*
* LinkedDnaStrand strand = new LinkedDnaStrand("GATTACA");
*
* Then strand's linked list should look something like (previous pointers not shown):
*
* first -> "GATTACA" -> null
*
* The first line of this constructor should look like:
*
* public LinkedDnaStrand(String dnaSequence) {
*/
/**
* #return The entire DNA sequence represented by this DnaStrand.
*/
public String toString();
/**
* Returns the number of nucleotides in this strand.
*
* #return the number of base-pairs in this strand
*/
public long getNucleotideCount();
/**
* Appends the given dnaSequence on to the end of this DnaStrand. appendCount is incremented. Note: If this
* DnaStrand is empty, append() should just do the same thing as the constructor. In this special case, appendCount
* is not incremented.
*
* #param dnaSequence
* is the DNA string to append
*/
public void append(String dnaSequence);
/**
* This method creates a <bold>new</bold> DnaStrand that is a clone of the current DnaStrand, but with every
* instance of enzyme replaced by splicee. For example, if the LinkedDnaStrand is instantiated with "TTGATCC", and
* cutSplice("GAT", "TTAAGG") is called, then the linked list should become something like (previous pointers not
* shown):
*
* first -> "TT" -> "TTAAGG" -> "CC" -> null
*
* <b>NOTE</b>: This method will only be called when the linke list has just one node, and it will only be called
* once for a DnaStrand. This means that you do not need to worry about searching for enzyme matches across node
* boundaries.
*
* #param enzyme
* is the DNA sequence to search for in this DnaStrand.
*
* #param splicee
* is the DNA sequence to append in place of the enzyme in the returned DnaStrand
*
* #return A <bold>new</bold> strand leaving the original strand unchanged.
*/
public DnaStrand cutSplice(String enzyme, String splicee);
/**
* Returns a <bold>new</bold> DnaStrand that is the reverse of this strand, e.g., if this DnaStrand contains "CGAT",
* then the returned DnaStrand should contain "TAGC".
*
* #return A <bold>new</bold> strand containing a reversed DNA sequence.
*/
public DnaStrand createReversedDnaStrand();
/**
*
* #return The number of times that the DnaStrand has been appended via a call to append() or during the cutSplice()
* operation. Note that the very first time that a DnaStrand is given a DNA sequence is not to be counted as
* an append.
*/
public int getAppendCount();
/**
* This is a utility method that allows the outside world direct access to the nodes in the linked list.
*
* #return The first DnaSequenceNode in the linked list of nodes.
*/
public DnaSequenceNode getFirstNode();
/**
* This is a utility method that allows the outside world to determine the number of nodes in the linked list.
*
* #return
*/
public int getNodeCount();
}
package sbccunittest;
import static java.lang.Math.*;
import static java.lang.System.*;
import static org.apache.commons.lang3.StringUtils.*;
import static org.junit.Assert.*;
import java.io.*;
import org.apache.commons.lang3.*;
import org.junit.*;
import dnasplicing.*;
// Updated 25-Feb-2016 at 6:10pm
public class LinkedDnaStrandTester {
static String ecoliSmall = "AGCTTTTCATTAGCCCGCAGGCAGCCCCACACCCGCCGCCTCCTGCACCGAGAGAGATGGAATAAAGCCCTTGAACCAGC";
static String ecor1 = "GAATTC"; // restriction enzyme
public static int totalScore = 0;
public static int extraCredit = 0;
public static InputStream defaultSystemIn;
public static PrintStream defaultSystemOut;
public static PrintStream defaultSystemErr;
public static String newLine = System.getProperty("line.separator");
public void testCutSplice() {
String enzyme = "GAT";
String splicee = "TTAAGG";
String[] strands = { "TTGATCC", "TCGATCTGATTTCCGATCC", "GATCTGATCTGAT" };
String[][] recombinants = { { "TT", "TTAAGG", "CC" },
{ "TC", "TTAAGG", "CT", "TTAAGG", "TTCC", "TTAAGG", "CC" },
{ "TTAAGG", "CT", "TTAAGG", "CT", "TTAAGG" } };
for (int ndx = 0; ndx < strands.length; ndx++) {
LinkedDnaStrand linkedStrand = new LinkedDnaStrand(strands[ndx]);
DnaStrand newlinkedStrand = linkedStrand.cutSplice(enzyme, splicee);
assertEquals("cutSplice(" + enzyme + ", " + splicee + ") failed at ndx = " + ndx, join(recombinants[ndx]),
newlinkedStrand.toString());
assertEquals("Append counts didn't match for ndx = " + ndx, recombinants[ndx].length - 1,
newlinkedStrand.getAppendCount());
// Verify that each node contains the correct DNA sequence
DnaSequenceNode node = newlinkedStrand.getFirstNode();
for (int nodeNdx = 0; nodeNdx < recombinants.length; nodeNdx++) {
assertNotNull("For strand " + ndx + ", there is no node at position " + nodeNdx, node);
assertEquals("For strand " + ndx + ", the sequences don't match at position " + nodeNdx,
recombinants[ndx][nodeNdx], node.dnaSequence);
node = node.next;
}
}
totalScore += 5;
}
/**
* Verifies that LinkedDnaStrand can model a cut and splice of (part of) the E Coli sequence using the ECoR1
* restriction enzyme and insulin as a splicee.
*/
#Test
public void testSpliceInsulinIntoEcoli() {
for (int testNumber = 1; testNumber <= 5; testNumber++) {
int startNdx = (int) (random() * 0.33 * ecoliSmall.length()); // Somewhere in the
// first third
int endNdx = ecoliSmall.length() - 1 - (int) (random() * 0.33 * ecoliSmall.length());
String ecoliPart = ecoliSmall.substring(startNdx, endNdx);
LinkedDnaStrand linkedStrand = new LinkedDnaStrand(ecoliPart);
SimpleDnaStrand simpleStrand = new SimpleDnaStrand(ecoliPart);
DnaStrand newL = linkedStrand.cutSplice(ecor1, insulin);
DnaStrand newS = simpleStrand.cutSplice(ecor1, insulin);
assertEquals(newS.toString(), newL.toString());
assertEquals(newS.getAppendCount(), newL.getAppendCount());
assertEquals(newS.getAppendCount(), newL.getNodeCount() - 1);
// Verify that the nodes exist
DnaSequenceNode node = newL.getFirstNode();
for (int ndx = 0; ndx < newL.getNodeCount(); ndx++) {
assertNotNull("There is no node at position " + ndx, node);
node = node.next;
}
}
totalScore += 10;
}
/**
* Verifies that LinkedDnaStrand can model a cut and splice efficiently.
*/
#Test
public void testSplicingTime() {
// First verify that the LinkedDnaStrand cutSplice works
int startNdx = (int) (random() * 0.33 * ecoliSmall.length()); // Somewhere in the first
// third
int endNdx = ecoliSmall.length() - 1 - (int) (random() * 0.33 * ecoliSmall.length());
String ecoliPart = ecoliSmall.substring(startNdx, endNdx);
LinkedDnaStrand linkedStrand = new LinkedDnaStrand(ecoliPart);
SimpleDnaStrand simpleStrand = new SimpleDnaStrand(ecoliPart);
String splicee = createRandomDnaSequence(1024 * 1024, 1024 * 1024);
DnaStrand newL = linkedStrand.cutSplice(ecor1, splicee);
DnaStrand newS = simpleStrand.cutSplice(ecor1, splicee);
assertEquals(newS.toString(), newL.toString());
assertEquals(newS.getAppendCount(), newL.getAppendCount());
// Now verify that it can cut and splice N times in less than T seconds
int numSplicings = 200;
double maxTime = 2.0;
double start = nanoTime();
for (int i = 0; i < numSplicings; i++)
newL = linkedStrand.cutSplice(ecor1, splicee);
double end = nanoTime();
double time = ((end - start) / 1e9);
// out.println("Time = " + time);
assertTrue("Time limit of " + maxTime + " seconds exceeded. Time to splice " + numSplicings + " times was "
+ time + " seconds.", time <= maxTime);
totalScore += 5;
}
/**
* Verifies that LinkedDnaStrand can create a new, reversed LinkedDnaStrand.
*/
#Test
public void testReverse() {
String dnaSequence = createRandomDnaSequence(50, 100);
String dnaToAppend = createRandomDnaSequence(5, 10);
int numTimesToAppend = (int) (random() * 10);
LinkedDnaStrand linkedStrand = new LinkedDnaStrand(dnaSequence);
SimpleDnaStrand simpleStrand = new SimpleDnaStrand(dnaSequence);
for (int ndx = 0; ndx < numTimesToAppend; ndx++) {
linkedStrand.append(dnaToAppend);
simpleStrand.append(dnaToAppend);
}
assertEquals(simpleStrand.toString(), linkedStrand.toString());
assertEquals(numTimesToAppend + 1, linkedStrand.getNodeCount());
LinkedDnaStrand rl = (LinkedDnaStrand) linkedStrand.createReversedDnaStrand();
// Verify that the original linked strand wasn't changed
DnaSequenceNode node = linkedStrand.getFirstNode();
int nodeNdx = 0;
while (node != null) {
assertEquals("Sequences don't match at node index " + nodeNdx, nodeNdx == 0 ? dnaSequence : dnaToAppend,
node.dnaSequence);
node = node.next;
nodeNdx++;
}
// Verify that the new strand string is reversed
assertEquals(simpleStrand.createReversedDnaStrand().toString(), rl.toString());
totalScore += 10;
// If the new strand has a reverse order of nodes and sequences within each node, give extra
// credit
int numNodes = linkedStrand.getNodeCount();
if (numNodes == rl.getNodeCount()) {
// Build array of reversed dna strings from original LinkedDnaStrand. Start at end of
// array and move toward
// start
node = linkedStrand.getFirstNode();
String[] reversedDnaSequences = new String[linkedStrand.getNodeCount()];
nodeNdx = numNodes - 1;
while (node != null) {
reversedDnaSequences[nodeNdx] = reverse(node.dnaSequence);
node = node.next;
nodeNdx--;
}
// Verify that the reversed list's nodes contain the same data as in the array
node = rl.getFirstNode();
nodeNdx = 0;
while (node != null) {
if (!node.dnaSequence.equals(reversedDnaSequences[nodeNdx]))
break;
node = node.next;
nodeNdx++;
}
if (nodeNdx == linkedStrand.getNodeCount())
extraCredit += 5;
}
}
private String[] createRandomDnaSequences(int numDnaSequences, int minLength, int maxLength) {
String[] dnaSequences = new String[numDnaSequences];
for (int ndx = 0; ndx < numDnaSequences; ndx++)
dnaSequences[ndx] = createRandomDnaSequence(minLength, maxLength);
return dnaSequences;
}
private String createRandomDnaSequence(int minLength, int maxLength) {
return RandomStringUtils.random((int) (random() * (maxLength - minLength) + minLength), "ACGT");
}
#BeforeClass
public static void beforeTesting() throws Exception {
totalScore = 0;
extraCredit = 0;
}
#AfterClass
public static void afterTesting() {
out.println("Estimated score (w/o late penalties, etc.) = " + totalScore);
out.println("Estimated extra credit (assuming on time submission) = " + extraCredit);
}
#Before
public void setUp() throws Exception {
defaultSystemIn = System.in;
defaultSystemOut = System.out;
defaultSystemErr = System.err;
}
#After
public void tearDown() throws Exception {
System.setIn(defaultSystemIn);
System.setOut(defaultSystemOut);
System.setErr(defaultSystemErr);
}
public void sendToStdinOfTestee(String message) {
System.setIn(new ByteArrayInputStream(message.getBytes()));
}
}
So I don't have some of the classes like the node class you are using so I cannot write the actual code but i will give you some pseudo code.
public String toString(){
String result = "";
Node n = start;
while(n != null){
string += n.data;
}
return result;
}
public long getNucleotideCount() {
long result = 0;
Node n = start;
while(n != null){
result += n.data.length();
}
return result;
}
public void append(String dnaSequence) {
end.next = new Node(dnaSequence);
end = end.next;
appendCount++;
}
public DnaStrand cutSplice(String enzyme, String splice) {
// For this I think it would be best to assemble into string then use replace
Node n = start;
String result = "";
while(n != null){
result += n.data;
}
result = result.replace(enzyme, splice)
return new DnaStrand(result);
}
The reverse method would be similar to cutSplice. Assemble to string, manipulate, then return new strand. If you need more help LMK.
I'm trying to call a divide method that's overridden from an interface class. All similar methods (add, subtract, multiply) work just fine, except divide for some reason isn't found. Here's what I have below:
Arithmetic Interface class
public interface Arithmetic {
public Object add(Object obj);
public Object subtract(Object obj);
public Object multiply(Object obj);
public Object divide(Object obj);
}
Number class (Arithmetic methods are overridden below, divide being the last one)
public class Number implements Comparable,Arithmetic{
/**
* A string representing a non-negative number
*/
private String value;
/**
* An integer greater than or equals to 2.
*/
private int base;
/**
* - for negative numbers and otherwise null
*/
private char sign;
/**
* creates 0 base 2.
*/
public Number()
{
value = "0";
base = 2;
}
/**
* creates a number in a specified based using the specified parameters.
* #param num a string representing a non-negative number with digit
* written in uppercase letters.
* #param radix the base of the number
*/
public Number(String num, int radix) throws InvalidNumberException
{
String list = ".-0123456ABCDEFGHIJKLMNOPQRSTUVWXYZ";
Boolean pars = false;
for (int i = 0; i < list.length(); i++) {
if (num.indexOf(list.charAt(i)) != -1) {
pars = true;
}
}
if (radix < 1 || radix > 35) {
throw new InvalidNumberException("Number invoked with a radix less than 1 or greater than 35.");
} else if ((num.indexOf(".") != num.lastIndexOf(".")) || (num.indexOf("-") != num.lastIndexOf("-"))) {
throw new InvalidNumberException("Number invoked with more than one dash or period in string.");
} else if (num.indexOf("-") != 0) {
throw new InvalidNumberException("Number invoked with dash not at beginning of string.");
} else if (num.indexOf(".") == num.length()) {
throw new InvalidNumberException("Number invoked with period at end of string.");
}
else if (pars == true) {
throw new InvalidNumberException("Number invoked with invalid character.");
}
Boolean test=false;
for (int i = 0; i < num.length(); i++) {
if ((num.charAt(i) != '-') || (num.charAt(i) != '.')) {
if (toValue(num.charAt(i)) >= radix) {
test=true;
throw new InvalidNumberException("Number invoked with digit greater or equal to radix.");
}
}
}
if(test==false){
value = num;
base = radix;
}
}
/**
* Converts a digit to its integer equivalent
* #param digit 0...9 or A...Z to be converted
* #return the integer equivalent of the specified digit.
*/
private int toValue(char digit)
{
return Character.getNumericValue(digit);
}
/**
* Converts this integer to its equivalent digit
* #param anInt an integer between 0-35
* #return the digit equivalent to an integer
*/
private char toDigit(int anInt)
{
if(anInt >= 0 && anInt <= 9)
return (char)(anInt + 48);
else if(anInt >= 10 && anInt <= 35)
return (char)(anInt + 55);
else
return (char)(-1);
}
/**
* converts a number to its decimal equivalent (double).
* #return the decimal equivalent of a number
*/
private double toDouble()
{
if (base == 10)
return Double.parseDouble(value);
int periodIndex = value.indexOf('.');
double base10Num = 0;
int i;
int radix = base;
String whole;
if (periodIndex >=0)
whole = value.substring(0, periodIndex);
else
whole = value;
int j=0;
int wholeLength = whole.length();
for (i=wholeLength-1; i>=0; i--)
base10Num = base10Num + toValue(whole.charAt(i))*(int)Math.pow(radix,wholeLength-i-1);
if (periodIndex >= 0)
{
String fract = value.substring(periodIndex+1,value.length());
int fractLength = fract.length();
for (i=0; i<fractLength; i++)
{
base10Num = base10Num + toValue(fract.charAt(i))*Math.pow(radix,-i-1);
}
}
if (sign == '-')
base10Num *= -1;
return base10Num;
}
/**
* converts a decimal number (double) to its equivalent representation
* in a given base.
* #param dec the decimal (base 10) number
* #radix the base to convert the number to.
* #return the equivalent number in the specified base
*/
private Number doubleToNumber(double dec, int radix)
{
if (radix == 10)
return new Number(Double.toString(dec),radix);
String numSign="";
if (dec < 0)
{
numSign = "-";
dec = -dec;
}
int whole = (int)dec;
double fract = dec - whole;
String numStr = "";
while (whole != 0)
{
numStr = toDigit(whole%radix) + numStr;
whole = whole / radix;
}
if (fract != 0)
{
numStr += ".";
int tolerance = 20;
int precision = 0;
while (precision < tolerance && fract != 0)
{
fract = fract * radix;
numStr += toDigit((int)(fract));
precision++;
fract = fract - (int)fract;
}
}
return new Number(numSign+numStr,radix);
}
/**
* Gives a string representation of this number in the
* format number[base].
* #return a string representation of this number
*/
#Override
public String toString()
{
return String.format("%s%s[%d]", this.sign, this.value, this.base);
}
#Override
public boolean equals(Object obj)
{
if (!(obj instanceof Number))
return false;
return (this.toDouble()==((Number)obj).toDouble());
}
#Override
public int compareTo(Object obj) throws IllegalArgumentException
{
if (!(obj instanceof Number))throw new IllegalArgumentException();
else if(this.toDouble()<((Number)obj).toDouble()) return -1;
else if(this.toDouble()>((Number)obj).toDouble()) return 1;
else return 0;
}
/**
* This method adds two numbers from two different objects
* #param obj the number of the object inputted from user
* #return a new added number object
*/
#Override
public Object add(Object obj) throws IllegalArgumentException {
if (!(obj instanceof Number)) {
throw new IllegalArgumentException();
} else if (this.base != ((Number) obj).base) {
throw new IllegalArgumentException();
} else {
return doubleToNumber((this.toDouble() + ((Number) obj).toDouble()), ((Number) obj).base);
}
}
/**
* This method subtracts two numbers from two different objects
* #param obj the number of the object inputted from user
* #return a new subtracted number object
*/
#Override
public Object subtract(Object obj) throws IllegalArgumentException {
if (!(obj instanceof Number)) {
throw new IllegalArgumentException();
} else if (this.base != ((Number) obj).base) {
throw new IllegalArgumentException();
} else {
return doubleToNumber((this.toDouble() - ((Number)obj).toDouble()), ((Number) obj).base);
}
}
/**
* This method multiplies two numbers from two different objects
* #param obj the number of the object inputted from user
* #return a new multiplied number object
*/
#Override
public Object multiply(Object obj) throws IllegalArgumentException{
if (!(obj instanceof Number)) {
throw new IllegalArgumentException();
} else if (this.base != ((Number) obj).base) {
throw new IllegalArgumentException();
} else {
return doubleToNumber(this.toDouble() * ((Number)obj).toDouble(), ((Number) obj).base);
}
}
/**
* This method divides two numbers from two different objects
* #param obj the number of the object inputted from user
* #return a new divided number object
*/
#Override
public Object divide(Object obj) throws IllegalArgumentException {
if (!(obj instanceof Number)) {
throw new IllegalArgumentException();
} else if (this.base != ((Number) obj).base) {
throw new IllegalArgumentException();
} else if (((Number) obj).toDouble() == 0) {
throw new IllegalArgumentException();
} else {
return doubleToNumber((this.toDouble() / ((Number) obj).toDouble()), ((Number) obj).base);
}
}
}
And finally my demo class, NumberDemo
public class NumberDemo
{
public static void main(String[] args)
{
Number a = new Number("12.25", 8);
Number b = new Number("13.75", 8);
System.out.println(a.toString() + " + " + b.toString() + " = " +
a.add(b));
a = new Number("ABC.75", 16);
b = new Number("18.5F", 16);
Number c = new Number("2.FB", 16);
System.out.println("(" + a.toString() + " - " + b.toString() + ") / " +
c.toString() + " = " + (a.subtract(b)).divide(c));
a = new Number("3.45", 9);
b = new Number("32.25", 9);
c = new Number("3.05", 9);
System.out.println(a.toString() + "(" + b.toString() + " + " +
c.toString() + " = " + a.multiply(b.add(c)));
a = new Number("10111.11", 2);
b = new Number("1100110.01", 2);
c = new Number("-101", 2);
System.out.println("(" + a.toString() + " - " + b.toString() + ") / " +
c.toString() + " = " + (a.subtract(b)).divide(c));
a = new Number("-5", 8);
b = new Number("5", 8);
System.out.println(a.toString() + " x " + b.toString() + " = " +
a.multiply(b));
a = new Number("-0.5", 8);
b = a;
System.out.println(a.toString() + " x " + b.toString() + " = " +
a.multiply(b));
}
}
When I call all the arithmetic methods, they appear to be called just fine, however calling divide brings me the error tooltip:
cannot find symbol
symbol: method divide(Number)
location: class Object
I can't seem to find the reason for this, can anyone spot it?
This is my first time using Stockoverflow, so please let me know if anything's apart from the format norm.
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 8 years ago.
Improve this question
I have I am having trouble figuring out an issue I have with a toString method. toString () must be changed so that it prints all the relevant information about the Player (and collection of
Items). Subclasses should overwrite the superclass toString (), but still use the toString ()
from the super class implementation when this reduces code duplication.
How do I go about doing this?
Player class:
import java.util.HashMap;
public class Player extends Character {
private String name;
private String type;
public static HashMap<String, Item> backpack;
private int maxCarryingCapacity;
/**Constructor
* Creates a player with health 100, an empty backpack
* and max carrying capacity 100
*
* #param nick the players name
* #param type the players type
* #param minDamage players minimum damage
* #param maxDamage players maximum damage
*/
public Player(String name, String type, int minDamage, int maxDamage) {
super(name, minDamage, maxDamage);
setName(name);
setType(type);
health = 100;
gold = 100;
backpack = new HashMap<String, Item>();
maxCarryingCapacity = 100;
setMinDamage(minDamage);
setMaxDamage(maxDamage);
}
/**
* Use an item in backpack
* #param itemName
* #return true if item is used, and false
* if there's no item by that name in the backpack
*/
public boolean useItem(String itemName) {
Item item = findItem(itemName);
if(item != null) {
System.out.println(name + " " + item.getAction() + " " + item.getName());
return true;
} else {
return false;
}
}
public boolean equipItem(String itemToEquip) {
Item item = findItem(itemToEquip);
if (item != null) {
this.minDamage = this.minDamage + item.getBonus();
return true;
} else {
return false;
}
}
/**
* Adds item to players inventory. An
* item can only be bought if the total weight does not
* exceed the players carrying capacity
* #param item
* #return true if the item is bought
*/
public boolean addItem(Item item) {
int totalWeight = totalWeight() + item.getWeight();
if(totalWeight <= maxCarryingCapacity){
backpack.put(item.getName(), item);
return true;
} else {
return false;
}
}
/**
* Find item in backpack
*
* #param name of item
* #return item, or null if item is not int the backpack
*/
public Item findItem(String itemName) {
return backpack.get(itemName);
}
/**
* Removes item from player's backpack and
* add item value to player's gold
*
* #param name of item to sell
* #return true if successful
*/
public boolean sellItem(String itemToSell) {
Item item = findItem(itemToSell);
if(item != null) {
gold += item.getValue();
backpack.remove(item.getName());
return true;
} else {
return false;
}
}
/**
* #return true if the player is alive
*/
public boolean isAlive() {
if(health > 0 && health <= 100) {
return true;
} else return false;
}
/**
* #return a string with player information
*/
#Override
public String toString() {
String string = "Name: " + name + " Type: " + type + "\n";
if(isAlive()) {
string += "Is alive with health: " + health;
} else {
string += "Is dead.";
}
string += "\n"+ name + "'s backpack contains the following items: \n";
for(Item item : backpack.values()) {
string += item;
}
return string;
}
/**
* #return the players type
*/
public String getType() {
return type;
}
/**Sets the players type
* Valid types: Mage, Ranger, Warrior, Rogue
* #param newType
*/
public void setType(String newType) {
newType = newType.toLowerCase().trim();
if(newType.equals("mage") || newType.equals("ranger") || newType.equals("warrior") || newType.equals("rogue")){
this.type = newType;
} else {
this.type = "Unspecified";
}
}
/**
* #param item
* #return current carrying weight
*/
private int totalWeight() {
int tempWeight = 0;
for(Item itemInBackpack : backpack.values()) {
tempWeight += itemInBackpack.getWeight();
}
return tempWeight;
}
public int attack(Monster currentEnemy) {
int damage = Utils.random(minDamage, maxDamage+1);
currentEnemy.changeHealth(-damage);
return damage;
}
}
The Character superclass (abstract class):
abstract class Character
{
public String name;
public static int health;
public int gold;
public int minDamage;
public int maxDamage;
public Character(String name, int minDamage, int maxDamage) {
setName(name);
health = 100;
gold = 100;
setMinDamage(minDamage);
setMaxDamage(maxDamage);
}
public Character () {
}
/**
* Changes the character health
* The health can not be less the 0 or "less than or euqal to" 100.
* #param healthPoints
*/
public void changeHealth(int healthPoints) {
int temp = health + healthPoints;
if(temp > 100) {
health = 100;
} else if (temp <= 0) {
health = 0;
} else {
health = temp;
}
}
/**
* #return true if the character is alive
*/
public boolean isDead() {
if(health > 0 && health <= 100) {
return false;
} else return true;
}
/**
* #return the characters name
*/
public String getName() {
return name;
}
/**Set to Unspecified if the string is empty
* #param name
*/
public void setName(String name) {
this.name = Utils.checkString(name);
}
/**
* #return the characters health
*/
public static int getHealth() {
return health;
}
/**
* Get minimum damage
* #return minimum damage
*/
public int getMinDamage() {
return minDamage;
}
/**
* Set minimum damage, if minDamage >= 5, minDamage is otherwise set to 5
* #param minimum Damage
*/
public void setMinDamage(int minDamage) {
this.minDamage = minDamage >= 5 ? minDamage : 5;
}
/**
* Get maximum damage
* #return maximum damage
*/
public int getMaxDamage() {
return maxDamage;
}
/**
* Set maximum damage, if maxDamage <= minDamage, maxDamage is set to minDamage +5
* #param maximum damage
*/
public void setMaxDamage(int maxDamage) {
this.maxDamage = maxDamage <= minDamage ? minDamage+5 : maxDamage;
}
/**
* Get money
* #return amount of money
*/
public int getGold() {
return gold;
}
/**
* Set money
* #param amount of money
*/
public void setGold(int gold) {
this.gold = Utils.checkNegativeInt(gold);
}
}
In general, given two classes, A and B and if class B extends A then B has all of the properties of A plus some of its own. Therefore, when you implement B's toString() method, you should do this:
#Override
public String toString() {
String newStuff = // description of the new variables
return super.toString() + newStuff;
// Now describe the elements of B that aren't included in A
}
However, your implementation doesn't give a basic toString() method for Character so calling super.toString() is equivalent to calling Object.toString(). Therefore you should first implement toString for your Character abstract class.
for example, you could do:
public String toString() {
return "Name: " + name + "\nHealth: " ... all the attributes
}
There is a lot of redundancy in your code though. First of all, both your Character class and your Player class have the same name variable, which goes against the point of inheritance. In fact, you never even use Player's name variable.
also, there is no point in creating getter/setter methods in Character if all the variables are declared public anyways. It is better to make them private and use getter/setters though.
Your abstract superclass has name and health, but not type or backpack. (I just noticed, thanks to user2573153's answer, that you also have name in your Player class; I don't think you want that.)
I think the first thing you want to do is to answer this question: Suppose you create a new subclass, and you don't override toString(), and then an object gets printed out. What would you want to see printed out?
Maybe you want the name and health printed out. So you can declare this in your abstract Character class (which I think shouldn't be called Character because java.lang already has a Character):
#Override
public String toString() {
String string = "Name: " + name + "\n";
if(isAlive()) {
string += "Is alive with health: " + health;
} else {
string += "Is dead.";
}
return string;
}
Then, if you wanted toString() in Player or Monster to add something to the end of that, it would be pretty easy:
#Override
public String toString() {
String string = super.toString(); // here's where you call the superclass version
string += "\n Type: " + type;
string += "\n"+ name + "'s backpack contains the following items: \n";
for(Item item : backpack.values()) {
string += item;
}
return string;
}
In your actual code, however, you want the Type information inserted in the middle of the string that the superclass toString() would return. That makes things tougher. I can think of two ways to handle it. One would be to use some string manipulation methods to search for \n and insert the "Type" string in there. But I think it's better to split the string into two methods. You can put these in your Character class:
protected String nameString() {
return "Name: " + name;
}
protected String healthString() {
if(isAlive()) {
return "Is alive with health: " + health;
} else {
return "Is dead.";
}
}
Now, your toString() in Character might look like
#Override
public String toString() {
return nameString() + "\n" + healthString();
}
and in Player:
#Override
public String toString() {
return nameString() + " Type: " + type + "\n" + healthString();
}
and you still get to avoid duplicated code. (You don't need to say super.nameString() because your subclass will automatically inherit it and you don't plan to override it.)
Superclass methods aren't automatically called. When you override toString() in Player and you call toString() on an instance of Player the only code that gets run is Player's toString().
If you want to include the toString() of Character in your toString() of Player you need to make that explicit by calling super.toString() in Player's toString().
Your Player implementation of toString() could be amended to include my recommendation as follows:
/**
* #return a string with player information
*/
#Override
public String toString() {
String string = "Name: " + name + " Type: " + type + "\n";
if(isAlive()) {
string += "Is alive with health: " + health;
} else {
string += "Is dead.";
}
string += "\n"+ name + "'s backpack contains the following items: \n";
for(Item item : backpack.values()) {
string += item;
}
return super.toString() + string;
}
The salient part of this is changing:
return string;
To:
return super.toString() + string;