i know how it works here
Polymorphism does not include instance fields. Methods yes, fields no. Baap b is a reference of type Baap when accessing fields (b.h). When accessing methods, b morphs into a Beta type (b.getH()).
class Baap
{
public int h = 4;
public int getH()
{
System.out.println("Baap "+h);
return h;
}
}
public class Beta extends Baap
{
public int h = 44;
public int getH()
{
System.out.println("Beta "+h);
return h;
}
public static void main(String[] args)
{
Baap betaInBaap = new Beta();
System.out.println(betaInBaap.h+" "+betaInBaap.getH());
Beta castedBeta = (Beta) betaInBaap;
System.out.println(castedBeta.h+" "+castedBeta.getH());
}
}
What I don't understand is the order of output
As Here o/p must be 4(calling b.h) followed by Beta 44(calling method b.geth()) and the method returns 44 as well so the first line must be 4 Beta 44 44
public int h = 44;
public int getH()
{
System.out.println("Beta "+h); // print line 1
return h;
}
public static void main(String[] args)
{
Baap b = new Beta();
System.out.println(b.h+" "+b.getH()); // print line 2
Beta bb = (Beta) b;
System.out.println(bb.h+" "+bb.getH()); // print line 3
}
In your first print statement in your main method, you want it to print b.h+ " "+ b.getH(). It can't print this, before it knows the value returned by b.getH();
So, it runs b.getH() which prints (seperately) System.out.println("Beta "+h);
before returning a value to the main method. (print line 1)
That explains your first line.
After the value is returned, the main method can now print print line 2, because it now knows what b.getH() has as result:
System.out.println(b.h+" "+b.getH());
This explains your second line in the output.
The same order is executed when running print line 3.
Related
So this is basically my code
abstract class B
{
int x = 3;
B()
{
x+=2;
System.out.print("-x" + x + "\n"); // print -x5
x++; // 5 then 6
}
abstract int calculate();
abstract int calculate(int i);
}
class A extends B
{
int x = 2;
A()
{
System.out.print("-x" + calculate(2)+"\n");
}
#Override
int calculate()
{
return x;
}
#Override
int calculate(int i)
{
return(calculate()+i);
}
}
public class Test2 extends A
{
Test2()
{
x+=3;
}
#Override
int calculate()
{
return x + 6;
}
public static void main(String[] args) {
Test2 sub = new Test2();
System.out.print("-x" + sub.calculate()+"\n");
}
}
My problem here is after digging up about variable hiding I learned that if a instance variable is of the same name in both parent class and child class then the childclass hides the instance variable of the parent class. Also I have the prior knowledge that variables cannot be overridden when child class inherits parent class.
So now coming to the problem, in the code when A extends to B, why does the print statement inside constructor A() gives a value -x10? shouldn't it be -x8?? I dont understand how the variable is being changed here. I am new to java so any kind of knowledge will be greatly appreciated. :)
Ok so I have done some debugging and found that the calculate(void) method in class A returns 8. But how is that possible shouldn't it return 6? Please help!
The reason it prints -x10 is because A::calculate(2) calls the Test2::calculate(), which uses A::x to do the calculation.
The sequence of calls that happens is the following:
Test2() {
A()
B() {
B::x = 3
B::x += 2
System.out.print("-x" + x + "\n"); // print -x5
B::x++ // B::x is now 6
}
A::x = 2
System.out.print("-x" + calculate(2)+"\n")
A::calculate(2) {
return(calculate()+2);
Test2::calculate() {
return A::x + 6; // A::x is 2 here, so returns 8
}
} // returns calculate()+2, so returns 10
}
A::x += 3
}
I hope this is just code to test things out, because you should never allow this to happen in real code. You should never allow a method of a subclass to be called from the constructor of a base class, because the subclass is not initialised at that time. The Java compiler does its best to prevent that, but sometimes it does not detect it.
It is returning 8 because:
The line you called System.out.print("-x" + sub.calculate()+"\n"); in class A calls
#Override
int calculate()
{
return x + 6;
}
in class A still, which is incrementing the instance variable int x = 2 in class A . this variable overwrote the one in class B
Hence 2+6 = 8
This is one of the practice questions of a test:
Write a method which accepts two integer values as input parameters and returns the boolean result true if the sum of the inputs is greater than or equal to 10 (and falseotherwise)
My answer is below but I don't think it looks correct. Can anyone give me a pointer?
public class Bruh{
public static void main (String [] arg){
int a;
int b;
boolean sum = true;
if ( a+b > 10)
System.out.println ("yo");
else{
sum = false;
}
}
}
You only wrote some code in the main method but you did not create one.
In order to do that you need to actually create a method in your Bruh class like:
public static boolean isSumGreaterThan9(int a, int b){
return (a + b) > 9;
}
Than call it from the main method:
public static void main (String [] arg){
int a = 4; // or whatever
int b = 7; // or whatever
System.out.println(isSumGreaterThan9(a, b));
}
You need to put your logic into a method and change your comparison to >= as per the requirement:
public static boolean isSumGreaterThanOrEqualToTen(int a, int b) {
return (a + b) >= 10;
}
I'm new to Java and wanted some clarification, I understand that I'm declaring an int variable of x inside the method's parameters but why is it that 'result' can not be resolved to a variable.
public class Methods{
public static void main(String[] args) {
//f(x) = x * x
square(5);
System.out.println(result);
}
//This method
static int square(int x) {
int result = x * x;
}
You can, but note that local variable are only defined in their respected functions. So even though result is defined in square(), it's not defined in main(). So what you want to do is return a value for your square function and store that in a variable inside main() like so:
public static void main(String[] args) {
int myResult = square(5);
System.out.println(myResult);
}
//This method
static int square(int x) {
int result = x * x; // Note we could just say: return x * x;
return result;
}
Example Here
Since you are beginner, I will explain it bit thoroughly
Rule 1:Local variables are declared in methods, constructors, or blocks.
Rule 2:Local variables are created when the method, constructor or block is entered and the variable will be destroyed once it exits the method, constructor or block.
Rule 3:There is no default value for local variables so local variables should be declared and an initial value should be assigned before the first use.
public class Methods{
public static void main(String[] args) {
//f(x) = x * x
square(5);
System.out.println(result); //result! who are you?
//Main will not recognize him because of rule 3.
}
static int square(int x) {
int result = x * x; //you did it as said in rule 1
}//variable result is destroyed because of rule 2.
Please go thorough comments in code.
Well solution for your code is:
public class Methods{
public static void main(String[] args) {
//f(x) = x * x
int result=square(5);
System.out.println(result); //result! who are you?
//Main will not recognize him because of rule 3.
}
static int square(int x) {
int result1 = x * x; //you did it as said in rule 1
return result1;
}
I'm in a beginning programming class, and a lot of this had made sense to me up until this point, where we've started working with methods and I'm not entirely sure I understand the "static," "void," and "return" statements.
For this assignment in particular, I thought I had it all figured out, but it says it "can not find symbol histogram" on the line in the main method, although I'm clearly returning it from another method. Anyone able to help me out?
Assignment: "You see that you may need histograms often in writing your programs so you decide for this program to use your program 310a2 Histograms. You may add to this program or use it as a class. You will also write a class (or method) that will generate random number in various ranges. You may want to have the asterisks represent different values (1, 100, or 1000 units). You may also wish to use a character other than the asterisk such as the $ to represent the units of your graph. Run the program sufficient number of times to illustrate the programs various abilities.
Statements Required: output, loop control, decision making, class (optional), methods.
Sample Output:
Sales for October
Day Daily Sales Graph
2 37081 *************************************
3 28355 ****************************
4 39158 ***************************************
5 24904 ************************
6 28879 ****************************
7 13348 *************
"
Here's what I have:
import java.util.Random;
public class prog310t
{
public static int randInt(int randomNum) //determines the random value for the day
{
Random rand = new Random();
randomNum = rand.nextInt((40000 - 1000) + 1) + 10000;
return randomNum;
}
public String histogram (int randomNum) //creates the histogram string
{
String histogram = "";
int roundedRandom = (randomNum/1000);
int ceiling = roundedRandom;
for (int k = 1; k < ceiling; k++)
{
histogram = histogram + "*";
}
return histogram;
}
public void main(String[] Args)
{
System.out.println("Sales for October\n");
System.out.println("Day Daily Sales Graph");
for (int k = 2; k < 31; k++)
{
if (k == 8 || k == 15 || k == 22 || k == 29)
{
k++;
}
System.out.print(k + " ");
int randomNum = 0;
randInt(randomNum);
System.out.print(randomNum + " ");
histogram (randomNum);
System.out.print(histogram + "\n");
}
}
}
Edit: Thanks to you guys, now I've figured out what static means. Now I have a new problem; the program runs, but histogram is returning as empty. Can someone help me understand why? New Code:
import java.util.Random;
public class prog310t
{
public static int randInt(int randomNum) //determines the random value for the day
{
Random rand = new Random();
randomNum = rand.nextInt((40000 - 1000) + 1) + 10000;
return randomNum;
}
public static String histogram (int marketValue) //creates the histogram string
{
String histogram = "";
int roundedRandom = (marketValue/1000);
int ceiling = roundedRandom;
for (int k = 1; k < ceiling; k++)
{
histogram = histogram + "*";
}
return histogram;
}
public static void main(String[] Args)
{
System.out.println("Sales for October\n");
System.out.println("Day Daily Sales Graph");
for (int k = 2; k < 31; k++)
{
if (k == 8 || k == 15 || k == 22 || k == 29)
{
k++;
}
System.out.print(k + " ");
int randomNum = 0;
int marketValue = randInt(randomNum);
System.out.print(marketValue + " ");
String newHistogram = histogram (randomNum);
System.out.print(newHistogram + "\n");
}
}
}
You're correct that your issues are rooted in not understanding static. There are many resources on this, but suffice to say here that something static belongs to a Class whereas something that isn't static belogns to a specific instance. That means that
public class A{
public static int b;
public int x;
public int doStuff(){
return x;
}
public static void main(String[] args){
System.out.println(b); //Valid. Who's b? A (the class we are in)'s b.
System.out.println(x); //Error. Who's x? no instance provided, so we don't know.
doStuff(); //Error. Who are we calling doStuff() on? Which instance?
A a = new A();
System.out.println(a.x); //Valid. Who's x? a (an instance of A)'s x.
}
}
So related to that your method histogram isn't static, so you need an instance to call it. You shouldn't need an instance though; just make the method static:
Change public String histogram(int randomNum) to public static String histogram(int randomNum).
With that done, the line histogram(randomNum); becomes valid. However, you'll still get an error on System.out.print(histogram + "\n");, because histogram as defined here is a function, not a variable. This is related to the return statement. When something says return x (for any value of x), it is saying to terminate the current method call and yield the value x to whoever called the method.
For example, consider the expression 2 + 3. If you were to say int x = 2 + 3, you would expect x to have value 5 afterwards. Now consider a method:
public static int plus(int a, int b){
return a + b;
}
And the statement: int x = plus(2, 3);. Same here, we would expect x to have value 5 afterwards. The computation is done, and whoever is waiting on that value (of type int) receives and uses the value however a single value of that type would be used in place of it. For example:
int x = plus(plus(1,2),plus(3,plus(4,1)); -> x has value 11.
Back to your example: you need to assign a variable to the String value returned from histogram(randomNum);, as such:
Change histogram(randomNum) to String s = histogram(randomNum).
This will make it all compile, but you'll hit one final roadblock: The thing won't run! This is because a runnable main method needs to be static. So change your main method to have the signature:
public static void main(String[] args){...}
Then hit the green button!
For starters your main method should be static:
public static void main(String[] Args)
Instance methods can not be called without an instance of the class they belong to where static methods can be called without an instance. So if you want to call your other methods inside the main method they must also be static unless you create an object of type prog310t then use the object to call the methods example:
public static void main(String[] Args)
{
prog310t test = new prog310t();
test.histogram(1);
}
But in your case you probably want to do:
public static String histogram (int randomNum)
public static void main(String[] Args)
{
histogram(1);
}
Also you are not catching the return of histogram() method in your main method you should do like this:
System.out.print(histogram(randomNum) + "\n");
Or
String test = histogram(randomNum);
System.out.print(test + "\n");
Static methods are part of a class and can be called without an instance but instance methods can only be called from an instance example:
public class Test
{
public static void main(String[] args)
{
getNothingStatic();// this is ok
getNothing(); // THIS IS NOT OK IT WON'T WORK NEEDS AN INSTANCE
Test test = new Test();
test.getNothing(); // this is ok
getString(); // this is ok but you are not capturing the return value
String myString = getString(); // now the return string is stored in myString for later use
}
public void getNothing()
{
}
public static void getNothingStatic()
{
}
public static String getString()
{
return "hello";
}
}
Void means the method is not returning anything it is just doing some processing. You can return primitive or Object types in place of void but in your method you must specify a return if you don't use void.
Before calling histogrom (randomNum) you need to either make histogram static or declare the object that has histogram as a method
e.g
prog310t myClass = new prog310t();
myClass.histogram()
I am hoping that someone can clarify what is happening here for me. I dug around in the integer class for a bit but because integer is overriding the + operator I could not figure out what was going wrong. My problem is with this line:
Integer i = 0;
i = i + 1; // ← I think that this is somehow creating a new object!
Here is my reasoning:
I know that java is pass by value (or pass by value of reference), so I think that in the following example the integer object should be incremented each time.
public class PassByReference {
public static Integer inc(Integer i) {
i = i+1; // I think that this must be **sneakally** creating a new integer...
System.out.println("Inc: "+i);
return i;
}
public static void main(String[] args) {
Integer integer = new Integer(0);
for (int i =0; i<10; i++){
inc(integer);
System.out.println("main: "+integer);
}
}
}
This is my expected output:
Inc: 1
main: 1
Inc: 2
main: 2
Inc: 3
main: 3
Inc: 4
main: 4
Inc: 5
main: 5
Inc: 6
main: 6
...
This is the actual output.
Inc: 1
main: 0
Inc: 1
main: 0
Inc: 1
main: 0
...
Why is it behaving like this?
There are two problems:
Integer is pass by value, not by reference. Changing the reference inside a method won't be reflected into the passed-in reference in the calling method.
Integer is immutable. There's no such method like Integer#set(i). You could otherwise just make use of it.
To get it to work, you need to reassign the return value of the inc() method.
integer = inc(integer);
To learn a bit more about passing by value, here's another example:
public static void main(String... args) {
String[] strings = new String[] { "foo", "bar" };
changeReference(strings);
System.out.println(Arrays.toString(strings)); // still [foo, bar]
changeValue(strings);
System.out.println(Arrays.toString(strings)); // [foo, foo]
}
public static void changeReference(String[] strings) {
strings = new String[] { "foo", "foo" };
}
public static void changeValue(String[] strings) {
strings[1] = "foo";
}
The Integer is immutable. You can wrap int in your custom wrapper class.
class WrapInt{
int value;
}
WrapInt theInt = new WrapInt();
inc(theInt);
System.out.println("main: "+theInt.value);
Good answers above explaining the actual question from the OP.
If anyone needs to pass around a number that needs to be globally updated, use the AtomicInteger() instead of creating the various wrapper classes suggested or relying on 3rd party libs.
The AtomicInteger() is of course mostly used for thread safe access but if the performance hit is no issue, why not use this built-in class. The added bonus is of course the obvious thread safety.
import java.util.concurrent.atomic.AtomicInteger
There are 2 ways to pass by reference
Use org.apache.commons.lang.mutable.MutableInt from Apache Commons library.
Create custom class as shown below
Here's a sample code to do it:
public class Test {
public static void main(String args[]) {
Integer a = new Integer(1);
Integer b = a;
Test.modify(a);
System.out.println(a);
System.out.println(b);
IntegerObj ao = new IntegerObj(1);
IntegerObj bo = ao;
Test.modify(ao);
System.out.println(ao.value);
System.out.println(bo.value);
}
static void modify(Integer x) {
x=7;
}
static void modify(IntegerObj x) {
x.value=7;
}
}
class IntegerObj {
int value;
IntegerObj(int val) {
this.value = val;
}
}
Output:
1
1
7
7
What you are seeing here is not an overloaded + oparator, but autoboxing behaviour. The Integer class is immutable and your code:
Integer i = 0;
i = i + 1;
is seen by the compiler (after the autoboxing) as:
Integer i = Integer.valueOf(0);
i = Integer.valueOf(i.intValue() + 1);
so you are correct in your conclusion that the Integer instance is changed, but not sneakily - it is consistent with the Java language definition :-)
You are correct here:
Integer i = 0;
i = i + 1; // <- I think that this is somehow creating a new object!
First: Integer is immutable.
Second: the Integer class is not overriding the + operator, there is autounboxing and autoboxing involved at that line (In older versions of Java you would get an error on the above line).
When you write i + 1 the compiler first converts the Integer to an (primitive) int for performing the addition: autounboxing. Next, doing i = <some int> the compiler converts from int to an (new) Integer: autoboxing.
So + is actually being applied to primitive ints.
I think it is the autoboxing that is throwing you off.
This part of your code:
public static Integer inc(Integer i) {
i = i+1; // I think that this must be **sneakally** creating a new integer...
System.out.println("Inc: "+i);
return i;
}
Really boils down to code that looks like:
public static Integer inc(Integer i) {
i = new Integer(i) + new Integer(1);
System.out.println("Inc: "+i);
return i;
}
Which of course.. will not changes the reference passed in.
You could fix it with something like this
public static void main(String[] args) {
Integer integer = new Integer(0);
for (int i =0; i<10; i++){
integer = inc(integer);
System.out.println("main: "+integer);
}
}
If you change your inc() function to this
public static Integer inc(Integer i) {
Integer iParam = i;
i = i+1; // I think that this must be **sneakally** creating a new integer...
System.out.println(i == iParam);
return i;
}
then you will see that it always prints "false".
That means that the addition creates a new instance of Integer and stores it in the local variable i ("local", because i is actually a copy of the reference that was passed), leaving the variable of the calling method untouched.
Integer is an immutable class, meaning that you cannot change it's value but must obtain a new instance. In this case you don't have to do it manually like this:
i = new Integer(i+1); //actually, you would use Integer.valueOf(i.intValue()+1);
instead, it is done by autoboxing.
1 ) Only the copy of reference is sent as a value to the formal parameter. When the formal parameter variable is assigned other value ,the formal parameter's reference changes but the actual parameter's reference remain the same incase of this integer object.
public class UnderstandingObjects {
public static void main(String[] args) {
Integer actualParam = new Integer(10);
changeValue(actualParam);
System.out.println("Output " + actualParam); // o/p =10
IntObj obj = new IntObj();
obj.setVal(20);
changeValue(obj);
System.out.println(obj.a); // o/p =200
}
private static void changeValue(Integer formalParam) {
formalParam = 100;
// Only the copy of reference is set to the formal parameter
// this is something like => Integer formalParam =new Integer(100);
// Here we are changing the reference of formalParam itself not just the
// reference value
}
private static void changeValue(IntObj obj) {
obj.setVal(200);
/*
* obj = new IntObj(); obj.setVal(200);
*/
// Here we are not changing the reference of obj. we are just changing the
// reference obj's value
// we are not doing obj = new IntObj() ; obj.setValue(200); which has happend
// with the Integer
}
}
class IntObj {
Integer a;
public void setVal(int a) {
this.a = a;
}
}
We can do this using Apache Commons Mutable Int
public static Integer inc(MutableInt i) {
i.increment();
System.out.println("Inc: "+i.getValue());
return i;
}
public static void main(String[] args) {
MutableInt integer = new MutableInt(0);
for (int i =0; i<10; i++){
inc(integer);
System.out.println("main: "+integer.getValue());
}
}
This produces output:
Inc: 1
main: 1
Inc: 2
main: 2
Inc: 3
main: 3
Inc: 4
main: 4
Inc: 5
main: 5
Inc: 6
main: 6
Inc: 7
main: 7
Inc: 8
main: 8
Inc: 9
main: 9
Inc: 10
main: 10