I'm not sure if the title is right but basically I have this piece of code:
for(int i = 0; i < ArrEmployee.size(); ++i){
ArrEmployee.get(i);
double provTax = ProvincialTax.calculateTax(ArrEmployee.get(i));
And this arrayList:
List<Employee> ArrEmployee = new ArrayList<>(); // array for employee objects
And the ProvincialTax class is like this:
public class ProvincialTax extends Deductions { // deductions is an abstract class with the abstract method calculateTax()
public double calculateTax(Employee employee) {
if (employee.getAnnualGrossSalary() < 41495){
return employee.getAnnualGrossSalary()*0.16;
}
else if (employee.getAnnualGrossSalary() < 82985){
return employee.getAnnualGrossSalary()*0.20;
}
else if(employee.getAnnualGrossSalary() < 100970){
return employee.getAnnualGrossSalary()*0.24;
}
else
return employee.getAnnualGrossSalary()*0.2575;
}
}
So basically my arrayList ArrEmployee stores Employee objects that have the variables:
public long EmployeeNumber;
public String EmployeeName;
public String LastName;
public double HoursWorked;
public double HourlyWage;
And the HoursWorked and HourlyWage are used to calculate AnnualGrossSalary used in my ProvincialTax class. With my for loop, I'm trying to calculate the provincial tax for each object inside the ArrEmployee, but it keeps asking me to make the method calculateTax() static, but it's supposed to override an abstract method?
How do I bypass this?
The problem isn't that you should make your method static, the problem is that you're invoking the method as if it was static, which you shouldn't do. The problem is in the line:
double provTax = ProvincialTax.calculateTax(ArrEmployee.get(i));
Which instance of ProvincialTax do you want to invoke it on? Invoke it on that instance.
ProvincialTax taxInstance = ...; // Get an instanceof of ProvincialTax
double provTax = taxInstance.calculateTax(ArrEmployee.get(i));
Without further evidence and the fact that you're not using preferred naming conventions, ProvincialTax.calculateTax appears to be trying to call the calculateTax via the ProvincialTax Class and not a instance of it...
ProvincialTax provincialTax = new ProvincialTax();
for(int i = 0; i < ArrEmployee.size(); ++i){
double provTax = provincialTax.calculateTax(ArrEmployee.get(i));
}
You might like to have a read through Code Conventions for the Java TM Programming Language, it will make it easier for people to read your code and for you to read others
Related
I have an array of objects called _Array. I have defined _Array[0] as object that is a subclass of the superclass. I have fields in this sub class that dont exist in the superclass yet i want to access these fields from the array that i created in the superclass. Is this possible? There is sample code below. I have indicated the line i'm having an issue with by the comment.
public class SuperClass {
String color = "Red";
int favenumber = 15;
public static void main(String[] args) {
SuperClass[] _Array = new SuperClass[10];
_Array[0] = new SubClass(10, 150);
_Array[0].age = 10; /////THIS LINE HERE IS MY QUESTION
System.out.println(_Array[0].getClass());
}
}
public class SubClass extends SuperClass{
public int age = 0;
public int weight = 0;
SubClass(int age, int weight)
{
this.age = age;
this.weight = weight;
}
}
This is not possible, but you could instead do this, if you are COMPLETELY SURE that the object is always a SubClass:
((SubClass) _Array[0]).age = 10;
This is casting the object first as SubClass and then accessing the field in one line. You could also check first if it is a SubClass:
if(_Array[0] instanceof SubClass){
((SubClass) _Array[0]).age = 10;
}
You'd have to cast the object to the derived class, in your case:
((SubClass) _Array[0]).age = 10;
However, it's quite ugly:
The code will throw an InvalidCastException if the object in that array isn't of type SubClass, and the compiler cannot help you catch this.
The code is hard to understand.
Instead, you could first create a SubClass without immediately assigning it to the array, set the age as needed, and then add it to _Array:
SubClass s = new SubClass(10, 150);
_Array[0] = s;
Yes you can but compiler should complain that the object doesn't have field named age because your array is declared as containing superclasses but at runtime array[0] will be instance of subclass which effectively has age, you just have to add something in order that code compiles you should cast array[0] to subclass. I advise you to read about object oriented programming and inheritance
I have a class that calculates the mean of an ArrayList, and I'm wondering whether I have it set up correctly? I am still very new to Java, so what I want to end up with is just to take an ArrayList as a parameter, and return it within the main method using:
StatCalc stats = new StatCalc(someArrayList);
System.out.printf("Mean of someArrayList is: %.3f\n", stats.getAverage());
Here is the StatCalc class
public class StatCalc {
//declare inst variables & method
private double average = 0;
private double meanCalc(ArrayList<Double> myList) {
double sum = 0;
if (!myList.isEmpty()) {
for (Double element : myList) {
sum += element;
}
}
return sum / myList.size();
}
//Constructor
public StatCalc(ArrayList<Double> myList) {
double average = meanCalc(myList);
this.average = average;
}
//getter
public double getAverage() {
return average;
}
}
I am just wondering is this is how it's 'supposed' to be done in Java, as before I had the meanCalc method inside the constructor, which worked but I thought was bad practice?
In your constructor, you are declaring average as constructor-scoped.
Just remove double from: double average = meanCalc(myList);
That will assign your instance field, instead of a variable with the same name inside your constructor.
In turn, the getAverage() method will return instance field average after it's been assigned, instead of its default value as unassigned, which is 0.0.
In short:
//Constructor
public StatCalc(ArrayList<Double> myList) {
average = meanCalc(myList);
}
Final note
If you are delivering a functionality that only depends on the parameters given, you can probably do without creating an instance of your class.
You could simply have a static method returning double and taking a List<Double> as parameter.
FYI, under java 8+, all your code can be replaced by only one line :
List<Double> list = new ArrayList<>();
[...]
OptionalDouble average = list.stream().mapToDouble(Double::doubleValue).average();
I am doing an assignment for a beginning Java class. We have to write a commission calculator and use two classes in it. I am stuck on how to use variables from one class in a second class. The methods that i have found so far are not working for me. Any advice would be greatly helpful. Below is the code i have so far.
package calc;
/**
*
* #author Ethan
*/
import java.util.Scanner;
public class Calc {
public static void main(String[] args) {
Scanner calcu = new Scanner(System.in); //Creats the scanner used for Input
//Sets all of the variables to be used
double sal; //salary
double com1; //Comission percentage
double com2; // Find the ammount of comisssion from yearly sales
double comp; //Yearly Sales
double frac; //Decimal Comission form
double total; // Total of Compensation of Yearly salary + Comission
System.out.println("Enter the annual Salary here: ");
sal = calcu.nextDouble();
System.out.println("Enter the total Sales here: ");
comp = calcu.nextDouble();
Rate();
frac = com1/100; //converts the Sales Comission to a decimal
com2 = frac * comp; // Find the total Comission based on the
total = sal + com2; //find the total compensation
System.out.print("Your total compensation is " + total);
}
private static void Rate(){
// Rate of commission is determined below.
if (comp < 10000)
com1 = 20; //20% commission rate
else if (comp < 30000)
com1 = 22; // 22% commission rate
else if (comp < 50000)
com1 = 23; // 23% commission rate
else if (comp < 100000)
com1 = 24; // 24% commission rate
else
com1 = 25; // 25% commission rate
}
}
The problem i have is the i can't pull the rates so they can be used in the calculations.
A few major issues on your code. Your code is encapsulated in the Calc class, but no constructor is ever called. (eg. new Calc()). Rate() is a method in Calc, so it would be called by Calc.Rate(). Check out a few more examples of how to construct a java class, and you will understand encapsulation of your variables.
You only have posted one class so far. Where is the second? You will need to make sure both classes are in separate files as well.
public class Class1(){
//Class variables
public int myPublicInt; //public variables are accessable to any class that calls it
private int myPrivateInt; //private variables can not be modified outside of the class
//Class constructor, this is used to create objects of a class
public Class1(){
myPublicInt = 0;
myPrivateInt = 1;
}
//Now we have setter and getter methods to handle private variables
public void setMyPrivateInt(int newValue){
myPrivateInt = newValue;
}
public void getMyPrivateInt(){
return myPrivateInt;
}
//lastly this is a private method, only Class1 objects can call this method
//internally, so we can call it in our constructor but not from Class2
private void somePrivateMethod(){
//does something
}
}
So Now you will have some first class, it has some data and some methods and a constructor. Making variables public is not a good idea for the security of your code, you will want to make your second program create an object of the first one to access its variables and method calls. See the below program.
public class Class2{
//Class Variables, declares an object of the first class
private Class1 myClassObject;
//Constructor for this class, instantiates the first class object
public Class2(){
myClassObject = new Class1();
}
//Main method and runtime of our program
public static void main(String args[]){
Class2 thisClass = new Class2();
thisClass.printMyPrivateIntFromClass1();
}
//Method from this class, Class2
public void printMyPrivateIntFromClass1(){
System.out.println(myClassObject.getMyPrivateInt());
}
}
So in the second class we make an object of the first one, this way we can manipulate and use that object, its data and its methods. Notice that I used constructors to make objects of each class. When you call that object you can also call its public methods and variables. Again I would not recommend making variables public because then they are too easy to manipulate. If you have public methods that lead to your variables you can use those as a safer way to change or access the data stored in them. Hope this helps explain using a class inside another.
A couple of other notes, work on indentation, you should use the same indentation for code nested on the same level, and anything nested underneath something else by use of {} should be indented in once more so that code is more readable for you and others.
I'm trying to create a program that reads user input and stores it and then calculates the area of a polygon. When I try and compile it it gives me one error which is the one about .toString being non static.
import java.util.Scanner;
class regularpoTest {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
boolean finished = false;
double s;
double n;
double area;
//starts loop to record data
do {
s =0;
n =0;
System.out.println("Enter the side length, or anything else to quit: ");
s = in.nextDouble();
in.nextLine();
if (in.hasNextDouble()) {
System.out.println("Enter number of sides");
n = in.nextDouble();
area = (s*s*n)/(4*Math.tan(Math.PI/n));
} else {
finished = true;
}
} while(!finished);
//This prints out the student details
System.out.println(regularpo.toString());
}
}
public class regularpo {
private double side;
private double numberOf;
private double area;
public regularpo(double side, double numberOf){
side = 0;
numberOf = 0;
area = 0;
}
public double getSide(){
return side;
}
public double getNumberOf(){
return numberOf;
}
public String toString(){
return ("area = " + area+ " side length "+side+ " number of sides "+numberOf);
}
}
You are trying to call a method of a class, when that method has been defined for (and only makes sense as) a method of an instance of that class. Maybe you mean to make an object of that class, and call its toString method, although I can't be sure from your code.
You can not access non-static methods by using classname.nonStaticMethodName. You need to instantiate your object using the new keyword. Basically, you create an instance of your object by regularpo r = new regularpo(2.0, 2.0). After that you can invoke r.toString();
Check out this SO-question for more info.
And this Oracle-tutorial explains class members well.
Suggestions:
1) Eliminate "regularpoTest". Just move "main()" into "regularpo".
2) Capitalize "RegularPo" (by convention, class names should start with a capital letter).
3) Make the RegularPo constructor actually save the initial values (not just set them to zero).
... and, most important ...
4) Your main should call RegularPo regularPo = new RegularPo (...).
Then reference object instance "regularPo".
Try to make a object of class regularpo and call toString over that object
regularpo obj=new regularpo();
obj.toString();
Also as per conventions a class name must start with Upper case,so name your class asRegularpo
toString() is a non static method in regularpro class , and we know that the non static belongs to an object so we need to create and object of same class and call it.
toString() is belongs to Object class so its non static method.
regularpo obj=new regularpo();
obj.toString();
The aim is to be able to read data from a textfile containing information pertaining to stocklevels into an object and then manipulating that object in various ways
fields in the textfile are seperated by "#". The textfile either has 3 fields on a line or 5 fields on a line.
line with 3 fields go into the constructor of my superclass
line with 5 fields go read into the subclass
The superclass is called StockItem and the subclass is called StockItemFood, it extends StockItem(the superclass).
Below is my code, found in a seperate 'Manager' class which reads from the textfile into an array of StockItem objects. simple enough.
public void readFromText() throws IOException, FileNotFoundException{
String [] temp;
BufferedReader br = new BufferedReader (new FileReader("stocklist.txt"));
String line = br.readLine();
while(line!=null){
temp=line.split("#");
if (temp.length==3){
s[counter]=new StockItem(temp[0], (double) Integer.parseInt(temp[1]), temp[3]);
}else if (temp.length==5){
s[counter]=new StockItemFood(temp[0], (double) Integer.parseInt(temp[1]), temp[2], (double) Integer.parseInt(temp[3]), (double) Integer.parseInt(temp[4]));
}
}
counter++;
br.close();
}
In the below method i am trying to return a String that will be concatinated with the return of a method from the Superclass and a return from a method in the subclass. I cannot however see my subclass methods when i type s[y]. as seen below.
public String getOrderingList(){
String toOrder="";
for(int y = 0; y < s.length; y++){
toOrder+=s[y].getDescription() + s[y].//getOrderAmount() <-subclass method
}
}
return toOrderl
}
Below is the code for my subclass:
public class StockItemFood extends StockItem {
private double min,max; //3.2
public StockItemFood(String description, double quantity, String units,double min, double max) { //3.3
super(description, quantity, units);
this.min = min;
this.max=max;
}
public boolean mustOrder(){ //3.4
boolean b;
if(getQuantity()<min){
b=true;
} else {
b=false;
}
return b;
}
public double getOrderAmount(){ //3.5
double amount = max-getQuantity();
return amount;
}
}
I thought of maybe using instanceof but i am not entirely sure of the syntax required and i've also read several posts where it was adviced to avoid instanceof.
Any help would be much appreciated.
- Shaun
abstract class StockItem{
protected abstract double getOrderAmount();
public String getOrderingList(){
String result = method(); //can invoke it
}
}
class StockItemFood extends StockItem{
#Override
protected double getOrderAmount(){
//return the value
}
}
Abstract keyword in Java
I don't know if I have completely understood your question. But I will try to answer it. Create method getOrderAmount() as abstract in your base class.
If every StockItem in your design is going to have a order amount then you should define it as abstract method in your class StockItem.
i've also read several posts where it was adviced to avoid
instanceof.
Yes that is true, you should avoid using instanceof as it means you don't have proper design for your code.
still unclear about your explanation, the solution given is based on a feeble understanding, Explain further by editing your question and maybe a better solution will be provided then.
assuming s is an array of type SuperClass
String toOrder = "";
for(int y=0;y<s.length;y++){
toOrder+=s[y].superClassMethod();
if(s[y] instanceof subclass) {
toOrder+= ( (SubClassName)s[y]).subClassMethod();
}
}
will work for you