2

I've been trying to understand how to call a method from inside another method of the same class by reading "Java how to program early objects".

I'm totally lost at the moment, the analogy used in the book makes it easy to visualise whats going on. However, translating that into code is challenging.

I have tried many times to figure this out and have gotten this far: P.S. for the sake of simplicity I have excluded code that I think is not important for my question...

import java.util.Scanner;

public class BuyAHouseInc
{
    private int housePrice;
    private int amountOfHouses;
    private int houseCounter;

    // method to enter the amount of houses on sale
    public void setAmountOfHouses()
    {
        // do stuff etc.
    }

    // method that sets the house price
    public void setHousePrice()
    {
        // do stuff etc.

        calculateFees(this.housePrice); // this is where I'm not sure...
    }

    //method to calculate fees and taxes
    public void calculateFees(int housePrice) // does this receive this.housePrice?
    {
      // do some stuff
    }

Tester code:

public class BuyAHouseIncTester
{
    public static void main(String[] args)
    {
        BuyAHouseInc client1 = new BuyAHouseInc("John","Doyle","15 Newton Drive\nDublin 5\n", 550000) // Create object 
        // set amount of houses on sale to client 1
        client1.setAmountOfHouses(); 

        // set house price for each of the houses added to database
        client1.setHousePrice();
    }
}

What is the code to call a method inside another method? Do the values of each individual house price get called?

  • Again, why don't you put some System.out.println() statements and test it, or run it using your debugger? You ask "Do the values of each individual house price get called?". But his question doesn't make sense: there is a **single** housePrice in this code. – JB Nizet Mar 09 '16 at 20:18
  • AFAIK, unless you use [`static imports`](https://stackoverflow.com/q/162187), unqualified method calls (let's say to `x()`) can only be interpreted as either `this.x()` or `super.x()`, with `this.x()` taking precedence. (Exception: In the case of an inner class, it can also be interpreted as `EnclosingClass.this.x()`. Not sure about precedence then.) – Siguza Mar 09 '16 at 20:19
  • There is no code prompting anything. There is no loop at all. You're asking yourself if calculateFees receives this.housePrice. So print this.housePrice() before calling the calculateFees() method, and print the housePrice argument in calculateFees(). – JB Nizet Mar 09 '16 at 20:46
  • @JB Nizet My thinking behind the code is that you enter the 1st house price and do all the code in the calculateFees method then prompt the user to enter the 2nd house price and so on. Where would you put the print statements to debug the code? –  Mar 09 '16 at 20:46
  • @JBNizet As I expected it prints the last house price I enter. How would I go about passing each house price to all the methods I have in my program and "do some stuff to the 1st house" and then I enter the 2nd house and so on. –  Mar 09 '16 at 20:52
  • You didn't post the relevant code. As previously said, in the code you posted, there is a single client, called only once, and absolutely no code asking for house prices. So we can't help. – JB Nizet Mar 09 '16 at 20:56
  • @eamonn-keogh you should use an ArrayList and store all the houses there once your finished call each objects to string method with the an enhanced for loop. – Monroy Mar 09 '16 at 21:07

4 Answers4

2

you could simple call calculateFees(housePrice); as the only housePrice variable visible at point of calling is instance variable private int housePrice;

Assuming you've a constructor call to set housePrice based on how you're creating BuyAHouseInc

//method to calculate fees and taxes public void calculateFees(int housePrice) // does this receive this.housePrice? { // do some stuff }

Yes, this would receive housePrice passed via calculateFees(housePrice);

calculateFees(int housePrice) Local variable defined above is only visible inside calculateFees(int housePrice){...} method

Passing Information to a Method or a Constructor

UPDATE: Based on comments, you'd need to update your setter to pass house price

public void setHousePrice(int housePrice)
    {
        this.housePrice = housePrice;

        calculateFees(this.housePrice); 
    }
Charu Khurana
  • 4,511
  • 8
  • 47
  • 81
  • Thank you I'll give this a try for all the methods I have –  Mar 09 '16 at 20:25
  • I tried that but I'm getting an error in the tester class... method cannot be applied to given types, the types are double found no arguments... Can you explain whats going wrong here? –  Mar 09 '16 at 20:31
  • Do you've a constructor call on `BuyAHouseInc`?\ – Charu Khurana Mar 09 '16 at 20:34
  • If you are having errors, post the stack trace. A guess would be that you're passing a double (a number with a decimal point) instead of an integer. – Christopher Schneider Mar 09 '16 at 20:34
  • In my full version of code I have a constructor but I'm only passing in a clients details e.g. name, address and budget. I'm not passing any house prices or anything like that in the constructor. –  Mar 09 '16 at 20:38
  • A stack trace or compiler error will show exactly what the problem is. From the incomplete error you gave, there is a mismatch between a method you're calling and a parameter being passed to that method. – Christopher Schneider Mar 09 '16 at 20:45
  • You're calling a constructor that doesn't exist. It would be beneficial to post a [minimal, complete, and verifiable example](http://stackoverflow.com/help/mcve) and to include the stack trace or any _exact_ errors you're seeing. – Christopher Schneider Mar 09 '16 at 20:49
  • Im working my way through it now. You're a great help thank you. –  Mar 09 '16 at 21:10
  • Glad it helped you. Don't forget to accept the answer then – Charu Khurana Mar 10 '16 at 02:13
1

Yes, your assumptions are correct.

However, there is something important to note. This code:

public void setHousePrice()
{
    // do stuff etc.

    calculateFees(this.housePrice); // <---This probably doesn't do what you think it does
}

// No. This doesn't receive this.housePrice. It receives the VALUE of this.housePrice. 
// It's a completely new variable
public void calculateFees(int housePrice) .
{
  // do some stuff
}

Java is pass by value. You're passing the value of housePrice, but you aren't modifying the original housePrice.

So if you "do some stuff" and modify the housePrice variable passed in, those changes aren't saved unless you are setting housePrice inside calculateFees.

In a case like this, it's best to manipulate any member variables through getters/setters. Convention, by the way, is that a setter should always take a value. This isn't arbitrary, as many libraries rely on set/get methods acting a certain way.

I've edited the above answer to be more clear.

Christopher Schneider
  • 3,745
  • 2
  • 24
  • 38
  • Oh! Its a completely new variable...that helps! so to store this.housePrice the calculateFees(int housePrice) parameter can't have the same name so change it from housePrice to houseCost? –  Mar 09 '16 at 21:03
  • The name can be the same. It's a little weird here. Assuming you're inside `calculateFees(housePrice)`, `housePrice` would refer to the value passed in. `this.housePrice` would refer to the member variable that belongs to the object. – Christopher Schneider Mar 09 '16 at 21:12
  • I have a love hate relationship with Java....I'll keep playing around with the code I'm sure I'll get it to work, my knowledge is at beginner level so I'm tinkering around with stuff I barely understand at the moment. Thats the best way to learn I find. –  Mar 09 '16 at 21:20
1

Please correct me if I'm wrong but is this a possible solution:

public void setHousePrice(int price)
{


    calculateFees(price); 
}


public void calculateFees(int housePrice) 
{
  // stuff with housePrice
}

then do

variable.setHousePrice(variable.getHousePrice);
0
public class BuyAHouseInc {
    private double housePrice;
    private int amountOfHouses;
    private int houseCounter;

    public BuyAHouseInc(double housePrice, int amountOfHouses, int houseCounter) {
        this.housePrice = housePrice;
        this.amountOfHouses = amountOfHouses;
        this.houseCounter = houseCounter;
    }

    // method that sets the house price
    public void generateHousePrice() {
        // do stuff etc.
        // you could also put the logic in the set method... Had to change the method name to 
        // generate as the getters and setter where created and the setter method is named
        // exactly like your previous method
        calculateFees(housePrice); // this is were I'm not sure...
    }

    // method to calculate fees and taxes
    public void calculateFees(double housePrice) // does this receive
                                                    // this.housePrice?
    {
        // do some stuff
    }

    public double getHousePrice() {
        return housePrice;
    }

    public void setHousePrice(double housePrice) {
        this.housePrice = housePrice;
    }

    public int getAmountOfHouses() {
        return amountOfHouses;
    }

    public void setAmountOfHouses(int amountOfHouses) {
        this.amountOfHouses = amountOfHouses;
    }

    public int getHouseCounter() {
        return houseCounter;
    }

    public void setHouseCounter(int houseCounter) {
        this.houseCounter = houseCounter;
    }

    @Override
    public String toString() {
    return "BuyAHouseInc [housePrice=" + housePrice + ", amountOfHouses=" + amountOfHouses + ", houseCounter="
            + houseCounter + "]";
}


}

Separate the two classes in different files. Another thing to point out is to use double for the price instead of int. You must also create the getters and setters to be able to get and set your properties. You must also add a constructor in the class. Then you can create an instance of the class in the main and call its methods. The main method would be something like below.

public class Main {

    public static void main(String... args) {
        BuyAHouseInc test = new BuyAHouseInc(200000, 4, 2);
        test.setAmountOfHouses(6); // changed from 4 to 6
        test.generateHousePrice();
        test.calculateFees(test.getHousePrice());
        test.toString();

    }
}

Hope you find this helpful and good luck ! I have edited the code and added the toString method to output information as a string.

Monroy
  • 420
  • 5
  • 19