instanceof, subclasses and casting - java

if I have a class myClass1 and a second class myClass1Extended that is an extension of the first class, I have this source code:
myClass1 c1 = something(); // line 1
myClass1Extended c1ex = somethingElse(); // line 2
if (c1ex instanceof myClass1) { // line 3
(myClass1)c1ex.doSomething(); // line 4
}
I have a few questions:
in Line 3, will the operator instanceof return true?
in line 4, supposing the first answer is yes, what will happen if doSomething() has not been overriden in myClass1Extended?
And what happens instead if doSomething() has been overriden?
in line 4, is (myClass1) necessary?
Thank you very much

Why don''t you try the code to see?
yes
it will call the one in the parent class
it will call the one in the child class
no.
Given:
class Parent
{
public void foo()
{
System.out.ptintln("parent::foo");
bar();
}
public void bar()
{
System.out.println("parent::bar");
}
}
class Child
extends Parent
{
public void foo()
{
super.foo();
System.out.ptintln("child::foo");
}
}
You can use the Child class anywhere you use the Parent class, because all Children are types of Parents.
When the compiler looks at this code:
Parent p = new Child();
it verifies that the Child extends or implements the Parent.
When the compiler looks at this code:
p.foo();
it verifies that the type the p is declared as, Parent, has a foo method.
At runtime when the p.foo() line is executed the Virtual Machine looks at the type that p is actually pointing at, Child, and looks there for the foo method. Assuming the foo method is found in Child it runs it, otherwise it looks at the Parent class for it.
In the Parent class when the foo method calls bar the compiler again looks to make sure that the Parent class has a bar method. At runtime the VM again looks at the Child class to for the bar method, and since it does not it calls the one in the Parent.
If the methods don't exist in Parent then they have to exist the in the parent class of Parent, all the way up to java.lang.Object.

To answer your question take this example here:
package test;
public class Parent
{
public void printFoo()
{
System.out.println("foo");
}
public void printBar()
{
System.out.println("bar");
}
}
package test;
public class Child extends Parent
{
#Override
public void printFoo()
{
System.out.println("myFoo");
}
}
package test;
public class Main
{
public static void main(String ... args)
{
Parent test = new Child();
Parent test2 = new Parent();
print(test);
print(test2);
}
public static void print(Parent parent)
{
if (parent instanceof Parent)
{
System.out.println(parent.getClass().getName()+" is Parent");
parent.printFoo();
parent.printBar();
}
}
}
As you can see Child inherits from Parent and overrides printFoo() method. On printing those Parent objects you will get the following output:
test.Child is Parent
myFoo
bar
test.Parent is Parent
foo
bar
So to answer your questions:
1) yes
2) it will call the method of the parent class
3) it will invoke the overriden method - if this method contains a super-call then the parent's method will execute as well
4) No - if you specify f.e. Parent o = new Child() and implement a method in Child that is not present in Parent and you want to invoke the method of the child object, you will have to cast it back to Child ((Child)o).invokeYourMethod()

Related

Can anyone explain why below o/p

Parent class :
public class Parent {
public void run()
{
walk();
System.out.println("Parent run");
}
public void walk()
{
System.out.println("Parent walk");
}
Child Class :
public class Child extends Parent {
public void run()
{
super.run();
System.out.println("child run");
}
public void walk()
{
super.walk();
System.out.println("child walk");
}
public class FirstJava {
public static void main(String[] a) {
Child c=new Child();
c.run();
}
I am gettting below o/p
Parent walk
child walk
Parent run
child run
Here when i call walk() its going for walk() of Child.
Why not for walk() of parent?
While calling walk() which object its refering to and why? any one explain why??
how come its calling both the methods from child as well as parent.
in
Child c=new Child();
c.run();
you apply run corresponding to the type of the value in c, because c values a Child and run is defined on it you call the operation run defined on Child being :
public void run()
{
super.run();
System.out.println("child run");
}
super.run() applies the operation corresponding to the parent class, because the parent class of Child is Parent and run is defined on it you call :
public void run()
{
walk();
System.out.println("Parent run");
}
the operation walk is applied depending on the real type of the instance being Child so you call :
public void walk()
{
super.walk();
System.out.println("child walk");
}
like before because of super that calls the operation on Parent :
public void walk()
{
System.out.println("Parent walk");
}
printing Parent walk then you come back in Child walk printing child walk then come back in Parent run printing Parent run then come back in Child run printing child run
After your edit
Here when i call walk() its going for walk() of Child. Why not for walk() of parent? While calling walk() which object its refering to and why?
As I already say this is because the called method is determined (at the execution) by the real type of the instance, and in that case the instance is a Child, so the called method is the walk defined on Child and not the one on Parent. Of course if there is no walk defined on Child it would be the one defined on Parent. All the method are applied on the unique instance you created in main and being a Child
Of course if walk is a method for the class Parent (e.g. static) rather than for its instances that changes all and walk() in run of Parent would be the walk of Parent. But this is not the case in your code so the real type of the instance counts.
Note also the execution would the all the same modifying your main to have :
public class FirstJava {
public static void main(String[] a) {
Parent c=new Child();
c.run();
}
because even c is declared Parent its value is a Child
If you override a parent method in its child, child objects will always use the overridden version.

Is overloading in inheritance class possible in Java?

Is overloading in inheritance class possible in Java? Parent class and Child class contain the same method name, but different parameters. Is this overloading?
class Parent {
public void add(int a) {
System.out.println("I am parent" + a);
}
}
class Child extends Parent {
public void add(long a) {
System.out.println("I am child.");
}
}
Yes. While extending any class, internally it means all accessible behaviour of the parent class will be present or inherited in child class. i.e, so in your case same name with different argument is overloading.
Yes of course, overloading in inheritance class is possible in Java. Java compiler detect that add method has multiple implementations. so according to the parameter java compiler will determines which method has to be executed.
class Parent {
public void add(int a) {
System.out.println("I am parent " + a);
}
}
class Child extends Parent {
public void add(long a) {
System.out.println("I am child.");
}
}
class Demo{
public static void main(String args[]){
Child child = new Child();
child.add(1); // prints "I am parent 1"
child.add(1L); // prints "I am child."
}
}
Yes, In java allow overloading concept which means you can declare different method with Same name and different parameter .In your case You are extending the parent class ,which means all the property of parent class available in child class(child).
Its a overloading:
Child c = new Child();
c.add(1);//it will call the parent method
c.add(1L);//It will call the child method

Java - calling a method by passing child instance to a function with parameter of parent class type [duplicate]

public class Parent {
....
}
public class Child1 extends Parent {
....
public void foo() {
....
}
}
public class Child2 extends Parent {
....
public void foo() {
....
}
}
Here method foo() only exists in the Child classes and CAN NOT be added to the Parent class (not even abstract method). In this situation when I want to call the foo() method on obj which is Parent class's reference then I need to use intanceof with multiple if..else which I want to avoid.
Parent obj = ...// Object of one of the child classes
obj.foo();
EDIT: I Need to use type of obj as Parent only. Else I will not be able to call methods on obj which exists in Parent class.
My Solution: The approach that I am thinking is to define an interface say FooInterface with foo() method and let all the child classes implement it, then I could just type cast the obj to that interface and call foo() method like this:
if(obj instanceof FooInterface){
((FooInterface)obj).foo();
}
Is there a better approach ? Or any improvement to this one?
You can't do it with parent object reference until an unless method is declared in parent class/interface itself.
You have to downcast it to child class because parent class/interface doesn't have any knowledge about the child class other than the contract defined between them.
Here contract means abstract methods.
you can try in this way where there is no need to put a check it.
FooInterface sc =new Child1();
sc.foo();
...
interface FooInterface{
void foo();
}
public class Parent {
}
public class Child1 extends Parent implements FooInterface{
public void foo() {
}
}
public class Child2 extends Parent implements FooInterface{
public void foo() {
}
}
The approach that I am finally taking is to define an interface say FooInterface with foo() method and let all the child classes implement it, then I could just type cast the obj to that interface and call foo() method like this:
Parent obj = ...// Object of one of the child classes
.....
if(obj instanceof FooInterface){
((FooInterface)obj).foo();
}
The polymorphism is applied on object reference, not a type. When you call
FooInterface obj = ...// Object of one of the child classes
obj.foo();
the child class method foo() is called.
If you want to typecast only then there is no need of adding interface. You can typecast it to your desired class and call the method. Example
public class HelloWorld {
public static void main(String args[]) throws FileNotFoundException {
SuperClass sc =new Child1();
if(sc instanceof Child1)//Do same for Child2
((Child1)sc).foo();
}
}
class SuperClass {
}
class Child1 extends SuperClass{
public void foo(){
System.out.println("From child1");
}
}
class Child2 extends SuperClass{
public void foo(){
System.out.println("From child2");
}
}
Output :
From child1
You could implement an AbstractChild inheriting from Parent and then extend this class instead of Parent:
public class Parent {
....
}
public abstract class AbstractChild extends Parent{
public abstract void foo();
}
public class Child1 extends AbstractChild {
....
public void foo() {
....
}
}
public class Child2 extends AbstractChild {
....
public void foo() {
....
}
}
So you need to only check if your instance is instanceof AbstractChild.

Why is the parent class method called?

Why is the parent class method called when I am creating a child object. This is not even a static method.
class Parent {
public String pubMethod(Integer i) {
return "p";
}
}
public class Child extends Parent {
public String pubMethod(int i) {
return "c";
}
public static void main(String[] args) {
Parent u = new Child();
System.out.println(u.pubMethod(1)); // Prints "p" why??
}
}
Here I am passing a primitive int . Still it goes to the parent method.
Any explanation?
When you call u.pubMethod(1), the compiler considers only the signatures of the methods of Parent class, since Parent is the compile-type type of u. Since public String pubMethod(Integer i) is the only method of Parent having the required name, that's the selected method. public String pubMethod(int i) of Child class is not considered as a candidate, since Parent has no method of such signature.
In run-time, the method of the sub-class, public String pubMethod(int i), cannot override the super-class method public String pubMethod(Integer i), since it has a different signature. Therefore the Parent class method is executed.
In order for the Child class to be executed, you must either change its signature to match the Parent class method's signature, which will allow it to override the Parent class method:
public class Child extends Parent {
#Override
public String pubMethod(Integer i) {
return "c";
}
}
Or you can add a second method to the Parent class, which the existing Child class method will override:
class Parent {
public String pubMethod(Integer i) {
return "pInteger";
}
public String pubMethod(int i) {
return "pint";
}
}
In the first case, the compiler will still have a single method to choose - public String pubMethod(Integer i) - but in run-time the Child class method will override it.
In the second case, the compiler will have two methods to choose from. It will choose public String pubMethod(int i), since the type of the literal 1 is int. In run-time, the Child class public String pubMethod(int i) method will override it.
I think you didnt create your child object properly, you have:
Parent child = new Child();
But you should have:
Child child = new Child();

Why bother using abstract method and overriding while we can always use a generic method in the superclass?

The following is a popular use case involving abstract method and overridding.
class Demo {
public static void main(String[] args) {
Parent a = new Child_A();
Parent b = new Child_B();
a.method();
b.method();
}
}
abstract class Parent {
abstract void method();
}
class Child_A extends Parent {
#override
void method() {
do the task for Child_A;
}
}
class Child_B extends Parent {
#override
void method() {
do the task for Child_B;
}
}
It seems that we can always achieve the same thing by defining a generic method in the superclass, which uses the instanceof keyword to determine the subclass and performs the corresponding task for the subclass.
class Demo {
public static void main(String[] args) {
Parent a = new Child_A();
Parent b = new Child_B();
a.method();
b.method();
}
}
class Parent {
void method() {
if (this instanceof Child_A) {
do the task for Child_A;
}
else if (this instanceof Child_B) {
do the task for Child_B;
}
}
}
class Child_A extends Parent {
}
class Child_B extends Parent {
}
Which code style is better and why?
Because:
you don't want to have to modify the parent class every time you add another subclass
in some circumstances like a library API you may not even know all the subclasses
code that deals with a subclass should be in that subclass, not in the parent.
If you do the latter, your subclasses becomes useless. They don't do anything. I'd like to think of it this way, the parent passed you the ability to do methodA in your own way. However in your case, the parent does everything, meaning you are dependent on your parent forever. Who would want that?
Well aside from that, when you create a new subtype, you'll have to edit also the parent(very absurd), think of what will happen 100 subtypes later. Give your subtypes the power to have their own individuality.

Categories