Failing to override the default methods - java

I am basically trying to override the default valueOf(Object obj). So why is this still calling the default method and not the overridden one?
class Method {
public static String valueOf(Object obj) {
return "hey!!";
}
public static void main(String[] args)
{
Method m1 = new Method();
System.out.println(m1);
}
}
o/p : Method#1de3f2d
Why am I getting this output? Why is the obj.toString() method being called without me defining it in the overridden method body?

You aren't overriding the toString method, you are attempting to override the valueOf method. Which isn't a method in Object according to the javadoc.
Do this.
#Override
public String toString() {
return "Hey!";
}
instead of your valueOf method.

Object isn't an interface, it's just a class. It has default implementations that will be used, unless you override them. That way you always know that toString will return a string (even if you don't specifically implement it).
Now, the valueOf doesn't get called because you never try to call it?
class Method {
#Override
public static String toString() {
return "hey!!";
}
public static void main(String[] args)
{
Method m1 = new Method();
System.out.println(m1);
}
}
Should print "hey".
EDIT: DISREGARD THIS:I think I see your problem. You are thinking about the Strings toString method, which quite correctly calls the valueOf method to determine what to print. But since Method doesn't extend String
I do not know why you think it will call the value of method. It will instead use Objects toString method. Which uses the class name and hashcode to make the string.

Related

Why is the output in the last row "Wuff Ringding" ? and not "Ringding Ringding"?

Hey guys can you help me wih my code. Its about polymorphism. I have just a question about the last row of the main function. Where is the output there "Wuff Ringding" and not "Ringding Ringding" ?
public class Hund{
public Hund (){
}
public String belllen(){
return "Wuff";
}
public String spielen(Hund h){
return "Wuff" + h.bellen();
}
}
public class Fuchs extends Hund{
public Fuchs (){
}
public String bellen(){
return "Ringding";
}
public String spielen(Fuchs f){
return "Ringding" + f.bellen();
}
}
public class Park {
public static void main (Strin[] args){
Hund bello = new Hund();
Fuchs foxi = new Fuchs();
Hund hybrid = new Fuchs();
System.out.println(hybrid.spielen(foxi));// Output is Wuff Ringding
System.out.println(foxi.spielen(hybrid)); // Output is Wuff Ringding
}}
Java has dynamic method dispatch, but it is only a single dispatch based on the runtime type of the object whose method you are invoking. There is no dynamic dispatch based on the runtime types of the arguments, instead the method (if there are multiple overloaded methods to choose from) is selected at compile-time based on the declared types.
foxi.spielen(hybrid)
foxi is known to be a Fuchs. You have the following overloaded methods
public String spielen(Hund h); (inherited from Hund)
public String spielen(Fuchs f); (declared on Fuchs)
hybrid is declared to be a Hund, so the first method will be called. It does not matter that it is actually a Fuchs at runtime. You'd get to the second method with foxi.spielen((Fuchs)hybrid).
Maybe you intended to override instead of overloading the method? Then it would indeed have printed your expected result. But that did not happen, because to override a method, you have to match the parameter types exactly. If you intend to override a method, you should use the annotation #Override which will alert you have such mistakes.

How toString() is automatically call inside println()

I just started learning Java. What I've learned about constructor is that :
It will automatically run when an object is initialized.
The name of the constructor has be the same as the class name.
Now, below is where I'm starting to get confused.
class Frog{
public String toString() {
return "Hello";
}
}
public class App {
public static void main(String[] args) {
Frog frog1 = new Frog();
System.out.println(frog1);
}
}
My question :
Since public String toString () is not a constructor, then why can it behave like constructor when I run the program. I thought It can only be run when I call it from the App class.
Short answer: public frog1.toString() method call is used inside System.out.println(Object x) call stack.
But how? Let's find it out together :)
Take a look at the PrintStream class (which instance is used as System.out field value by default) source code and its println implementation that accepts Object argument:
public void println(Object x) {
String s = String.valueOf(x);
synchronized (this) {
print(s);
newLine();
}
}
And the String's valueOf method for argument with Object type is:
public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
}
obj is frog1 in your case, its toString() method is called and returns "Hello" String instance for the console output)
The "toString" is not behaving like a constructor; the reason why it is being called is the second line in your main method:
System.out.println(frog1);
This invokes toString on frog1.
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();
}
public String toString(){..} is method of class Object , here overridden specifically for Frog class. This method returns object value representation. It's a method not a constructor. Please remember constructor cannot return value.
Valid constructor would be something like below:
public Frog(){}
The usage of toString is to give some meaningful representation for your class. Something like description about the object or class can go inside toString method.
Whenever the object is used with any String referenced operations like System.out.print or String s="abcd"+frog1;" the content of toString will be returned.
If toString is not overridden it would return the object class and its hash code. Please check here
From your code,
Frog frog1 = new Frog(); => creates object frog1 of type Frog.
System.out.println(frog1); => outputs the String representation
of the object frog1.
Hope it explains.
The toString method overrides Object.toString
public String toString() {
return "Hello";
}
So when call
System.out.println(frog1);
It toString's the object to "hello"
I'm not sure you understand what "behaving like a constructor" means. The Frog constructor (the default one, because you haven't written one) is called when you do new Frog(). The call to .toString() is done automatically inside the call to .println(), which is in the line after the call to the constructor.
You may be getting confused because toString() is the only method you have declared. However, you are missing the knowledge that there is an implicit default constructor automatically in your class. If you were to type it out it would look like this:
public Frog() {
// default constructor does nothing
}
It is that default constructor that is "behaving like a constructor". toString() is just behaving like a method that is being called by another method (the key thing being that println(Object o) is definitely certain that Object has a toString() method because it is part of the class definition).

Can void be used in toString method

I am creating a program but i want to print the string from toString method directly with using System.our.println(ClassName.toString()),
Instead i want just to write the ClassName.toString(); and it print the output.
No, because if you want to call toString method like ClassName.toString(), that means you want to create a static toString() method in your ClassName class, means you are hiding toString instance method of Object class with static method of your class, but Java rule says you cannot hide instance methods with static method.
Java Specification reference: jls 8.4.8.2. Hiding (by Class Methods)
It is a compile-time error if a static method hides an instance method.
toString() method is a method available in Object class.
any class in java if its not extending any parent class then it will have internally Object class as parent.
and toString() method is non final in Object class
so it means we can override the toString() method in any of the subclass.
and return type of overridden methods should be same if its built in type and it should be same or parent if its custom object.
so in our case of toString() its return type is String so nobody can replace String for return type.
hence changing it will give compile time error.
so to achieve your scenario you can do as below in the worst case
#Override
public String toString() {
System.out.println("your string");
return super.toString();
}
and call this method using object of this class, if class name is A
then
A a = new A();
a.toString();
will automatically print the content on console using its body.
I feel like the other answers have covered “don’t do that”, but this is my “try this instead”. But if you are simply trying to accomplish a more terse way of printing the toString() output you could do something like this instead:
public class PrintMe {
private String data = "Just an example";
#Override
public String toString() {
return data;
}
public void print() {
System.out.println(toString());
}
public static void main(String[] args) {
PrintMe p = new PrintMe();
p.print();
}
}
Output: Just an example

Variable Inheritance in Java

I have a Super class and a bunch of subclasses. I want to have one field that has the same name in every single subclass, but I do not want it to be defined in the super class, or at least I do not want to use that value. This is what I have right now
public abstract class Big {
public String tellMe = "BIG";
public Big() {}
public void theMethod() {
System.out.println ("Big was here: " + tellMe() + ", " + tellMe);
}
public String tellMe() {
return tellMe;
}
}
public class Little extends Big{
public String tellMe = "little";
public Little(){}
public String tellMe() {
return "told you";
}
public static void main(String [] args) {
Little l = new Little();
l.theMethod();
}
}
When I run Little, this is the output
Big was here: told you, BIG
I am not sure why 'told you' is printed out while tellMe refers to "BIG". How can both be true?
My problem is that I want the method tellMe() to be in Big, and to have the variable tellMe (that it will actually return) to be defined in all the subclasses. The only way I can get this to work is as I have written, by rewriting the tellMe() method in each subclass. But doesn't that defeat the whole purpose of inheritance??? Please help
EDIT: I do not use the constructor in my subclasses. All I want is a field that can be set in all subclasses and a method in the super that uses those values. I don't understand why this isn't possible because every subclass would have to implement it, so it would make sense... If this simply is not possible, let me know please
Fields are not virtual, unlike methods. For this reason, it is a bad idea to declare fields with the same name as a field in another class in the hierarchy. The field referred to in theMethod is always going to be from Big (i.e. when you declare a field with the same name, it just hides the old field when in the scope of the replacing class, but doesn't replace it).
One solution would be to override a method that gets the field from the current class:
In theMethod replace the tellMe field with getTellMe() and for all classes override getTellMe() to return the correct value (or the field that hides the superclass's field).
You can overwrite the value of Big.tellMe in the constructor of Little.
get rid of:
public String tellMe = "little";
and change the Little constructor to:
public Little(){
tellMe = "little";
}
at that point, you can get rid of Little.tellMe() also.
What you are doing is hiding the super class field, not overriding it, as the Java documentation states.
And it's also stated that it's not a good idea to do it.
So, the dynamic lookup won't work as for a method. If the variable is read from the son class, it will take "its" field value.
On the top class, the other one.
What you can override in Java is the behaviour, so what I would suggest is to
define a method
public String tellMe() {
return "Whatever";
}
that you can override in the subclasses to return whatever string you need.
Instead of defining tellMe inside of Big (since you said you do not want to define/use that value in Big) you can create a function in Big:
public abstract String tellMeString();
And define that in each subclass like so (for Little):
public String tellMeString()
{
return "Little";
}
Then theMethod can execute:
System.out.println ("Big was here: " + tellMe() + ", " + tellMeString());
In this case you wouldn't have to define a variable "tellMe" at all, you just override tellMeString in each subclass to return different Strings.
Fields are not inherited as you are expected. You can access the super class' field (unless it is private) from subclass. But you cannot "override" field. This is why tellMe used by method implemented in super class Big uses variable defined in the same class.
If you want inheritance use methods. For example you can implement method "tellMe()" that returns "BIG" in super class and "little" in subclass:
class Big {
protected String tellMe() {
return "BIG";
}
}
class Little {
#Override
protected String tellMe() {
return "Little";
}
}
Alternatively you can initialize variable tellMe in constructor:
class Big {
private String tellMe;
public Big() {
this("BIG");
}
protected Big(String tellMe) {
this.tellMe = tellMe;
}
protected String tellMe() {
return "BIG";
}
}
class Little {
public Little() {
super("Little");
}
}
Now new Little().tellMe() will return "Little": the variable in super class was initialized when constructing the object; the method defined in super class returned this variable.
Methods can be overridden, fields are visible at the scope where they're called.
static class Big {
String field = "BIG";
String bark() { return "(big bark)"; }
void doIt() {
System.out.format("field(%s) bark(%s)\n", field,bark());
}
void doIt2() {
System.out.format("2:field(%s) bark(%s)\n", field,bark());
}
}
static class Small extends Big {
String field = "small";
String bark() { return "(small bark)"; }
void doIt2() {
System.out.format("2:field(%s) bark(%s)\n", field,bark());
}
}
public static void main(String... args) {
Big b = new Big();
b.doIt();
b.doIt2();
Small s = new Small();
s.doIt();
s.doIt2();
}
Output is:
field(BIG) bark((big bark))
2:field(BIG) bark((big bark))
field(BIG) bark((small bark))
2:field(small) bark((small bark))
since doIt() is defined in the Big class, it will always see the Big version of field. doIt2() is defined in Big, but overridden in Small. The Big.doIt2() sees the Big version of field, the Small.doIt2() version sees the Small version of field.
As others have pointed out, it's a pretty bad idea to do this - a better approach is to set the new value in the subclass constructor, or to use a method which is overridden.

Static And Non Static Method Intercall In Java

I am clearing my concepts on Java. My knowledge about Java is on far begineer side, so kindly bear with me.
I am trying to understand static method and non static method intercalls. I know --
Static method can call another static method simply by its name within same class.
Static method can call another non staic method of same class only after creating instance of the class.
Non static method can call another static method of same class simply by way of classname.methodname - No sure if this correct ?
My Question is about non static method call to another non staic method of same class. In class declaration, when we declare all methods, can we call another non static method of same class from a non static class ?
Please explain with example. Thank you.
Your #3, is correct, you can call static methods from non-static methods by using classname.methodname.
And your question seems to be asking if you can call non-static methods in a class from other non-static methods, which is also possible (and also the most commonly seen).
For example:
public class Foo {
public Foo() {
firstMethod();
Foo.staticMethod(); //this is valid
staticMethod(); //this is also valid, you don't need to declare the class name because it's already in this class. If you were calling "staticMethod" from another class, you would have to prefix it with this class name, Foo
}
public void firstMethod() {
System.out.println("This is a non-static method being called from the constructor.");
secondMethod();
}
public void secondMethod() {
System.out.println("This is another non-static method being called from a non-static method");
}
public static void staticMethod() {
System.out.println("This is the static method, staticMethod");
}
}
A method is and should be in the first regard be semantically bound to either the class or the instance.
A List of something has a length or size, so you ask for the size of special List. You need an object of that class to call .size ().
A typical, well known example of a static method is Integer.parseInt ("123");. You don't have an Integer instance in that moment, but want to create one.
If, at all, we would bind that method to an instance, we would bind it to a String instance - that would make sense:
int a = "123".parseInt ();
That would have been a reasonable choice, but it would mean that similar methods for float, double, long, short, Boolean and maybe every class which has a symmetric "toString" method would have to be put into String. That would have meant a zillion of extensions to the String class.
Instead String is final, so a reasonable place to put such a method is the target class, like Integer, Float and so on.
not sure that I understand the question correctly, but non-static methods are the standard way to design classes in OO. Maybe this sample will help spark the discussion:
public class MySampleClass{
private void methodA(){
System.out.println('a called');
}
public void methodB(){
this.methodA();
staticMethod(this);
}
private static void staticMethod( MySampleClass inst ){
inst.methodA();
}
}
You can call non-static method from non-static method using explicitly reference to object on which you want to call that method someObject.method, or without specifying that object someMethod() (in this case it will be invoked on same object that you are invoking current non-static method).
Maybe this will show it better
class Demo {
private String name;
public Demo(String n) {
name = n;
}
public String getName() {// non static method
return name;
}
public void test(Demo d) {// non-static method
System.out.println("this object name is: "+getName());// invoking method on this object
System.out.println("some other object name is: "+d.getName());// invoking method on some other object
}
//test
public static void main(String[] args) {
Demo d=new Demo("A");
Demo d2=new Demo("B");
d.test(d2);
}
}
output:
this object name is: A
some other object name is: B
public class TestClass{
public static void testStatic(){
System.out.println("test1");
}
public void testNonStatic(){
System.out.println("test2");
}
public void test1(){
// both is valid
testStatic();
TestClass.testStatic();
// this is valid, cause it can call the method of the same instance of that class
testNonStatic();
this.testNonStatic();
// this is not valid, cause without a concrete instance of a class you cannot call
// non static methods
TestClass.testNonStatic();
}
public static void test2(){
// again these are both correct
testStatic();
TestClass.testStatic();
// this doesn't work, cause you cannot call non static methods out of static methods
testNonStatic();
this.testNonStatic();
// this instead does work cause you have a concrete instance of the object
TestClass myTestClass = new TestClass();
myTestClass.testNonStatic();
// this still doesn't work
TestClass.testNonStatic();
}
}

Categories