Java printing inherited objects with a println method - java

I'm taking those first steps from python to java and here is my first of many Java questions do doubt.
When printing via a shortened print method, I'm running into a problem with the return value from a inherited class. I'm sure it's something simple about Java I don't get yet. I'm also trying to convert any integers the println method receives to a string with .tostring(), but I'm not sure if that is correct.
class Inheritance {
private static void println (Object line){
System.out.println(line.toString());
}
static class A {
public int multiply(int a, int b){
int val = a*b;
return val;
}
}
static class B extends A {
public int multiply(int a, int b) {
int val = a * b * 5;
return val;
}
}
public static void main(String[] args) {
B b_class = new B();
b_class.multiply(3,4);
println(b_class);
println("Hello World");
}
}
The output is as follows:
Inheritance$B#74a14482
Hello World

You can just use the method inside println
public static void main(String[] args) {
B b_class = new B();
println(Integer.ToString(b_class.multiply(3,4)));
println("Hello World");
}

For Java toString method default it will
returns a string consisting of the name of the class of which the object is an instance, the at-sign character `#', and the unsigned hexadecimal representation of the hash code of the object. In other words, this method returns a string equal to the value of:
getClass().getName() + '#' + Integer.toHexString(hashCode())
https://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#toString()
so when you println b_class it will print: Inheritance$B#74a14482.
For your println (Object line) it's receiving Reference type(Object) to println, but as multiply method it's return a primitive type(int), it's not an object, you need to convert it to an Object for println method, as #StanteyS's answer, use Integer.toString can convert int to String.
What's the difference between primitive and reference types?

When you are executing println(b_class); implicitly it calls toString method of same class, which is inherited from Object class.
You need to override toString method to display correct output.
static class B extends A {
int val=0;
public int multiply(int a, int b) {
val = a * b * 5;
return val;
}
public String toString(){
return String.valueOf(val);
}
}
Now, println(b_class); will work as per your expectation.

Related

How to represent a value using object (Not representing the object as a whole)

How can I represent a value via an object(A custom value)
Hello, I would like to ask how to represent a value using object (I am not talking about referring the the object itself, but represent a custom value.)
This is one of the class that I found having a custom value
It is wrapper class. When I try to print a wrapper class object (Integer for example),it prints out the value that I stored in it.
package Testing;
public class test {
static Integer one = 1;
public static void main(String[] args) {
System.out.println(one);
}
}
So, I create an Integer object, and when I print it, it prints the value that I stored in it.
So,
I wanted to understand how it work. Sorry if it is a build in feature (that can't be coded in regular java)
Thank you :)
I will tell you the internal logic about System.out.println().
this is println(Object o) method.
public void println(Object x) {
String s = String.valueOf(x); // In summary, the output string in this line is determined.
synchronized (this) {
print(s);
newLine();
}
}
this is valueOf(Object o) method.
public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString(); // Here you can see that obj's toString() method is called.
}
In summary, when you println() with an object, it prints according to the return value of the toString() method in the object.
Now, let's see your case about Integer class.
private final int value;
public String toString() {
return toString(value);
}
public static String toString(int i) {
if (i == Integer.MIN_VALUE)
return "-2147483648"; // If integer is MinValue, the minimum value is returned as a string.
int size = (i < 0) ? stringSize(-i) + 1 : stringSize(i);
char[] buf = new char[size];
getChars(i, size, buf);
return new String(buf, true); // Creates a char array, assembles numbers, converts them to strings, and returns them.
}

Passing arguments to Method References

Given this method:
private static Integer getVal(Integer a, Integer b){
return a + b;
}
which can be called as a lambda:
a -> getVal(1, 2)
Is there anyway of turning this into a method reference, something like:
Class::getVal
Thanks
Well, if you are passing constants to the method call, you can create another method that calls the original method:
private static Integer getVal (Integer a) {
return getVal(1,2);
}
then you can use method reference for the second method.
i.e. you can change
a -> getVal(1, 2)
to
ClassName::getVal
That said, it doesn't make much sense.
P.S., it's not clear what's the purpose of a in your lambda expression, since you are ignoring it.
In general you can pass a method reference of a given method if it matches the signature of the single method of the required functional interface.
Example:
public static Integer apply (BinaryOperator<Integer> op, Integer a, Integer b)
{
return op.apply(a,b);
}
Now you can call:
apply(ClassName::getVal)
with your original method.
Here is an example.
interface Operator {
int operate(int a, int b);
}
class Calc {
public static int add(int a, int b) {
return a + b;
}
}
class Main {
public static void main(String[] args) {
// using method reference
int result = operate(1, 2, Calc::add);
// using lambda
int result = operate(1, 2, (a, b) -> Calc.add(a, b));
}
static int operate(int a, int b, Operator operator) {
return operator.operate(a, b);
}
}
You need a functional interface to use method reference (In this example Operator). And you also need a method which accepts an instance of the functional interface as its parermater (In this example operate(int a, int b, Operator operator).
UPDATE
If you need an object wrapper, just change the operate method to
static int operate(ObjectWrapper wrapper, Operator operator) {
return operator.operate(wrapper.getA(), wrapper.getB());
}
And then call the operate method:
int result = operate(wrapper, Calc::add);
getVal() will only be usable as a method reference, in places where a functional interface of an applicable type is expected, such as BiFunction or IntBinaryOperator, or a custom functional interface (as in the answer of zhh)
Example:
public static void main(String[] args) {
Integer result1 = calculate(1, 2, Second::getVal);
Integer result2 = calculateAsInt(1, 2, Second::getVal);
}
private static Integer getVal(Integer a, Integer b){
return a + b;
}
private static Integer calculate(Integer a, Integer b, BinaryOperator<Integer> operator) {
return operator.apply(a, b);
}
private static int calculateAsInt(int a, Integer b, IntBinaryOperator operator) {
return operator.applyAsInt(a, b);
}

Java print string and int on same line

I was trying to print a string and int on a same line. But I get an error. I know my way around this error but why does the line System.out.println("This is a string: %i", c2.a);gives error whereas the line System.out.println("This is class method" + c2.a ); gives the correct output. Below is my code.
public class MyClass
{
private int a;
public double b;
public MyClass(int first, double second)
{
this.a = first;
this.b = second;
}
// new method
public static void incrementBoth(MyClass c1) {
c1.a = c1.a + 1;
c1.b = c1.b + 1.0;
}
//pass by valuye therefore no change
public static void incrementA(int a)
{
a = a+1;
}
public static void main(String[] args)
{
MyClass c1 = new MyClass(10, 20.5);
MyClass c2 = new MyClass(10, 31.5);
// different code below
incrementBoth(c2);
incrementA(c1.a);
System.out.println("This is a object passing: %i",c2.a);
System.out.println("This is object passing: " + c2.a );
System.out.println("This is pass by value: %d",c1.a);
}
}
My other question is does the line incrementBoth(c2) changes value of c2 because here whole object is passed to the method rather than passing by value in incrementA(c1.a)
You need to use the printf method and not println.
println is used to print primitive types, Strings and objects as they are. Also, println takes only one argument as input. That is the reason you are getting an error when you pass multiple arguments to it in your code.
printf on the other hand is used to format and then print the formatted string to the Standard output / error. This is what you should use in your code above for formatting the output.
Here's a reference to the tutorials.
Hope this helps!
Try:
int x = 3;
System.out.println("This is my number" + x);
The output should be:
This is my number 3

Java overloading a method with two parameters

This problem is about overloading methods and I think I understand the basic idea but I get some weird error "Overloading.java:14".
Like my problem is that I don't know how to return two parameters of my method. So I thought maybe convert the method with the two int parameters with toString(), then return it. Something gone miserably wrong.
The output have to be following:
a 10
a and b 10, 20
char a
result 97
My problem as it is, is with the "a and b 10, 20", and have not done the "char a" just to make you guys aware. This is not homework.
Here is my code so far contains a main class and a helper class:
OverMain Class :
class OverMain {
public static void main(String args[]) {
Overload overload = new Overload();
int result;
System.out.println("a " + overload.test(10)); //prints a 10
System.out.println("a and b " + overload.test(10, 20)); //the method I have trouble with
result = overload.test('a'); //prints Result 97
System.out.println("Result " + result);
}
}
Overload Class:
//The class which is suppose to overload test methods
class Overload {
public int test(int a) {
return a;
}
public String test(int a, int b) {
String string = "";
string = test(a, b).toString();
return string;
}
}
It's not really clear what you're trying to do, but you don't return parameters, and I don't think overloading is really the problem here. To take overloading out of the situation, you can always change the methods to have different names - get it working that way, and then you can always change the names back later and work out any conflicts.
In your case I think you just need:
public String test(int a, int b) {
return a + ", " + b;
}
In other words, just use string concatenation and the automatic int to String conversion that the compiler will apply in order to use string concatenation.
Note that if your code actually compiled, you'd get a stack overflow because you're calling test(a, b) from test(int a, int b) - it would just call itself forever, until you ran out of stack space.
The problem is in your method test(int, int)
public String test(int a, int b) {
String string = "";
string = test(a, b).toString(); // Danger
return string;
}
You have a never ending recurrence relation
Solution: return a + ", " + b

Static vs Dynamic Binding Logic

I have the following code:
import java.lang.*;
public class Program
{
public static void main(String [] args)
{
B a = new A();
a.p(10);
a.p(10.0);
}
}
class B {
public void p(double i)
{
System.out.println(i*2);
}
}
class A extends B{
public void p(int i)
{
System.out.println(i);
}
}
When I execute this code using B a = new A() , I get 20.0 in both cases which makes sense because overloading is handles during compile time where the compiler looks at the declared type and calls a function appropriately. Since our declared type was class B, class B's method was called in both cases. Now if I do A a = new A(); , I should be getting 10 in both answers but I am not. I am getting 10 for a.p(10) and 20.0 for a.p(10.0). Based on the concept of static binding and whole notion of overloading being done by static binding which looks at the declared type as opposed to the actual type, why is the result coming out this way ? I would very much appreciate your help.
An int can be widened to a double, but not the other way around. This means that 10 can call B.p(double) or A.p(int) but 10.0 is a double and will not be implicitly converted to an int i.e. only B.p(double) will be called.
Its because your method p is not an overridden method, it is just inhereted in your sub-class when you use
Super sup = new Sub();
sup.p(int);
sup.p(double);
In this case as your Super class has a method which takes double as a parameter and aa an int can fit into a double your Super-class's method is invoked the one which accepts double.
Sub sup = new Sub();
sup.p(int);
sup.p(double);
In this case however, as your subclass doesn't have a method which takes a double, for sup.p(double) call it uses the inherited method from super class if you pass double as an argument.
In your case, your are doing overloading which will get binded at compile time(static binding.).And static binding happens with type of reference rather than the type of object the reference is pointing.
In your first case you are using a reference variable of B and assigning an object of A to it.Since your reference is B, the method p(double) from B will get binded statically even if you use an int(since int can be widened to double).
In the second case you are using reference as A itself.In this case, you have two p() methods available.One is p(double) from B and other p(int) from A.So p(10) will call p(int) and p(10.0) will call p(double)
Try this:
class B {
public void p(String i)
{
System.out.println("parent:"+i);
}
}
class A extends B{
public void p(int i)
{
System.out.println(i);
}
}
public class Test1 {
public static void main(String args[]) {
A a = new A(); //arg
a.p(10);
a.p("sample");
}
}
If you change the line marked arg to B a = new A(), you will see compiler trying to call parent p in both the cases.
When you write A a = new A() you create a new object of type A, which will have 2 methods. A.p(int) and B.p(double), and when you call A.p(10.0), it will call B.p(double) due to lack of conversion.
This counter-example might help:
import java.lang.*;
public class X
{
public static void main(String [] args)
{
B c = new A();
c.p(10);
c.p(10.0);
c.p("AAA");
((A)c).p(10);
}
}
class B {
public void p(String s)
{
System.out.println("B: my string is " + s);
}
public void p(double i)
{
System.out.println("B: twice my double is: " + i*2);
}
}
class A extends B{
public void p(int i)
{
System.out.println("A: my number is " + i);
}
}
Output:
C:\temp>java X
B: twice my double is: 20.0
B: twice my double is: 20.0
B: my string is AAA
A: my number is 10
The issue is:
1) You're declaring the type as "B" (not "A")
2) B.p(10) can accept an int as a floating point argument
3) Consequently, that's what you're getting
It's really an issue of what argument types can be implicitly converted, than what methods are overloaded or overridden.
When the object has declared type B, the double version is invoked because it's compatible with an int argument, since in Java int is a subtype of double.
When the object is declared as a A, it has the method p() overloaded with two versions:
p(int arg);
p(double arg);
So, when you pass an int, the first version is picked because it's more accurate, and when you pass double the second one, because it's the most specific signature.
For reference, see the relevant JLS at ยง15.12.2 and this post by Gilad Bracha. BTW, don't try to figure out how the language should behave based on what you think is the most logical way, because every programming language is an engineering effort, and this means that there's a price you pay for whatever you take. The primary source of information for Java are the JLS, and if you read it carefully, you'll (surprisingly?) discover that there are even cases where the line in the source code is ambiguous and cannot be compiled.
To make the effect of widening of int to double more vivid I have created another example which is worth looking. Here, instead of double I have created a class called Parent and instead of int a Child class is created.
Thus,
double ~ Parent int~Child
Obviously child object can be widened to Parent reference.
package test;
public class OOPs {
public static void main(String[] args) {
Child ch = new Child(); // like int 10
Parent pa = new Parent();// like double 10.0
B a = new A(); // case 2 : A a = new A();
a.p(ch);// 10
a.p(pa);// 10.0
}
}
class B {
public void p(Parent i) {
System.out.println("print like 20");
System.out.println(i.getClass().getName());
}
}
class A extends B {
public void p(Child i) {
System.out.println("print like 10");
System.out.println(i.getClass().getName());
}
}
class Parent {
String name;
Parent() {
name = "Parent";
}
public String getName() {
return name;
}
}
class Child extends Parent {
String name;
Child() {
name = "Child";
}
public String getName() {
return name;
}
}
Case 1 - Output (B a = new A();)
print like 20
test.Child
print like 20
test.Parent
Case 2 - Output (A a = new A();)
print like 10
test.Child
print like 20
test.Parent

Categories