Calling an instance method from a different class - java

The purpose of this program is to test another program I created.
It's called ComplexNumber. This class has everything from add, multiply, dividing complex numbers numbers and stuff and they are all in methods. The teacher wants us to create a testing class, here is what I have so far.
The problem I am having is calling the methods from the ComplexNumber class. For example: I tried calling the plus method, this method takes in two ComplexNumbers and adds them up. So far I've been testing these methods using the interaction panel and it has worked great. The way I called them in the interaction panel was by doing first.plus(Second) and this would give the final values.
On the testing class, I am having difficulty calling the methods.
I know that I need the class name.
I tried:
ComplexNumber.first.plus(second)
But it didn't work.
How can I do it?
Here is my code:
class TestComplexNumber
{
double real;
double imag;
public TestComplexNumber(double a, double b)
{
this.real=a;
if ((b<1000)&&(b>-1000))
this.imag=b;
else
{
this.imag=0;
System.out.println("The value you typed in for imag is <1000 or >-1000, value of imag is assigned the value of 0.");
}
}
public String toString()
{
double real,imag;
real=this.real;
imag=this.imag;
if (((real<0)||(real>0))&&(imag%1!=0))
{
if (roundThreeDecimals(imag)>0)
return ""+roundThreeDecimals(real)+"+"+roundThreeDecimals(imag)+"i";
else
return ""+roundThreeDecimals(real)+""+roundThreeDecimals(imag)+"i";
}
else if ((real%1!=0)&&(imag!=0))
return ""+roundThreeDecimals(real)+"+"+(int)imag+"i";
else if((real==0)&&(imag%1!=0))
return ""+imag+"i";
else if ((real==0)&&(imag !=0))
return ""+(int)imag+"i";
else if ((imag==0)&&(real!=0))
return ""+(int)real+"";
else if (((real<0)||(real>0))&&(imag<0))
return ""+(int)real+"-"+(int)Math.abs(imag)+"i";
else if((real!=0)&&(imag!=0))
return ""+(int)real+"+"+(int)imag+"i";
else
return "";
}
public static double roundThreeDecimals(double c)
{
double temp = c*1000;
temp = Math.round(temp);
temp = temp /1000;
return temp;
}
public static void main(String args[])
{
for(int i=0;i<1;i++)
{
//Testing decimal values
TestComplexNumber first=new TestComplexNumber((int)(Math.random()*100)-(int)(Math.random()*100),(Math.random()*100));
TestComplexNumber second=new TestComplexNumber((Math.random()*100),(Math.random()*100)-(int)(Math.random()*100));
//Testing whole values
TestComplexNumber third=new TestComplexNumber((int)(Math.random()*100)-(int)(Math.random()*100),(int)(Math.random()*100));
TestComplexNumber fourth=new TestComplexNumber((Math.random()*100)-(int)(Math.random()*100),(int)(Math.random()*100));
System.out.println(first);
System.out.println(second);
System.out.println(third);
System.out.println(fourth);
System.out.println("Test value for plus:"+first+second+" which added="+plus(second));
}
}
}
Example of a method on the ComplexNumber class:
public ComplexNumber plus(ComplexNumber other) {
ComplexNumber sum= new ComplexNumber(this.real,this.getImag());
sum.real=(this.real)+(other.real);
sum.setImag((this.getImag())+(other.getImag()));
return sum;
}

public class Tester {
public static void main(String [] args) {
// create two objects of ComplexNumbers with whatever values you like
ComplexNumber numA = new ComplexNumber(....);
ComplexNumber numB = new ComplexNumber(....);
// then add them and store the returned reference into a new variable
ComplexNumber result = numA.plus(numB);
// print the number however you like
System.out.println(result.real + " + i" + result.getImag());
}
}

I don't know what this "interaction panel" is, but first.plus(second) from there should work no different than in the actual code.
plus is the method called in the first instance.
The method should not be static, as in static ComplexNumber plus(ComplexNumber other), so you do not need the class name to use it.
In conclusion, to call an instance method from another class, you need an instance, which you have should have four calls to new ComplexNumber(), and not new TestComplexNumber()
My teacher said i have to create the testing program in a new class and not on the ComplexNumber class
I think your real issue is that you have this class TestComplexNumber, which is only intended to be a "test class" (only need a main method), not a re-creation of the ComplexNumber class, which seems to be what you've done (since I see no plus, mutiply, divide, etc).
And if you are supposed to actually create a "test suite", not a main method, then you should use JUnit, or other testing framework

Related

Why are the variables I'm requesting showing up as 0.0 when called from another class?

So basically my program is a StudySchedule where it takes user input (StudyTime, Subjects, PrioritizedSubjects, PriorityScale) and then creates a schedule based off each of those values. It begins with a class CreateSchedule which takes all the user input and then my other class CalculateScheduleTime takes the input and makes calculations (Calculate does extend to Create).
But when I request the variables from CreateSchedule, to CalculateScheduleTime, the variables appear as 0.0 rather than the number I had put in.
class CreateSchedule extends Test {
public String ScheduleName;
public double userStudyTime;
public double userSubjects;
public double userPrioritySubjects;
public double userSubjectScale;
public String getScheduleName() {
ScheduleName = setScheduleName();
return (ScheduleName);
}
public double getuserStudyTime() {
userStudyTime = setuserStudyTime();
return (userStudyTime);
}
public double getuserSubjects() {
userSubjects = setuserSubjects();
return (userSubjects);
}
public double getuserPrioritySubjects() {
userPrioritySubjects = setuserPrioritySubjects();
return (userPrioritySubjects);
}
public double getuserPriorityScale() {
userSubjectScale = setuserPriorityScale();
return (userSubjectScale);
}
public static String setScheduleName(){
System.out.println("What would you like to name your Schedule?");
Scanner sch = new Scanner(System.in);
return sch.nextLine();
}
public static double setuserStudyTime(){
System.out.println("How many hours are you studying for?");
Scanner sch = new Scanner(System.in);
return sch.nextDouble();
}
public static double setuserSubjects (){
System.out.println("How many subjects are you studying?");
Scanner sch = new Scanner(System.in);
return sch.nextDouble();
}
public static double setuserPrioritySubjects (){
System.out.println("How many subjects are you prioritizing?");
Scanner sch = new Scanner(System.in);
return sch.nextDouble();
}
public static double setuserPriorityScale (){
System.out.println("On a scale of 1 - 5, how much priority would you like to give the prioritized subjects?");
Scanner sch = new Scanner(System.in);
return sch.nextDouble();
}
public double confirm() {
System.out.println("Input Results:");
System.out.println("Schedule Name: " + ScheduleName);
System.out.println("Study Time: " + userStudyTime);
System.out.println("Subjects: " + userSubjects);
System.out.println("Priority Subjects: " + userPrioritySubjects);
System.out.println("Priority Scale" + userSubjectScale);
return (0);
}
}
class CalculateScheduleTime extends CreateSchedule {
public double SubjectPriorityTime;
public double SubjectRemainderTime;
public CalculateScheduleTime() {
}
public double calcSubjectPriorityTime() {
System.out.println("Priority" + userSubjectScale);
double PriorityPercent = ((double) (userSubjectScale / 5.0));
System.out.println(userSubjectScale);
SubjectPriorityTime = ((double) (PriorityPercent * userStudyTime));
System.out.println("Time to Prioritized Subject is: " + SubjectPriorityTime);
return (SubjectPriorityTime);
}
public double calcSubjectRemainderTime() {
System.out.println("Remainder");
SubjectRemainderTime = ((double) (SubjectPriorityTime - userStudyTime));
System.out.println("Remainder time to Subject is: " + SubjectRemainderTime);
return (SubjectRemainderTime);
}
}
public class Test {
public static void main(String[] args) {
CreateSchedule user = new CreateSchedule();
user.getScheduleName();
user.getuserStudyTime();
user.getuserSubjects();
user.getuserPrioritySubjects();
user.getuserPriorityScale();
user.confirm();
CalculateScheduleTime calc = new CalculateScheduleTime();
calc.calcSubjectPriorityTime();
calc.calcSubjectRemainderTime();
}
}
That's not what subclassing is for.
A class describes what a given instance can do. "Dog" is a class. "Lassie" is an instance of it.
Subclassing is a thing you do to concepts, not instances. You might for example have a class "Animal", and a subclass "Dog": Dog simply specializes Animal: Any Dog is also an Animal and therefore can do and has all the properties that all Animals have, and perhaps a few additional things and properties (in java parlance: It would have all fields and methods of the superclass, and can add more. It cannot remove any).
When you write CreateSchedule user = new CreateSchedule(); that's like writing: Dog rover = new Dog(); - then you write CalculateScheduleTime calc = new CalculateScheduleTime(); which is like writing GermanSchnauser fifi = new GermanSchauser();.
You made a whole new dog, which gets its own copy of all those fields, which are all still 0 - uninitialized.
The 'calc' stuff should just go in CreateSchedule, probably. But there is a ton wrong with this code:
Classes represent tangible concepts. A good class name is 'Schedule'. Or perhaps 'ScheduleCreator'. 'CreateSchedule' is not a proper class name, and thinking about it as 'the code for creating schedules' is just plain incorrect, the right way to think about classes is about what they represent. "It is the code that explains what Schedules can do and how to create them", that's a proper way to think about it (and that class would be called Schedule. Not CreateSchedule).
methods named getX should not have sideeffects.
You should not be making a new scanner every time.
setters take an argument. They don't ask the user.
Separate concerns. A Schedule should just do schedule stuff - something else should be doing the interaction with the user. Either a main method or a class for this (perhaps TextBasedScheduleCreator).
Those calcX() methods store the result in a field, return it, and that field is never actually used anywhere. Just return it, don't have that field.

Abstract class cannot be instantiated

I had to create this point program a year ago, a year ago it worked fine. Now I have to revisit it and upon compiling and trying to run it I ran into the error of the fact that an abstract class cannot be instantiated. I have done some looking around online and figured out that some update or sort with Java has made it where the method of using PointClass point1 = new PointClass(); is no longer valid and will through an error.
I have yet to find an answer for fixing the error when trying to instantiate the class using a driver program. I also saw that in order to use an abstract class now, a subclass must be present. The thing is is that due to the instructions of the program I cannot use a subclass. Only the driver and the point class.
The program is very simple, just declare some points and call them from the abstract class in order to print to the screen. I need some help on figuring out the updated method to make this work again without the instantiated error.
The PointClass
public abstract class PointClass {
private int pointX;
private int pointY;
//set instance variables
public PointClass() { this.pointX = 10; this.pointY = 10; }
public PointClass(int x, int y){ this.pointX = x; this.pointY = y; }
//make getters and setters
public void setPointX(int x) { this.pointX = x; }
public void setPointY(int y) { this.pointY = y; }
public int getPointX() { return this.pointX; }
public int getPointY() { return this.pointY; }
//make string for format with driver
public String toString() { return "x = " + this.pointX + " y = " + this.pointY; }
}
The Driver
public class PointTest {
public static void main(String[] args){
System.out.println();
PointClass point1 = new PointClass(); //set point1 as no argument
PointClass point2 = new PointClass(11, 24); // set point2 as argument with x and y
System.out.println("Point1: " + point1); //display point1 from toString method
System.out.println();
System.out.println("Point2: " + point2); //display point2 from toString method
System.out.println("---------------------");
}
}
The best thing to do would be to remove the abstract keyword. There's no need for it. Point has no abstract methods.
If you can't do that for whatever reason, you can create inline anonymous classes by adding curly braces after each instantiation:
PointClass point1 = new PointClass() { };
PointClass point2 = new PointClass(11, 24) { };
By the way, your claim that this used to work is incorrect. It has never been possible to directly instantiate an abstract class. That is in fact the entire point of the keyword, to prevent a class from being instantiated.

How to expand a randomHuman constructor to take two types of objects?

I am a java-noob as I recently started to learn in a course.
I have created a class:Humans which have ability to store their name and age, and also a subclass Students which extends Humans and adds the Year they began there studies.
I have constructed a randomHuman constructor where I call it(in my main class) and create a list with the humans(with random name and age).
My problem is when i want to random 5 human non-students and 5 students and create this list, I'm not sure how to find out what type of object is sent to the random constructor, so i know if i should give it a year or not. And what type to tell the constructor to return.
I am sorry that this turned into an essay, but if anyone would be so kind to help then I would greatly appreciate it.
TLDR; How to expand a randomHuman constructor to take two types of objects?
Here is my main class:
public class Main {
public static void main(String []args){
Human newHuman = new Human( 18, "Tommy");
System.out.println("Age: " + newHuman.getAge());
System.out.println("Name: " + newHuman.getName());
System.out.println(newHuman.toString());
Human putte = new Human (25,"Putte");
System.out.println(putte);
//Varför blir det så?
//kanske lokal variabel
//Array RandomHumans
System.out.println(" ");
System.out.println("Array Human");
ArrayList<Human> myAl = new ArrayList();
for(int i = 0; i<15; i++){
Human xx =Human.randomHuman();
myAl.add(xx);
}
//Array RandomFysiker
for(int j = 0; j<myAl.size(); j++){
Human var = myAl.get(j);
System.out.println(var.toString());
}
System.out.println(" ");
System.out.println("Array Fysiker");
ArrayList<Fysiker> myAl2 = new ArrayList();
//puts the Fysiker in an array
for(int i = 0; i<15; i++){
Fysiker xx =Fysiker.randomHuman();
myAl2.add(xx);
}
//prints teh array
for(int j = 0; j<myAl2.size(); j++){
Fysiker var = myAl2.get(j);
System.out.println(var.toString());
}
}
}
and my Human class:
public class Human {
public String name;
public int age;
Human(int ageIn, String nameIn){ //Constructor
age=ageIn;
name=nameIn;
}
public int getAge(){
return age;
}
public String getName(){
return name;
}
public String toString(){
return "Name: " + getName() +"," + " Age: " + getAge();
}
//Random human
// Behöver ändra konstruktorn så att den kan kolla
// om objectet är Fysiker eller Human och sedan,
// Behandla dom olika
//Problem1: Hur kollar man? Föreslag if(obj instanceof Fysiker), men vad ska jag ha som obj
//Problem2: Vilken returtyp ska man då ha?
public static Human randomHuman(){
String[] anArrayOfStrings={"Tom", "Jon", "Chris","Julian","Roberto","Sam","Lisa","Roxanne","Rebecca","Anton","Johannes","Antonella","Bianca"};
int randomAge = (int) (100*Math.random());
String randomName = anArrayOfStrings[(int)(Math.random()*anArrayOfStrings.length)];
int RandomYear = (int) (Math.random()*(2013-1932) + 1932);
// if(xx instanceof Fysiker){
//
// }
return new Human(randomAge,randomName);
}
}
and the subclass Fysiker(aka student):
/**
*
* #author Julian
*/
public class Fysiker extends Human{
public int schoolYear;
public Fysiker(int startYear,int ageIn, String nameIn){
super(ageIn, nameIn);
if (age>15){
if (startYear>2013){
} else if (startYear<1932){
} else {
schoolYear = startYear;
}
} else {
}
}
public int getYear(){
return schoolYear;
}
public String toString(){
return super.toString() +","+" Startyear: " +getYear();
}
}
Actually, your randomHuman() method, as mentioned in the comments, is not a constructor at all. It's a static factory method, although I'm sure you're not aware of what that means as yet.
Basically, a constructor is not a method at all and doesn't have a return type. What a constructor does is provide an initialization for a new instance of the class, created by using new, although it can do things that don't strictly initiate the fields of that object.
A method, in contrast, can return something. And in your particular case, the last line actually tells you exactly what it returns - it's calling new for the class Human, so it will return an object of class Human, never a Student.
In fact, the class Human is not aware of the class Student. In principle, you could write a subclass for a class, years after the parent class has been written. Parent classes don't need to know about their descendents. They just decide what they allow those descendents to change and what they don't allow them to change.
You could, in theory, put a method in Human that creates a Student instance. But I'm pretty sure that's not needed in the current situation.
What you probably want to do is fill a list of humans outside the definition of either Human or Student. Filling a random list is probably not part of "being a human" or "being a student" is all about, so you should just do it in your Main class, calling new Human() or new Student() as you wish and filling them as appropriate. Since you know which new you called, you also know whether or not to use a random year.
You could do it in a static method in your Main class, to signify that this is something you do for testing, and not really part of the logic of either a Human or a Student.
As for being able to tell which object you now got from the list - you can do that with instanceof. But you'll also need to typecast it to Student if you want to access its getYear() method.
However - and this is the neat thing about polymorphism - if you just call the toString() method, and don't even check the type of the object, you'll get it with the year if it's really a Student object, and without it if it's a plain Human object.
Let's assume your teachers actually want you to extend the randomHuman method so that it sometimes gives Human instances, and sometimes Students. When it gives Student, it should of course provide it with a year.
As I said above, this is called Tight Coupling between parent and subclass, and is not recommended. If I wanted to build another human subclass, such as Politician, I'd have to call you and ask you to release a new version of Human that also sometimes gives random Politicians. So, under protest, I'll explain how to do it.
Your existing function is:
public static Human randomHuman(){
String[] anArrayOfStrings={"Tom", "Jon", "Chris","Julian","Roberto","Sam","Lisa","Roxanne","Rebecca","Anton","Johannes","Antonella","Bianca"};
int randomAge = (int) (100*Math.random());
String randomName = anArrayOfStrings[(int)(Math.random()*anArrayOfStrings.length)];
int RandomYear = (int) (Math.random()*(2013-1932) + 1932);
// if(xx instanceof Fysiker){
//
// }
return new Human(randomAge,randomName);
}
We change it like so:
public static Human randomHuman(){
String[] anArrayOfStrings={"Tom", "Jon", "Chris","Julian","Roberto","Sam","Lisa","Roxanne","Rebecca","Anton","Johannes","Antonella","Bianca"};
int randomAge = (int) (100*Math.random());
String randomName = anArrayOfStrings[(int)(Math.random()*anArrayOfStrings.length)];
Human result = null;
if ( Math.random() < 0.5 ) {
// With a probability of 50%, create a plain human
result = new Human( randomAge, randomName );
} else {
// Create a student. Start by calculating a random year.
int randomYear = (int) (Math.random()*(2013-1932) + 1932);
result = new Fysiker( randomYear, randomAge, randomName );
}
return result;
}
So, you decide that you want to make a plain human, and within the scope of that decision, you create it with new Human(...) and assign to the result variable.
If you decide to make a student, within the scope of that decision, you calculate a random year, and create it with new Fysiker(). You can assign it to the variable result because polymorphically, it's Human. But in reality, internally, it's a Student.
You return the result variable, which may contain either a Human or a Student at this point.
For determining what type the object instance is use either object instanceof class or object.getClass().equals(Clazz.getSimpleName())
For return type just use the superClass (or interface). You can always cast it to the child if needed.
If you want to create 5 class of each you need a boolean in the method declaration and call it 5 times each to be sure u will have 5 instances of each class.
public static Human randomHuman(boolean isHuman){
If this is not important u can add a random boolean and then call the constructor:
boolean isHuman = Math.random() < 0.5;
if(!isHuman){
int RandomYear = (int) (Math.random()*(2013-1932) + 1932);
// create student
} else {
// create human
}

Function of return statement and method parameters in java?

I'm a beginner in java. I don't know the function of return statement and method parameters in java. Can you please explain it to me further and when should it be used?
Here's my code:
public class Person{
public void display (String name){
System.out.println("hello" + name );
}
public int execute (int num1, int num2){
int result = num1 + num2;
return result;
}
public void display1(int num){
System.out.println("the number is: " + num);
}
}
According to how i understand you question, the return parameter (datatype according to what i understood) is the data type your method should retrun when called (e.g. void int,string,float).
The second question which i think you are asking is when to use the return key name in a method. This should be used when you have a method that you want to return results to the calling variable after execution of the method e.g
//this is a your class that performs some related task
public class Person{
public void display (String name){
System.out.println("hello" + name );
}
public int execute (int num1, int num2){
int result = num1 + num2;
return result;
}
public void display1(int num){
System.out.println("the number is: " + num);
}
}
//main class or the calling class
public class MainCallingClass {
public static void main(String[] args) {
//instantiate the Person class here
Person prsn = new Person();
//calls the execute(),which adds 2 numbers inside Person class
int getSum = prsn.execute(1,1);
System.out.println("Sum of 1 and 1 is: " + getSum );
}
}
Parameters refers to the list of variables in a method declaration. Arguments are the actual values that are passed in when the method is invoked. When you invoke a method, the arguments used must match the declaration's parameters in type and order.
Example:
double sales_tax(double price)
{
return 0.05 * price;
}
After the function has been defined, it can be invoked as follows:
sales_tax(10.00);
In this example, the function has been invoked with the number 10.00. When this happens, 10.00 will be assigned to price, and the function begins calculating its result. The steps for producing the result are specified below enclosed in {} "0.05 * price" indicates that the first thing to do is multiply 0.05 by the value of price, which gives 0.50. "return" means the function will produce the result of "0.05 * price". Therefore, the final result is 0.50.
The return statement is used to explicitly return from a method. That is, it causes program control to transfer back to the caller of the method. As such, it is categorized as a jump statement. A brief look at return is presented here.
like for example:
public int execute (int num1, int num2){
int result = num1 + num2;
return result;
}
Person prsn = new Person();
int getSum = prsn.execute(1,1);
the value of getSum will be the value of result through which you have returned in the method execute that you have invoked.
From this page:
This example shows a simple method that computes the area of a rectangle:
public static int computeArea(int width, int height) {
int area; // This is a local variable
area = width * height;
return area;
}
Line 1: This is the method header. The first int indicates that the value this method returns is going to be an integer. The name of the function is "computeArea", and it has two integer parameters: width and height.
Line 2...4: The body of the method starts with the left brace, "{", on the end of the first line. The "{" doesn't have to be on the same line as the header, but this is a common style.
The body of this simple function contains a declaration on line 2, an assignment statement in line 3, and a return statement on line 4. If a method returns a value, then there must be at least one return statement. A void method (one which does not return a value),
does not require a return statement, and will automatically return at the end of the method.

Getting value to display for Java CurrentAccount class

package bankAccount;
public class CurrentAccount {
int account[];
int lastMove;
int startingBalance = 1000;
CurrentAccount() {
lastMove = 0;
account = new int[10];
}
public void deposit(int value) {
account[lastMove] = value;
lastMove++;
}
public void draw(int value) {
account[lastMove] = value;
lastMove++;
}
public int settlement() {
int result = 0;
for (int i=0; i<account.length; i++) {
result = result + account[i] + startingBalance;
System.out.println("Result = " + result);
}
return result;
}
public static void main(String args[]) {
CurrentAccount c = new CurrentAccount();
c.deposit(10);
}
}
At the moment, when I run the class, the expected System.out.println does not appear, and if I simply move public static void main(String[] args) to the top, this generates multiple red points. What is the best way for me to refactor my code so it works in the expected way?
you can have another class called Main in the file Main.java in which you can write your
public static void main(String args[])
and call
c.settlement();
in you main() to print.
Also one more advice,
in your constructor you have
account = new int[10];
which can hold only 10 ints.
in your deposit() and draw() you are not checking the account size. When the value of lastMove is more than 10 , the whole code blows up.
Hence I suggest you to use ArrayList
You never called the settlement method...
public static void main(String args[]) {
CurrentAccount c = new CurrentAccount();
c.deposit(10);
c.settlement();
}
I have the feeling that you come from some non-OOP language, like C or PHP. So some explanation:
The main method is static: that means it "exists" even when there is no object instance created, it can be thought of as if it belonged to the class instance.
on the contrary, for the other methods to "work", an instance is required.
This way the main method can be (and is actually) used as the entry point of the application
It is executed, and when it exists, (if no other threads are left running) the application terminates.
so nothing else is run that is outside of this method just by itself...
so if you don't call c.settlement(); - it won't happen...
Other notes:
Running main doesn't create an instance of the enclosing class
with new CurrentAccount(), you create an object instance, which has states it stores, and can be manipulated
be careful with arrays, they have to be taken care of, which tends to be inconvenient at times...
Why do you expect the printed output to appear? You don't actually call the settlement method, so that command is not executed.
You did not call settlement.. so nothing appears
if you add c.settlement... it is fine..
You have not called deposit() and settlement() in the main method untill you call, You cannot get expected output.

Categories