Questions about object superclasses and casting - java

I'm preparing for a java exam. I came across the following question
String s = new String ("hello");
Object o = (object) s;
Since o and s are both references that point to the same object, is there any difference in accessing the object through the reference s over the reference o?
Would I be right in saying that all objects (like the one being reference by s) are subclasses of Object in Java and as such using the reference s you will be able to call the methods known by the superclass Object like clone() and the methods known by String like length(). Whereas, the superclass object reference o will only be able to call it's own methods and not those of the subclass? Thanks.

The difference is that by using o you will not be able to call string specific methods unless you cast it back to String.
However, any method that you call on o that is defined on the String class will call the later version of the method. For example, o.toString() will return "hello", and not the descriptor that the Object.toString() normally returns. This is called polymorphism.

Related

Call toString() when convert String to Object [duplicate]

This question already has answers here:
What is polymorphism, what is it for, and how is it used?
(29 answers)
Closed 5 years ago.
Here is my example code:
String str = "hello";
Object obj = (Object)str;
System.out.println(obj.toString());
I found the source code of Object, and the toString() method is:
public String toString() {
return getClass().getName() + "#" + Integer.toHexString(hashCode());
}
I thought the result of the example shound be the address of this Object, like [B#15db9742 , after I convert str to Object , but it still print hello. Why? Shoundn't obj use the method of Object? Can Anyone explain the principle of it to me?
This is polymorphism (specifically, runtime polymorphism). It doesn't matter what the type of your reference to the object is (Object or String), as long as that type has toString (so your code compiles), the toString that will be used is the one the object itself actually has, not necessarily the one provided by the type of your reference. In this case, the object is a String no matter what the type of your reference to it is, so String#toString is used.
Because the underlying object is a String object and the String class has overridden the toString() method in it.
Though you have the type Object on left hand, the methods from implemented Class gets execute and the overall phenomenon called as Polymorphism. You are Just changing the Form of String to Object.
When you do
Object obj = (Object)str;
That doesn't change String to Object class. You are just changing the type of the Object not the actual behaviour of it.
Virtual method invocation implies the method override will be executed given the actual implementation, as opposed to the implementation in the reference type.
In other words, your String instance will still invoke overrides of Object's methods implemented in String, even if cast as Object.
Object obj is the result of an (unnecessary) cast, but is still a String....
the String class has an implemented overide of toString method:
public String toString() {
return this;
}
verify that obj is a String by doing:
System.out.println(str.getClass());
System.out.println(obj.getClass());
you will get
class java.lang.String
class java.lang.String

Assinging arbitrary values to Object type

I have a question regarding the following code:
Object o;
o = "Some string";
System.out.println(o.toString()); //Some string
o = 666;
System.out.println(o.toString()); //666
How come that the content of the Object can be printed without any casts? Is it really so universal container?
It's just due to polymorphism. Object defines the method toString(), and it is overridden in String and Integer.
Object o;
o = "Some string"; // o is now a String.
System.out.println(o.toString()); // so calls String::toString().
o = 666; // o is now an Integer.
System.out.println(o.toString()); // so calls Integer::toString().
If the method toString() had not been defined in Object, the cast would have been necessary.
The toString() method is defined on the Object class so, in a sense, yes it really is such a 'universal' container.
However, much of the useful functionality associated with any particular object is in the references of the object's subtype. Once you've assigned a String to an Object you can't access things like substring(). The functionality you can access with an Object reference is limited.
From the doc:
Class Object is the root of the class hierarchy. Every class has Object as a superclass. All objects, including arrays, implement the methods of this class.
Its not a universal container so to speak. Primitive types are not Object.
In your example, you are storing String and Integer which inherit from Object. Since Object has toString() method, you don't need to cast it.

creating an object with static type of base class vs subclass?

I cannot figure out the difference between accessing a method of a subclass that is accessed and overwritten using the base class(Object) for the static type of the object versus using the subclass(Point).
For example:
public class Point {
int x, y;
...
public boolean equals(Object o){
...
}
public boolean equals(Point p){
...
}
}
Object o = new Object();
Point p = new Point(3,4);
Object op = new Point(3,4);
// here the static type is Point and the dynamic type is point, in this case
// the equals() method that we choose and gets overwrriten depends on the
// parameter type that is passed.
p.equals(o);
p.equals(p);
p.equals(op);
// here however the static type is Object so we initially look at the equals()
// method in our Object class during compile time and check its parameter type
// which is Object, thus if we overwrite
// the equals() method we will pick the one that has a type Object parameter.
// Since the dynamic type of our object is Point, when we are at run time
// we will look for the equals() method in Point that matches with the
// method type Object parameter.
op.equals(o);
op.equals(op);
op.equals(p);
What i am not seeing is why would i want to use the later rather than the former to specify what method i would like to overwrite? The former depends on the type parameter while the later depends on the type parameter of the static type of our object. I just dont see the benefit of using Basetype obj = new Subclasstype() to access and overwritten method in my subclass. It looks more complicated and the object can only be used to access instances of methods in the subclass that were in the base class, not any other methods in the subclass.
public boolean equals(Point p){
...
}
The above method has nothing to do with equals(Object) except sharing the name equals. It does not override it, it cannot be invoked from an Object-typed variable, there is no contract for it defined by Object.
When you write
op.equals(p);
you are invoking a method on the Object type. The only method called equals in that type is equals(Object) and this choice is permanent. The runtime can only provide a different override of equals(Object), but it will never route the call to equals(Point).
Similarly, when you write
p.equals(op);
the compiler will again see that you are invoking equals with an argument whose static type is Object, selecting equals(Object).
I think you are messing up some concepts, so let me explain them:
Object op = new Point(3,4);
The behavior of variables o and p are clear, so I'll focus on op: it's a variable whose type is Object, which means you can use all methods declared in that class. You cannot use equals(Point p) method because it does not exist for Object. But, at the same time, the behavior of a method is given by the instance it self, not by the variable which is pointing at it, so op is pointing to a Point instance and the equals(Object) method has been overwritten, so the behavior of that method is given by the class Point.

How does the special variable "this" know exactly which Object to refer to in a program in JAVA? [duplicate]

This question already has answers here:
Using the keyword "this" in java [duplicate]
(12 answers)
Closed 9 years ago.
If the special variable this refers to an Object in a variable/method that is being used. How does it know exactly which object it must refer to out of various objects in a program?
The mechanism is almost disappointingly simple.
Each instance method actually takes one more argument than you declare for it, and that extra argument is assigned to this. Java syntax just thinly disguises this. When you write
list.get(0);
you have actually written
get(list, 0);
in a slightly modified way. The Java runtime resolves which get method to call by inspecting the type of that first argument and locating the appropriate get method in its class.
this points to the current object instance that it is used in.
If you define a class A with a method() that contains a this reference then you create two instances of the class
A a1 = new A();
A a2 = new A();
If you call a1.method() then this will refer to a1, if you call a2.method() then this will refer to a2
A a = new A();
a.doSomething(i) // is same as calling doSomething(a, i).
So, internally this refers to "a". The first argument to the function will be the object (there will only be one method that will be used by all objects). So, argument o will be the current object which has called this function.
From JAVA LANGUAGE SPECIFICATION
The keyword this may be used only in the body of an instance method,
instance initializer, or constructor, or in the initializer of an
instance variable of a class. If it appears anywhere else, a
compile-time error occurs.
When used as a primary expression, the keyword this denotes a value
that is a reference to the object for which the instance method was
invoked (§15.12), or to the object being constructed.
The type of this is the class C within which the keyword this occurs.
At run time, the class of the actual object referred to may be the
class C or any subclass of C.
The keyword this is also used in a special explicit constructor
invocation statement, which can appear at the beginning of a
constructor body (§8.8.7).
You can also refer to Oracle Tutorials
Within an instance method or a constructor, this is a reference to the current object — the object whose method or constructor is being called. You can refer to any member of the current object from within an instance method or a constructor by using this.
Oracle Java Tutorials
this is a very important keyword that can differentiate between parent and child class objects. this refers to the present context in which object has too be referred to..!!

Can you say an object is a reference to a class?

As part of my AP class I am learning objects, instances, references etc... So from what I understand a reference is a variable that points to something: a value, class etc . . . Therefore is it legal to say that a object is a reference to a class?
Note: I know this is subjective but I cant seem to find such a comparison anywhere else.
By the usual definition of reference you can not say that. Correct would be "An object is an instance of a class.".
The usual definition of a reference is a value which points to a memory location that is usually occupied by some object. The difference between pointers and references is that you can do pointer arithmetics on the former but not on the latter.
For example in the following code snippet:
SomeClass o = new SomeClass();
SomeClass foo = o;
SomeClass is the class and o is a reference to the instance of SomeClass returned by this particular invocation of the new keyword. new SomeClass() allocates memory for a new instance of SomeClass and calls its constructor to initialize it. foo is another reference to the very same instance of SomeClass also referred to by o. In other words, o and foo point to the same object but are not the same reference.
Object is not a reference of class, but instance of class.
No, that would not be a valid statement. An object is an instance of a class, not a reference to one. When you have something like:
MyClass var = new MyClass();
Then var is a reference to the MyClass instance to which it was assigned (new MyClass()). This instance is in turn an object.
From JLS §4.3.1:
An object is a class instance or an array.
The reference values (often just references) are pointers to these objects, and a special null reference, which refers to no object.
As somebody else said, a class is a like a blueprint. When you create an object based off of the class, the computer "builds" an object by allocating memory to create "parts" (variables) based off of your class.
Therefore, the object is not a reference to the class, implying that the object simply redirects you to the class.
The object is a instance of the class.
No. That would be like saying that the scrambeled eggs you ate this morning are a reference to the abstract concept of scrambeled eggs.
Remember that a class is a blueprint, but it's not an actual, concrete object on its own. That only happens when you instantiate an object via the new keyword.
An object is really an instance of a class. Let's say we have the String class. An object of the type String is an instance of the String class, not that class itself. Given String s="foo", s's value would be a reference to an instance of the String class.
Now, every class has a java.lang.Class object that is associated with it, so String.class is a reference to an instance of java.lang.Class.
From JLS:
An object is a class instance or an array.
The reference values (often just references) are pointers to these objects, and a special null reference, which refers to no object.
Object foo = new Object();
foo is an reference to a specific, concrete instance of the class Object but not to the class itself.
Class bar = Object.class;
bar is a reference to the Object class.

Categories