Why is the toString() method being called when I print an object? - java

I can't seem to understand why when I use println method on the quarter object, it returns the value of the toString method. I never called the toString method why am I getting the return value?
public class Main {
public static void main(String[] args) {
Quarter q = new Quarter();
Nickel n = new Nickel();
System.out.println(q);
System.out.println(n);
}
}
public abstract class Money {
private int value;
public Money(int v) {
value=v;
}
public abstract int getValue();
protected int myValue() {
return value;
}
public abstract String toString();
}
public abstract class Coin extends Money {
public Coin(int value) {
super(value);
System.out.println("I am a coin, my value is " + getValue());
}
}
public class Quarter extends Coin {
public Quarter () {
super(25);
}
public int getValue() {
return myValue();
}
public String toString() {
return "A Quarter is "+getValue();
}
}
public class Nickel extends Coin {
public Nickel () {
super(5);
}
public int getValue() {
return myValue();
}
public String toString() {
return "A "+this.getClass().getName()+ " is "+getValue();
}
}

On Refering to java docs what i undestand is that,
When you call PrintStream class print(obj) / println(obj) method then internally it called write method with arguement as String.valueOf(obj) shown below :
public void print(Object obj) {
write(String.valueOf(obj));
}
Now String.valueOf(obj) does the task of calling to String method as shown below :
/**
* Returns the string representation of the <code>Object</code> argument.
*
* #param obj an <code>Object</code>.
* #return if the argument is <code>null</code>, then a string equal to
* <code>"null"</code>; otherwise, the value of
* <code>obj.toString()</code> is returned.
* #see java.lang.Object#toString()
*/
public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
}

Because PrintStream.println has an overload that takes an Object, and then calls its toString method.

Because this is how this function operates: it formats the primitive types for you, but when you pass it an object, it will call .toString() on it.
If you don't override it, it will output the default .toString() implementation (Class#somenumber) which is not really useful...

When you are directly trying to print an object, by default it will call the toString method you need to override that toString method to print the attributes of your class.

Because all classes in java are subclasses of java.lang.Object , so whenever you try to call System.out.println() method to print object, it calls the toString() method of Object class.
For Security Reasons the method prints a hashcode, not the values of that object,
but you have inherited that method in your class and extended its definition to print object values
public String toString() {
return "A Quarter is "+getValue();
}
So you get a return value.

Related

How to call a non-void method from a void method?

Is it possible to call an int method which receives an object and returns an int value from a void method by sending a temporary object to it?
When I tried this, I got nothing; the output window appears for a millisecond and vanishes. I used this code:
class test {
int x (test ob) { return 10;}
public static void main (String args[]) { new test().x(new test()) }
}
Yes. If it just expects any object, you can pass new Object() and recieve the int value as a result.
In a word yes. The return type of the calling method has no effect on the return type of the method being called. E.g.:
public class SomeClass() {
public int increment(int i) {
return i + 1;
}
public void printFiveTheHardWay() {
System.out.println(increment(4));
}
}
Yes, you can call any method from Void method irrespective of return type of method , e.g:
Your example from comment should be like below:
class test {
int x(test ob) {
return 10;
}
public static void main(String args[]) {
System.out.println(new test().x(new test()));
}
}
More generic code for your better understanding here:
public class Foo {
private Integer value;
public Integer getValue() {
return value;
}
public void setValue(Integer value) {
this.value = value;
}
}
public class TestVoidMethodCall {
public void voidMethod() {
Foo f = new Foo();
f.setValue(100);
System.out.println(integerReturnMethod(f));
}
private Integer integerReturnMethod(Foo f) {
return f.getValue();
}
}
So, Calling method return type has no relation with called method return type.

how to print object value with String method

I have an abstract class like this
public abstract class Temperature
{
private float value;
public Temperature(float v)
{
value = v;
}
public final float getValue()
{
return value;
}
public abstract Temperature toCelsius();
public abstract Temperature toFahrenheit();
public abstract Temperature toKelvin();
}
then I have classes that extend this Temperature class, example:
public class Celsius extends Temperature
{
public Celsius(float t)
{
super(t);
}
public String toString()
{
return "";
}
#Override
public Temperature toCelsius() {
// TODO Auto-generated method stub
return this;
}
public Temperature toKelvin(){
return new Kelvin(this.getValue() + 273);
}
#Override
public Temperature toFahrenheit() {
// TODO Auto-generated method stub
return new Fahrenheit(this.getValue() * 9 / 5 +32);
}
}
main method creates objects of of Celcius
Temperature inputTemp = null, outputTemp = null;
inputTemp = new Celsius(temp_val);
outputTemp = inputTemp.toCelsius();
then prints the object by calling this method
System.out.println("\n The converted temperature is " + outputTemp.toString() +"\n\n");
}
What do i have to put in the toString method in order to print the desired value? this.super.getValue() didnt work and im kinda clueless. Since we are not going to be returning the same object everytime, dont we have to use the superclass?
It will be enough if you use:
public String toString()
{
return Float.toString(this.getValue());
}
this.super is invalid syntax. super is not a field of this. It's a keyword that allows calling the superclass implementation of a method rather than calling the overridden implementation, from the current class. You just need
return Float.toString(this.getValue());
or
return Float.toString(getValue());
or even
return Float.toString(super.getValue());
But using super.getValue() is useless, since the subclass doesn't override the base getValue() method, and you thus don't need to explicitely use the super implementation of the method.

How to read and write to variables of an abstract class

Put simply, I have an abstract class containing several variables and methods. Other classes extend this abstract class, yet when I try to read the private variable in the abstract class by calling getter methods inside the abstract class, it returns null as the value of the variable.
public class JavaApplication {
public static void main(String[] args) {
NewClass1 n1 = new NewClass1();
NewClass2 n2 = new NewClass2();
n1.setVar("hello");
n2.print();
}
}
public class NewClass1 {
public String firstWord;
public void setVar(String var) {
firstWord = var;
}
public String getVar () {
return firstWord;
}
}
public class NewClass2 extends NewClass1{
public void print() {
System.out.println(makeCall());
}
public String makeCall() {
return getVar();
}
}
Still prints out null.
Until the String is initialized, it will be null. You should probably have a constructor in the abstract class to set it.
public abstract class Command
{
String firstWord; // = null
protected Command(){}
protected Command( String w )
{
firstWord = w;
}
//...
}
public class Open extends Command
{
public Open()
{
this( "your text" );
}
public Open( String w )
{
super( w );
}
// ...
}
If you need to modify the firstWord string everytime execute() is called then it may not be necessary to use a constructor with a String parameter (I added a default constructor above). However, if you do it this way then either
You must make sure setFirstWord() is called before getFirstWord(), or,
Handle the case when getFirstWord() returns null. This could be by simply using a default value (maybe determined by each subclass) or something else, like failing to execute.
As I do not know all the details of your implementation I cannot tell you further information.

using equals or instanceof in toString

Ok guys I have a program with a 'MartianManager' class: *Note code is not complete still have some missing pieces just supplied entire code for reference of somewhat how it is going to look when complete
import java.util.ArrayList;
public class MartianManager {
private ArrayList<Martian> martians;
private ArrayList<Martian> teleporters;
public void addMartian(Martian m) {
martians.add(m);
if(m instanceof GreenMartian)
teleporters.add(m);
}
//public Object clone() {
public Martian getMartianClosestToID(int id) {
}
public void groupSpeak() {
for(Martian m : martians) {
m.speak();
}
}
public void groupTeleport(String dest) {
}
}
and Martian class:
public abstract class Martian implements Cloneable {
int id;
public Martian(int id) {
this.id = id;
}
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
public int getId() {
return id;
}
public boolean equals(Object o){
return this.getId() == ((Martian)o).getId();
}
public abstract void speak();
public String toString(){
String str = "";
if (this instanceof GreenMartian) {
str = "Green martian" + id;
}
if (this instanceof RedMartian) {
str = "Red martian" + id;
}
return str;
}
}
it is extended with GreenMartian:
public class GreenMartian extends Martian implements ITeleport{
public GreenMartian(int id) {
super(id);
}
public void speak() {
System.out.println(id + "Grobldy Grock");
}
public void teleport(String dest) {
System.out.println(id + "teleporting to " + dest);
}
}
also extended with RedMartian:
public class RedMartian extends Martian {
public RedMartian(int id) {
super(id);
}
public void speak() {
System.out.println(id + "Rubldy Rock");
}
}
I actually have a few questions , but for now my question is in the toString of the Martian class. It should return a string like this: "Red [or Green] martian" +id. I need to determine the type of Martian, I started to use the instanceof but like this "Martian couldn't be resolved to a variable". I'm trying to determine if this would be the best way or if an equals() would be the best way to determine the type?
Also this is my first time using "clone" so not sure how it works exactly, but had a thought is there a way to determine what the "clone" was and determine it that way?
Thanks for any and all help!
No
public String toString(){
String str;
if (Martian instanceof GreenMartian) {
}
in abstract Martian class is a bad idea. You don't want your parent class to depend on its children.
Implement a toString() method in each subclass instead and let polymorphism do its work.
If you absolutely have to
if (Martian instanceof GreenMartian) {
is wrong. You use instanceof as so
instanceOfClass instanceof SomeClass
In this case you get a reference to instanceOfClass with the this keyword, since you are calling the method on an instance
this instanceof GreenMartian
You really should not have a parent class reference any classes that extend it. This is bad practice (and might not actually work, i haven't tested). You should really just override the toString function in each extended class.
public class GreenMartian extends Martian implements ITeleport{
public GreenMartian(int id) {
super(id);
}
public void speak() {
System.out.println(id + "Grobldy Grock");
}
public void teleport(String dest) {
System.out.println(id + "teleporting to " + dest);
}
#Override
public String toString() {
return "GreenMartian: whatever info you'd like to include.";
}
}
Now, if you want to have a similar format for all subclasses, you have two options. One is to call the toString method of the parent class, and prepend that to the subclass's toString method.
#Override
public String toString() {
return super.toString() + "GreenMartin: info.....";
}
//The parent toString could look like this:
#Override
public String toString(){
return "Martian( ... put any parent class info here, id ect)";
}
The final output for a GreenMartian toString call then may look like this:
Martian(id:23) GreenMartian(planet:greenburg)
A Third option would be to have a common string format in the parent class. For example, in the parent class, include this attribute:
protected static final String format = "Class: %s, id: %s, info: %s";
Then, in the subclass toString, you can do this:
#Override
public String toString() {
return String.format(format,this.getClass().toString(),id,myInfo);
}
You can use String name = this.getClass().getSimpleName() to get the name of your class. Then you can check name.substring(0,1).equals("G") or name.substring(0,1).equals("R") to detect Red or Green.
FWIW, it should be if (this instanceof GreenMartian) - but IMHO whenever you are tempted to use such an downcast (upcast??), it is an sign of bad OO design. Rather write a specialized toString()method for your martians. And you should really check for o==null in your equals() method.
Martian is not a variable. Try this instead:
if(this instanceof GreenMartian)

Does the equals method work with objects? If so, how?

I have a program that is zoo and in the zoo there are branched subgroups of animals that are reptiles. When I do an equals method the main program compiles and it runs. I'm confused how does java know to use the equals method if I'm comparing objects and not specifically int or String?
public class Zoo {
public static void main(String[]args) {
Animal a=new Animal("Bob");
Reptile komodo= new Reptile("Snakey");
komodo.bask();
a.size=3;
komodo.size=5;
System.out.println(a);
System.out.println(komodo);
Turtle t= new Turtle("Slowy");
t.hide();
t.size=6;
t.numlegs=4;
System.out.println(t);
System.out.println(t.equals(komodo));
}
}
public class Animal {
public String name;
public boolean equals(Animal other) {
return other.size==this.size;
}
public Animal(String s) {
name=s;
}
public void setName(String n) {
this.name=n;
}
public void eat(String meal) {
System.out.println("chump chump yummy "+meal);
}
public int size;
public String toString() {
return "I am "+name+" and I'm "+size+" cm long";
}
}
public class Reptile extends Animal {
public Reptile(String n) {
super(n);
numlegs=0;
}
public Reptile(String n, int l) {
super(n);
numlegs=l;
}
public void bask() {
System.out.println("basking...");
}
public String toString() {
return super.toString()+numlegs+" legs";
}
public int numlegs;
}
public class Turtle extends Reptile {
public Turtle(String n) {
super (n,4);
shellColor="Brown";
}
public void hide() {
System.out.println("you cant see me");
}
public String toString() {
return super.toString()+" and my shell is"+ shellColor;
}
public String shellColor;
public void bask() {
super.bask();
System.out.println("turtle is basking...");
}
}
You're not overriding the Object#equals method, but overloading it. In your method declaration you use Animal type instead of Object:
public boolean equals(Animal other)
A good overriding of the method would be using the instanceof operator. Showing an example:
#Override
public boolean equals(Object other) {
if(other instanceof Animal) {
Animal otherAnimal = (Animal)other;
//comparison logic...
}
return false;
}
More info on the subject:
Best practices regarding equals: to overload or not to overload?
Overriding Object.equals VS Overloading it
For your question on how java knows how to compare objects,
you need to override the equals method
public boolean equals(Object other){
// return true or false based on your logic
}
While comparing, equals method is used.
You can have a look at this good tutorial which explains the significance of the equals method.
http://www.thejavageek.com/2013/06/26/what-is-the-significance-of-equals-method-in-java/
Also, only overriding equals is not enough if you are using objects into collections those use hashing. You will find a good tutorial at
http://www.thejavageek.com/2013/06/28/significance-of-equals-and-hashcode/
Every class inherits the Object class silently. And the Object class has a equals method. So if any class doesn't override the equals method then it will use the default implementation of Object.equals.
From the doc
The equals method for class Object implements the most discriminating
possible equivalence relation on objects; that is, for any non-null
reference values x and y, this method returns true if and only if x
and y refer to the same object (x == y has the value true).
From the source code of Object.equals
public boolean equals(Object obj) {
return (this == obj);
}
So If any object doesn't have it's own implementation of equals then the equals method will simply check if the object reference is same or not.
So get a desired result from equals you need to implement by your own as alread suggested in other answer

Categories

Resources