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.
Related
I am learning Java, so I understand this is a very simple question, but I still want to understand it.
I want to let my code automatically generate soldiers, and the number automatically increases, but I failed.
the Soldier.class:
package com.mayer;
import java.util.Random;
public class Soldier {
private int number=0;
private int ATK;
private int HP;
Random ra = new Random();
public Soldier(){
this.number++;
this.ATK = ra.nextInt(10)+90;
this.HP = ra.nextInt(20)+180;
}
public void report(){
System.out.println("number:"+this.number+"\t"+
"ATK:"+this.ATK+"\t"+
"HP:"+this.HP);
}
}
the main.class
package com.mayer;
public class Main {
public static void main(String[] args) {
Soldier[] soldiers = new Soldier[5];
int i = 0;
while(i<5){
soldiers[i] = new Soldier();
i++;
}
for(Soldier sol:soldiers){
sol.report();
}
}
}
That's what I get:
number:1 ATK:94 HP:187
number:1 ATK:94 HP:181
number:1 ATK:96 HP:193
number:1 ATK:90 HP:183
number:1 ATK:95 HP:193
So you see,each of this number is 1.
You have added number field which is instance field. It will initialize per instance. You are looking for static type variable. Please check static into java.
Instance Variables (Non-Static Fields) Technically speaking, objects
store their individual states in "non-static fields", that is, fields
declared without the static keyword. Non-static fields are also known
as instance variables because their values are unique to each instance
of a class (to each object, in other words); the currentSpeed of one
bicycle is independent from the currentSpeed of another.
Class Variables (Static Fields) A class variable is any field declared with the static modifier; this tells the compiler that there
is exactly one copy of this variable in existence, regardless of how
many times the class has been instantiated. A field defining the
number of gears for a particular kind of bicycle could be marked as
static since conceptually the same number of gears will apply to all
instances. The code static int numGears = 6; would create such a
static field. Additionally, the keyword final could be added to
indicate that the number of gears will never change.
The constructor is changed to:
public Soldier(int number){
this.number = number;
this.ATK = ra.nextInt(10)+90;
this.HP = ra.nextInt(20)+180;
}
As others have said, each Soldier instance has its own separate number field which starts with 0. You can use a static field to count the instances:
public class Soldier {
private static int counter = 0;
private int number;
// other fields left out for clarity
public Soldier(){
Soldier.counter++; // field shared among all Soldier instances
this.number = counter; // number belongs to this instance only
// ...
}
// ...
}
However, I wouldn't recommend doing it this way. When you get more advanced, you'll learn that using a static field like this can cause problems in a multi-threaded application. I would instead advise passing the number to the Soldier constructor:
public class Soldier {
private int number;
// ...
public Soldier(int number){
this.number = number;
// ...
}
// ...
}
And then:
public static void main(String[] args) {
Soldier[] soldiers = new Soldier[5];
int i = 0;
while(i<5){
soldiers[i] = new Soldier(i);
i++;
}
Soldier.class
all-uppercase field names tend to be used for constants.. basic fields use headless camel-case.. They should also be descriptive, i.e. you should look at them an it should be apparent what they represent - for example a variable "number" is not a good idea, because it's ambiguous
Random can be converted to a local variable, no need to keep it on the class level
The mechanism by which soldiers are assigned IDs should be on a higher level - it can't be managed by the soldier object itself, hence the constructor with an argument
overriding the toString method is the traditional way of transforming the object to string for debugging purposes.. also most IDEs can generate it with a press of a button so no space for human error
You will obviously need getters and setters for your variables, if you wish to read or change them from elsewhere, but I don't think that's necessary to post here.
private int soldierID;
private int attack;
private int health;
public Soldier(int id){
this.soldierID = id;
Random random = new Random();
this.attack = random.nextInt(10) + 90;
this.health = random.nextInt(20) + 180;
}
#Override
public String toString() {
return "Soldier{" +
"soldierID=" + soldierID +
", attack=" + attack +
", health=" + health +
'}';
}
Main.class
it's perfectly fine and actually preferred to use a List instead of an array, because it's more comfortable to work with
this way it's even much easier to add them dynamically and use the iterator for ID
you can "report" in the creation cycle
This even shortens the method a bit, not that it's that important here.
public static void main(String[] args){
List<Soldier> soldiers = new ArrayList<>();
for(int i=0; i<5; i++){
Soldier newSoldier = new Soldier(i);
soldiers.add(newSoldier);
System.out.println(newSoldier.toString());
}
}
This way when you define the soldier IDs it's not from within the Soldier class but rather from something that is "observing" all the soldier classes and knows which is which.
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
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();
I am trying to build a complete program from the partial code of a book. The difficulty is when a variable's modifier is set to private, I can't access it from the main method of my BankTest class after instantiating an object. Am confused on how to pass the Dollar Object as I can't set it to a primitive type like double or float.
Is there a way to set the Dollar object with amount = 100, so that when I run the BankTest class, I could get it to print the getAmount = 100 ? I want to maintain the Dollar object as the parameter of a method if possible ?
final class BankTest {
public static void main(String args[]) {
BankAccount ba = new BankAccount();
Dollar d = new Dollar(100);
//d.setAmount(100.00); "IF class Dollar method is PUBLIC"
//ba.deposit(d); "How to set the value of Dollar Object ??
System.out.println("Balance available: " + d.getAmount());
}
}
final class BankAccount {
private Dollar balance;
private boolean receipt;
public void deposit(Dollar amount, boolean receipt) {
balance.add(amount);
// if receipt == true, print receipt
}
public void deposit(Dollar amount) {
// validate and chain to base method
deposit(amount, true);
}
}
final class Dollar {
private double amount = 0;
public Dollar(double _amount) {
setAmount(_amount);
}
private void setAmount(double amt) { //can only be called by within Dollar class
// make sure amt is a valid currency amount
amount= amt;
}
double getAmount() {
return amount;
}
public void add(Dollar amt) {
// validate amt
amount+= amt.getAmount();
}
}
It seems Dollar was created to not be modified, but I wonder why the attribute is not final and why it can be modified by adding another Dollar object...
The idea is you have to create a new instance of Dollar every time you need a new value. Something similar happens with String and any primitive wrapper class (Integer, Float...).
As you are taking the code from a book you can decide how to deal with it: you can make the setter public or you can live with the current status and create a new object when needed.
You can already add an amount, so I think I'd modify the setter to public
Simply make setAmount public.
And also add a getter. eg getAmout() that returns the current dollar value.
Setters and getters are meant to be public, else they are pointless.
You could also pass the dollar value in the constructor.
~~~Update: Solved! Thanks everyone!~~~
I'm working on a project from the Blue Pelican Java book, lesson 16 project Gas Mileage. It asks to create two classes, one is Automobile which holds the methods I will work with. The other class, Tester, is the main class. Every time I run the Tester class, it returns a value of -Infinity. I can't figure out why, other than that I've singled out the problem is in the Automobile class at line 14 in the takeTrip method. When I leave that method out of the Tester class, it returns the correct values.
This is the Automobile class:
public class Automobile
{
public Automobile(double m) // Accepts value m to the double mpg. Also declares
{
double mpg = m;
double gallons;
}
public void fillUp(double f) // Adds fuel to the tank
{
gallons += f;
}
public void takeTrip(double t) // Takes away fuel from the tank depending upon how many miles are driven
{
gallons -= t / mpg; // Not sure how to do this line. For some reason, when I reference mpg, the output of Tester is "-infinity". Shouldn't it do gallons = gallons - (miles driven / mpg)?
}
public double reportFuel() // Returns value of how much fuel is left in tank
{
double r = gallons;
return r;
}
public double mpg;
public double gallons;
}
And this is the Tester class:
public class Tester
{
public static void main(String args[])
{
Automobile myBmw = new Automobile(24); // Passes constructor argument of 24 mpg
myBmw.fillUp(20); // Adds 20 gallons to fillUp method
myBmw.takeTrip(100); // Takes away the fuel used for 100 miles using the takeTrip method
double fuel_left = myBmw.reportFuel(); // Initializes fuel_left to the method reportFuel
System.out.println(fuel_left);
}
}
Any help is appreciated, thanks!
-AJ
You constructor doesn't need the 'double' identifier. Here you are creating a new variable also called mpg, which is forgotten after the constructor completes. Instead use this:
public Automobile(double m) // Accepts value m to the double mpg. Also declares
{
mpg = m;
}
This is the problem:
public Automobile(double m) // Accepts value m to the double mpg. Also declares
{
double mpg = m;
double gallons;
}
This is declaring a local variable called mpg, rather than changing the value of the instance variable for the object. (The instance variables are declared at the bottom of the class.) It's then declaring another local variable called gallons which isn't assigned any value. At the end of the constructor, the instance variables gallons and mpg will both be zero - which means you'll be dividing by zero in the takeTrip method - so you're subtracting "infinity gallons" from the fuel tank, leading to your final result. Your constructor should look like this instead:
public Automobile(double m)
{
this.mpg = m;
}
or just:
public Automobile(double m)
{
mpg = m;
}
If you're still unsure about local variables and instance variables after this, see if there's anything earlier in the book which might help you. (By lesson 16 I'd expect it to have been covered...)
In your Automobile c'tor, you're currently creating a local variable called mpg, instead of changing the class member. All there should be in that function is mpg = m; (the second line does nothing).
Currently, mpg (the member) is automatically initialized to 0, and then t/mpg is infinity, and when you take that away from some finite number, you get -infinity.
By the way, in reportFuel(), you could just as well just write return gallons;, without declaring r.
public class Automobile {
private double mpg = 0; //need to handle the division by 0 if you
//initialize it to 0
private double gallons = 0;
public Automobile(double m, double g)
{
mpg = m;
gallons = g;
}
Why are again declaring your attributes inside your constructor where as you have already declared them in your class. Actually the attributes you are declaring inside the constructor will not persist after the execution of the method ends (in this case the constructor). So though you are trying to initialize the attributes of your class you are actually not doing this.
So in your constructor try this
mpg=m
gallons=0
I think the other methods are fine. Another thing try to keep those attributes (mpg and gallons) private. Though the program will run without any error still you are violating the main thing of oop - encapsulation. cheers :)