Hi can someone please help me,I am a novice programmer and I don't understand the following code.
How does one.bark() automatically returns the statement under the first if condition. How does the compiler know which if statement to display (because we are not passing the size while calling bark())? I know the object calls the function setSize and passes the argument 70 to it. Does that mean that the value 70 becomes an attribute of the object one?
Code:
class GoodDog {
private int size;
public void setSize(int s) {
size = s;
}
public int getSize()
{
return size;
}
void bark()
{
if (size > 60)
{
System.out.println("Wooof! Wooof!");
}
else if (size > 14)
{
System.out.println("Ruff! Ruff!");
}
else
{
System.out.println("Yip! Yip!");
}
}
}
class GoodDogTestDrive
{
public static void main (String[] args)
{
GoodDog one = new GoodDog();
one.setSize(70);
GoodDog two = new GoodDog();
two.setSize(8);
System.out.println("Dog one: " + one.getSize());
System.out.println("Dog two: " + two.getSize());
one.bark();
two.bark();
}
}
Yes. When you call one.setSize(70), the size variable is saved as 70 in the one object. When you call one.bark(), size is still 70
When creating an object of a class , the object receives a copy of all non-static members of the class.
GoodDog one = new GoodDog();
object one contains a special copy of size. Like wise object two will have its own copy of member variable size.
When you set the size using setSize() function , the one object's size variable is modified and will contain the same value until another value is assigned.
When you call the bark function using one function , it's own copy of size variable is taken and used inside the bark function.
Actually, 70 is not a new attribute, but the size attribute takes the value 70.
And since you have two distinct instances (Dog one and Dog two) of GoodDog, each one has it's own attribute size, which has it's own value (in this case 70 and 8).
From there, when you call the bark method, each instance (one /two) will check the if/else statement according to it's own attribute's value (respectively 70 / 8).
Related
Preface
I'd like to saying two things:
I don't know how to phrase this question in a few words. So I can't find what I'm looking for when searching (on stackoverflow). Essentially, I apologize if this is a duplicate.
I've only been programming Java consistently for a month or so. So I apologize if I asked an obvious question.
Question
I would like to have a method with a parameter that holds (path to) an integer.
How is such a method implemented in Java code?
Restrictions
The parameter should be generic.
So, when there are multiple of that integer variables, the correct one can be used as argument to the method, when it is called (at runtime).
My Idea as Pseudo-Code
Here's the idea of what I want (in pseudo-code). The idea basically consist of 3 parts:
the method with parameter
the variables holding integer values
the calls of the method with concrete values
(A) Method
.
Following is the definition of my method named hey with generic parameter named pathToAnyInteger of type genericPathToInt:
class main {
method hey(genericPathToInt pathToAnyInteger) {
System.out.println(pathToAnyInteger);
}
}
(B) Multiple Integer Variables
Following are the multiple integer variables (e.g. A and B; each holding an integer):
class A {
myInt = 2;
}
class B {
myInt = 8;
}
(C) Method-calls at runtime
Following is my main-method that gets executed when the program runs. So at runtime the (1) previously defined method hey is called using (2) each of the variables that are holding the different integer values:
class declare {
main() {
hey("hey " + A.myInt);
hey("hey " + B.myInt);
}
}
Expected output
//output
hey 2
hey 8
Personal Remark
Again, sorry if this is a duplicate, and sorry if this is a stupid question. If you need further clarification, I'd be willing to help. Any help is appreciated. And hey, if you're going to be unkind (mostly insults, but implied tone too) in your answer, don't answer, even if you have the solution. Your help isn't wanted. Thanks! :)
Java (since Java 8) contains elements of functional programing which allows for something similiar to what you are looking for. Your hey method could look like this:
void hey(Supplier<Integer> integerSupplier) {
System.out.printl("Hey" + integerSupplier.get());
}
This method declares a parameter that can be "a method call that will return an Integer".
You can call this method and pass it a so called lambda expression, like this:
hey(() -> myObject.getInt());
Or, in some cases, you can use a so called method referrence like :
Hey(myObject::getInt)
In this case both would mean "call the hey method and when it needs an integer, call getInt to retrieve it". The lambda expression would also allow you to reference a field directly, but having fields exposed is considered a bad practise.
If i understood your question correctly, you need to use inheritance to achive what you are looking for.
let's start with creating a hierarchy:
class SuperInteger {
int val;
//additional attributes that you would need.
public SuperInteger(int val) {
this.val = val;
}
public void printValue() {
System.out.println("The Value is :"+this.value);
}
}
class SubIntA extends SuperInteger {
//this inherits "val" and you can add additional unique attributes/behavior to it
public SubIntA(int val) {
super(val);
}
#override
public void printValue() {
System.out.println("A Value is :"+this.value);
}
}
class SubIntB extends SuperInteger {
//this inherits "val" and you can add additional unique attributes/behavior to it
public SubIntB(int val) {
super(val);
}
#override
public void printValue() {
System.out.println("B Value is :"+this.value);
}
}
Now you method Signature can be accepting and parameter of type SuperInteger and while calling the method, you can be passing SubIntA/SuperInteger/SubIntB because Java Implicitly Upcasts for you.
so:
public void testMethod(SuperInteger abc) {
a.val = 3;
a.printValue();
}
can be called from main using:
public static void main(String args[]){
testMethod(new SubIntA(0));
testMethod(new SubIntB(1));
testMethod(new SuperInteger(2));
}
getting an Output like:
A Value is :3
B Value is :3
The Value is :3
Integers in Java are primitive types, which are passed by value. So you don't really pass the "path" to the integer, you pass the actual value. Objects, on the other hand, are passed by reference.
Your pseudo-code would work in Java with a few modifications. The code assumes all classes are in the same package, otherwise you would need to make everything public (or another access modifier depending on the use case).
// First letter of a class name should be uppercase
class MainClass {
// the method takes one parameter of type integer, who we will call inputInteger
// (method-scoped only)
static void hey(int inputInteger) {
System.out.println("hey " + inputInteger);
}
}
class A {
// instance variable
int myInt = 2;
}
class B {
// instance variable
int myInt = 8;
}
class Declare {
public static void main() {
// Instantiate instances of A and B classes
A aObject = new A();
B bObject = new B();
// call the static method
MainClass.hey(aObject.myInt);
MainClass.hey(bObject.myInt);
}
}
//output
hey 2
hey 8
This code first defines the class MainClass, which contains your method hey. I made the method static in order to be able to just call it as MainClass.hey(). If it was not static, you would need to instantiate a MainClass object in the Declare class and then call the method on that object. For example:
...
MainClass mainClassObject = new MainClass();
mainClassObject.hey(aObject.myInt);
...
I am getting a bit confused regarding few points regarding Java memory management.
Understood what is the difference between Stacks and Heap and I went to see a proper example on what is those memories when we execute some code.
I took for example this few lines
public static void main(String[] args)
{
int a = 5;
calculate(a);
System.out.println(a); //will print 5 not 50
}
private static void calculatee(int a)
{
a = a * 10;
}
I understood what is happening in the stack and in the heap. The variable is not getting returned and there is no reference to the Heap in this case.
while in this example:
public static void maina(String[] args)
{
Customer customer = new Customer("John");
setAName(customer);
System.out.println(customer.getName()); // this will return Philip
}
private static void setAName(Customer c)
{
c.setName("Philip");
}
I can see the state of the object changed this time!
Stacks are not shared thought threads, but heap is shared! Which make sense to me that the object customer has changed its value from Jhon to Philip when I am printing it!
Great! all make sense!
However, I was expecting that if I will do this
public static void main(String[] args)
{
Integer i = new Integer(5);
calculate(i);
System.out.println(i); // printing 5 and not 50
}
private static void calculate(Integer i)
{
i = i * 10;
}
I would get 50 and not 5!
In this case Integer is an object and I am assuming it is created in the heap!
Funny thing is that if I will wrap the Integer inside Customer I will get 50 instead of 5.
Why is this happening? Isn't the Integer type getting created in the Heap?
This is a problem of references and not of heaps and stacks.
When calling the method calculate, you pass a reference (in your case, i from main).
The trick is, that Java will create a new reference inside of calculate. So i inside of calculate and i inside of main might initially "point" to the same object, but they are not the "same".
So, if you change i inside of calculate to the object resulting from your multiplication, you don't automatically change the reference of the i inside of main.
With Customer, it's different. You never change where c in setAName points to. You change one reference inside of the object, but both customer inside of main and c in setAName still point to that one object!
Here two shitty Paint drawings to explain what I mean (numbers prefixed with 0x are references):
For the Integer example:
For the Customer example:
Don't hesitate to come back with any questions.
I hope this helps.
I have very silly doubt that why we use return statement in method . Without using return statement in method we can also get required value
as example
package testing;
public class ReturnMethod {
static int a = 10;
static int b = 5;
static int c;
static int d;
public static void add() {
c = a + b;
}
public static int returnAddValue() {
d = a + b;
return d;
}
public static void main(String[] args) {
add();
System.out.println("c: " + c);
int value = returnAddValue();
System.out.println("value: " + value);
}
}
In above example in both the cases i am getting output
c: 15
value: 15
So i am having doubt when to use return statement and why is neccessary
With return statement, the return value is not necessary to be saved in any global, external or member variable.
However, without return statement you have to prepare kind of outer variable value to track that.
If you assign the result of a method to a static variable (and, indeed, pass in the "parameters" of the method by setting static variables), you have problems when that method is called by two threads concurrently, since the variables are shared for all invocations of the method:
Thread t1 = new Thread(() -> {a = 1; b = 2; add(); }); t1.start();
Thread t2 = new Thread(() -> {a = 3; b = 4; add(); }); t2.start();
t1.join(); t2.join();
You don't know which of these threads run first, or even if they run at the same time; so you don't know what the value of a or b is when you call add(), and nor do you know whether the value in c afterwards is the result of the invocation in the first or second thread (or a mixture of the two).
The value stored in c afterwards could be any of 3, 5 or 7 (or any other value, if there is another thread which is also invoking add() concurrently outside this code.
This problem of thread interference just completely goes away if you keep values localized to the stack, by passing a and b as method parameters, and receiving the result as a return value.
Even if your code is single-threaded, it's simply ugly to have to write:
a = 1;
b = 2;
add();
int result = c;
rather than
int result = add(1, 2);
You should use a return statement, when you need the method to return a value.
In your case, both methods work.
But you can, and should use returning methods, when you don't want a field of your class to be changed by another class.
For example, you want money to be only seen, and not changed, when you are making a bank-account related software. So, you make money private, and make a method which returns the money. In this way, other classes can only see money, but not change it.
First, your functions are different, as you see
public static **void** add()
public static **int** returnAddValue()
First one does not return anything, because it has void as return type and the second one has int as return type.
First one works, because c is a global variable.
You typically would use return when you don't store the result in a (static) variable of your class.
public class ReturnMethod {
static int a = 10;
static int b = 5;
public static void add() {
int c = a + b;
}
public static int returnAddValue() {
int d = a + b;
return d;
}
public static void main(String[] args) {
add();
//not possible to access c here
//System.out.println("c: " + c);
int value = returnAddValue();
System.out.println("value: " + value);
}
}
In that modified example, there would be no way for you to access the result of the add() method.
You should probably read about Scopes in Java.
You have a class variable c & d. These variables are associated with the class and stored in heap. If you assign a value back to it and you can access it without a explicit return statement. But if you have declared d inside the method then return statement is required to give the value back to the caller.
The reason that you are able to access the value of class variable c is that it has been initialized as static. Had this not been the case the information in the c variable would be lost as soon as the add method ends. The reason methods have return value is that they user can get the updated value , if there are any manipulation in the object data. In this case there is a very small, what if there is series of manipulation with the data. In that case the final value has to be returned to the calling object which without return statement is not possible.
Its totally depends upon our requirement whether to return a value from our method or update instance variable. Some time we just want to process a value and get back the result in and result will be used in different manner, in this case we need to return value from method.
For example
java.lang.Math.sqrt(double a) method return a value and we use returned value as per our need OR requirement. Can you think if this method does not returned any value then what it should update, I think this method useless if it does not returned any value.
The variable C in your code snippet is accessed in the class throughout, and will stay until the object of the class exists. So you can print the value of Variable C outside the method.
However, if you had declared a local variable in the method add(), then print statement System.out.println("c: " + c); will print the default value for variable c. That is zero in this case.
This is the code I have, please look at it before you read the question
package ict201jansem2012;
public class Qn3b {
public static void main(String[] args) {
int a = 1;
int b[] = {4,5};
String s = "Good luck!";
method1(b[1]);
System.out.println("(1) b[0] = "+b[0]+"; b[1] = "+b[1]);
method2(b);
System.out.println("(2) b[0] = "+b[0]+"; b[1] = "+b[1]);
method3(a);
System.out.println("(3) a = " + a );
method4(s);
System.out.println("(4) s = " + s );
}
public static void method1(int b) {
b = 7;
}
public static void method2(int[] b) {
b[0] = 3;
}
public static void method3(int a) {
a = 3;
}
public static void method4(String s) {
s = "UniSIM";
}
}
Output:
(1) b[0] = 4; b[1] = 5
(2) b[0] = 3; b[1] = 5
(3) a = 1
(4) s = Good luck!
So my question is ,
This is intresting for me to know as learning programmer. The int b array 0 index value has changed, but not the other variables like the String s and int a. Before i ran this program I roughly thought in my mind that the variable will change their values as the methods are called ,this is because the method is being called and the main method vairable such as a,s and b array are passed and then they are being modified.
So in a nutshell why is that the b array 0 index is changed while the other variables are not changed?
Because you said you were a beginner programmer, I'll do a little writeup to explain (or try to explain) exactly what is happening.
It is because you are passing an argument to your method1 - method4 methods
These arguments, themselves, are references to other objects.
When you use the assignment operator, an equals sign, you overwrite that reference for the value in the current scope - where variables can be 'seen'.
In your code:
In the case of method1 you are creating a new reference, the variable can only be seen within that scope. That is, when you then go b = << expr >> you are assigning the variable b within method1's scope the value, not b in the main scope. The same is true of your method3 and method4 methods, you are assigning a new value to the respective variables within that scope, as you are creating new references rather than altering the original objects.
But, method2's code behaves differently, this is because you are mutating the object inside that code. You are altering the object directly - rather than creating a new reference inside that scope.
Consider the code below
int[] array = new int[] {1, 2};
public void test()
{
method1(array);
System.out.println(array[0] + ", " + array[1]);
method2(array);
System.out.println(array[0] + ", " + array[1]);
}
// because we are working with objects, the identifier, can be different to the arrays identifier
// in this case, I've chosen to use 'a' instead of 'array' to show this
public void method1(int[] a)
{
// this mutates the array object
a[0] = 2;
}
public void method2(int[] array)
{
// this overwrites the method2.array but not the global array
array = new int[] { 1, 2, 3 };
}
We create a new array, with identifer 'array' in the global scope. (In Java, this would be the classes own scope)
In method1, we take an argument, which is the same object being passed as the global array object, so when we mutate it, both objects will change. So, the first print statement will be
"2, 2"
Where array[0] has been altered
N.B. Because we dealing with objects, the 'name' of the variable doesn't matter - it will still be a reference to the same object
However, in method2, we take an argument, like in method1, but this time we use the assignment operator to assign that variable to a new value in the scope that it's currently in - so the global array isn't altered, so we still print out
"2, 2"
For a beginner programmer, I would personally write a few test programs where you get to fully understand how variables and scopes work.
But just know, everytime you create a new block of code, a new scope is created, local variables to that scope can only be seen in that scope and ones below it.
For instance:
public void test()
{
int a = 5;
method1(a);
System.out.println(a); // prints 5
}
public void method1(int a)
{
// a is only viewable in the method1 scope
// and any scopes below it, that is, any scopes created within method1
// and since we use an assignment operator, we assign method1.a a value, not global 'a' a value
a = 123;
if (true)
{
// this is a new scope, variables created in this block cannot be seen outside it
// but can see variables from above it
System.out.println(a); // prints 123
}
}
Here, we create a new scope inside method1 inside the if statement, which can see a above it. However, because method1 and test's scopes are both independent, when we use the assignment operator, we assign the value of a to the local scope. So a is different in both test and method1
I hope you understand better now.
I'm not very good at conveying things, but if it even helped a little bit in understanding scopes I did well, plus, it was fun.
Java is pass-by-value, but most values (everything that's not a primitive, in this case int[] and String) are references, which means they act like pass-by-reference.
Here's a nice writeup: http://javadude.com/articles/passbyvalue.htm
arrays are special type of objects and memory will be allocated on HEAP. When you pass array as parameter to method it will be pass as reference-value (copy of the reference).
This means initial b and this new reference points to same object. Unless new reference points to another object, changes on this reference will reflect on same object. That is why you are seeing value reflected on original array.
All of the values were passed TO the inner methods, but the inner methods returned nothing. However, method2 modified the internal value of the array that was passed to it, so that inner value appeared modified on return.
Note that method2 is the only one where you did not assign to the variable (parameter) itself, but rather assigned to an element of the object whose reference was passed in.
There is a critical difference between modifying the reference (pointer) to an object, and modifying the object itself.
I'm doing a task for a course in Java programming and I'm not sure how the following thing is working? The method below takes the value from an array and a integer. The integer should be added to the array and then be used outside the method in other methods and so on, but how could this work when the method has no return for the new content of the array? There is a void in the method? Have I missed something? Preciate some help? Is there something about pointers?
public static void makeTransaction(int[] trans, int amount);
Arrays in Java are objects. If you modify the trans array inside the method, the changes will be reflected outside of it1. Eg:
public static void modify(int[] arr)
{
arr[0] = 10;
}
public static void main(...)
{
int x = {1, 2, 3};
System.out.println(x[0]); // prints 1
modify(x);
System.out.println(x[0]); // now it prints 10
}
Note that native arrays can't be dynamically resized in Java. You will have to use something like ArrayList if you need to do that. Alternatively you can change the return type to int[] and return a new array with the new element "appended" to the old array:
public static int[] makeTransaction(int[] trans, int amount)
{
int[] new_trans = Arrays.copyOf(trans, trans.length + 1);
new_trans[trans.length] = amount;
return new_trans;
}
1 It is also worth noting that as objects, array references are passed by value, so the following code has no effect whatsoever outside of the method:
public void no_change(int[] arr)
{
arr = new int[arr.length];
}
You can't add anything to an array. Java arrays have a fixed length. So indeed, what you want to do is impossible. You might make the method return an int[] array, but it would be a whole new array, containing all the elements of the initial one + the amount passed as argument.
If you want to add something to an array-like structure, use an ArrayList<Integer>.
Do you have to keep the method signature as is?
Also, can you be a bit more specific. When you say "the integer should be added to the array", are you referring to the amount argument? If so, then how is that amount added? Do we place it somewhere in the array or is it placed at the end, thus extending the array's length?
As far as pointers go, Java's pointers are implicit, so if you don't have a strong enough knowledge of the language, then it might not be so clear to you. Anyways, I believe that Java methods usually will pass objects by reference, and primitives by value. But, even that isn't entirely true. If you were to assign your object argument to new object, when the method terminates, the variable that you passed to the method is the same after the method executed as it was before. But, if you were to change the argument's member attributes, then when the method terminated those attributes values will be the same as they were inside of the method.
Anyways, back to your question, I believe that will work because an array is an object. So, if you were to do the following:
public static void makeTransaction(int[] trans, int amount)
{
trans[0] = amount;
}
// static int i;
/**
* #param args
*/
public static void main(String[] args)
{
int[] trans = {0,1,3};
makeTransaction(trans, 10);
for(int i = 0; i<trans.length; i++)
{
System.out.println(trans[i]);
}
}
The output of the array will be:
10
1
3
But, watch this. What if I decided to implement makeTransaction like so:
public static void makeTransaction(int[] trans, int amount)
{
trans[0] = amount;
trans = new int[3];
}
What do you think that the output will be? Will it be set to all zero's or will be the same as it was before? The answer is that the output will be the same as it was before. This ties in to what I was saying earlier.
I might've assigned that pointer to a new object in memory, but your copy of the pointer inside of the main method remains the same. It still points to the same place in memory as it did before. When the makeTransaction method terminates, the new int[3] object that I created inside of it is available for garbage collection. The original array remains intact. So, when people say that Java passes objects by reference, it's really more like passing objects' references by value.