270 likes | 489 Views
Parameters. (And how to use them like a boss). You can already do this!. If you’ve taken an algebra class, you’ve already used parameters (even if you didn’t realize it). Consider the mathematical function: f(x) = 2x This function takes in one parameter: x.
E N D
Parameters (And how to use them like a boss)
You can already do this! • If you’ve taken an algebra class, you’ve already used parameters (even if you didn’t realize it). • Consider the mathematical function: f(x) = 2x • This function takes in one parameter: x. • Awesome mathematicians that we are, we can call this function and pass in 2: f(2). This function call will return 4: f(2) = 4. • Let’s translate this into code!
Writing a method that takes in a parameter (the “receiver”) public class Calculator { // constructor and other methods elided :) /* This method expects one parameter of type int, which it refers to as “numbah”. */ public intdoubleNumber(intnumbah) { int answer = numbah*2; // calculate numbah times two! return answer; // return the answer. } }
Writing a method that takes in a parameter (the “receiver”) public class Calculator { // constructor and other methods elided :) /* This method expects one parameter of type int, which it refers to as “numbah”. */ public intdoubleNumber(intnumbah) { int answer = numbah*2; // calculate numbah times two! return answer; // return the answer. } } parameter type parameter name The receiver must specify the type and name of every parameter it takes in!
Calling a method from somewhere else in your code (the “sender”) public class MathStudent { private Calculator _calc; // declare a Calculator named _calc /* constructor */ public MathStudent() { _calc = new Calculator(); // instantiate our Calculator _calc.doubleNumber(2); // call the method! } }
Calling a method from somewhere else in your code (the “sender”) public class MathStudent { private Calculator _calc; // declare a Calculator named _calc /* constructor */ public MathStudent() { _calc = new Calculator(); // instantiate our Calculator _calc.doubleNumber(2); // call the method! } } value The sender must pass the method a value (of a primitive type, such as “int”) or an instance of an object.
Another Example • Aisha is dog sitting for two dogs (named Sam and David), and they’re hungry! • Aisha is an instance of DogSitter. The DogSitter class has a method called feedDogs(), but it needs to be filled in. • In this method, the DogSitter should tell each of the Dogs to eat. • How do you tell a Dog to eat? Let’s look at the code for the Dog class…
The Dog Class public class Dog { // constructor and other methods elided :) /* this method takes in one parameter of type DogFood, which it refers to as “croquettes” */ public void eat(DogFoodcroquettes) { croquettes.beEaten(); } } parameter type parameter name One more time: the receiver specifies the type and name of the parameter it is expecting.
The DogSitter Class public class DogSitter { private Dog _sam; // declare _sam private Dog _david; //and _david private DogFood _food; // declare a DogFood named _food /* constructor */ public DogSitter() { _sam= new Dog(); // instantiate all instance variables! _david= new Dog(); _food = new DogFood(); } /* a method to feed the dogs */ public void feedDogs() { // we need to write code to tell _samand _davidto eat! } }
How do we call the eat(…) method on _samand _david? public class DogSitter { private Dog _sam; private Dog _david; private DogFood _food; public DogSitter() { _sam= new Dog(); _david= new Dog(); _food = new DogFood(); } /* a method to feed the dogs */ public void feedDogs() { ???????? ???????? } } public class Dog { // constructor and other methods // elided :) public void eat(DogFood croquettes) { croquettes.beEaten(); } }
How do we call the eat(…)? public class DogSitter { private Dog _sam; private Dog _david; private DogFood _food; public DogSitter() { _sam= new Dog(); _david= new Dog(); _food = new DogFood(); } /* a method to feed the dogs */ public void feedDogs() { _sam.eat(_food); _david.eat(_food); } } public class Dog { // constructor and other methods // elided :) public void eat(DogFood croquettes) { croquettes.beEaten(); } }
Wait… why can’t we just do this? public class DogSitter { private Dog _sam; private Dog _david; private DogFood _food; public DogSitter() { _sam= new Dog(); _david= new Dog(); _food = new DogFood(); } /* a method to feed the dogs */ public void feedDogs() { _sam.eat(_food); _david.eat(_food); } } public class Dog { // constructor and other methods // elided :) public void eat(DogFood croquettes) { _food.beEaten(); } } Don’t do this! It’s wrong!
Wait… why can’t we just do this? public class DogSitter { private Dog _sam; private Dog _david; private DogFood _food; public DogSitter() { _sam= new Dog(); _david= new Dog(); _food = new DogFood(); } /* a method to feed the dogs */ public void feedDogs() { _sam.eat(_food); _david.eat(_food); } } public class Dog { // constructor and other methods // elided :) public void eat(DogFood croquettes) { _food.beEaten(); } } Don’t do this! It’s wrong!
Because _food is a private instance variable of the DogSitter!!! public class DogSitter { private Dog _sam; private Dog _david; private DogFood _food; public DogSitter() { _sam= new Dog(); _david= new Dog(); _food = new DogFood(); } /* a method to feed the dogs */ public void feedDogs() { _sam.eat(_food); _david.eat(_food); } } public class Dog { // constructor and other methods // elided :) public void eat(DogFoodcroquettes) { croquettes.beEaten(); } } • Dog cannot access any of DogSitter’s private instance variables by name. • The sender’s name for the instance of DogFood it sends does not matter to the receiver. • The receiver refers to whatever DogFood it receives by the name “croquettes”!
So what’s really happening here? • DogSitterinstantiates three instance variables– two Dogs and one DogFood. DogSitter Somewhere in memory:
So what’s really happening here? • DogSitterknows the two Dogs by the names _samand _david, and the DogFoodby the name _food. DogSitter _food _sam _david Somewhere in memory:
So what’s really happening here? • _samand _davidare instances of the Dog class, and the DogSitter wants to tell them about _food! Dog DogSitter _food _sam _david Somewhere in memory:
So what’s really happening here? • But the Dogclass has no idea about the instance of DogFood that exists-- _food is just the name that DogSitter calls it! Dog DogSitter ??? Where’s my food??? _food _sam _david Somewhere in memory:
So what’s really happening here? • When DogSitter calls eatFood(_food) on a Dog, it’s telling that Dog about the instance of DogFood it calls “_food”! Dog DogSitter public void eatFood(DogFoodcroquettes) { croquettes.beEaten(); } _sam.eatFood(_food); _food _sam _david Somewhere in memory:
So what’s really happening here? • Now the Dog and the DogSitter are talking about the same instance of DogFood– but the DogSittercalls it “_food” and the Dog calls it “croquettes”. Dog DogSitter public void eatFood(DogFoodcroquettes) { croquettes.beEaten(); } _sam.eatFood(_food); _food _sam _david Somewhere in memory:
So what’s really happening here? • If the DogSitter called “_food.beEaten()”, it would have the same result as the Dog calling “croquettes.beEaten()”, because both names point to the same instance of DogFood. Dog DogSitter public void eatFood(DogFoodcroquettes) { croquettes.beEaten(); } _sam.eatFood(_food); _food _sam _david Somewhere in memory:
Would this also work? • Yes, but we are creating an instance variable that we don’t need. The name of the formal parameter “croquettes” works as a local variable that we can use inside the eat method. public class Dog { private DogFood _croquettes; // constructor and other methods // elided :) public void eat(DogFood croquettes) { _croquettes = croquettes _croquettes.beEaten(); } }
Accesors and Mutators public class Dog { private Collar _favoriteCollar; // constructor and other methods // elided :) public void setCollar(Collar collar) { _favoriteCollar = collar; } public Collar getCollar() { return _favoriteCollar; } } What are these two methods doing?
Let’s change _sam’scollar! public class ChangingCollarApp { private Collar _redCollar; private Collar _blueCollar; private Dog _sam; public ChangingCollarApp() { _sam= new Dog(); _redCollar = new Collar(); _blueCollar = new Collar(); ??????? //How do we set _sam’s //favorite collar to be the redCollar? } }
Let’s change _sam’scollar! public class ChangingCollarApp { private Collar _redCollar; private Collar _blueCollar; private Dog _sam; public ChangingCollarApp() { _sam= new Dog(); _redCollar = new Collar(); _blueCollar = new Collar(); _sam.setCollar(_redCollar); } } public class Dog { private Collar _favoriteCollar; // constructor and other methods // elided :) public void setCollar(Collar collar) { _favoriteCollar = collar; } public Collar getCollar() { return _favoriteCollar; } }
Let’s change _sam’scollar! public class ChangingCollarApp { private Collar _redCollar; private Collar _blueCollar; private Dog _sam; public ChangingCollarApp() { //instantiation elided _sam.setCollar(_redCollar); _sam.setCollar(_blueCollar); } } public class Dog { private Collar _favoriteCollar; // constructor and other methods // elided :) public void setCollar(Collar collar) { _favoriteCollar = collar; } public Collar getCollar() { return _favoriteCollar; } }
That’s it! A few things to remember: • The sender calls the receiver, and passes it either a value of a primitive or an instance of an object. • The receiver must specify the type (class) of the parameter it expects, and the name it will use to refer to that parameter from then on. • The sender and receiver usually use different names to refer to the same instance. This is OK!