How can we call methods overridden in a java anonymous class? - java

Consider the code below :
abstract class AbstractClass {
abstract m1();
}
public class Test {
public static void main(String [] args) {
AbstractClass obj = new AbstractClass() {
#Override void m1() {
System.out.print("Instance of abstract class !");
}
};
obj.m1();
}
}
Now here is what I did not understand about this code.
I read that anonymous class creates the class with unknown name which extends the class whose reference is provided (here it is abstract AbstractClass).
Also I remember that we cannot implement the method of child class if the the object is having reference of parent class.
see block of code below
Parent obj = new Child();
obj.methodOfParent();
obj.methodOfChild(); //this gives error
Now here is my point if Anonymous Class extends its Parent Class whose reference is provided, then how can we call overriden methods of Parent Class from Anonymous Class?

I guess you just miss one point. Let me show you example:
class Parent {
public void methodOfParent() {}
public void methodOfParentToBeOverriden() {}
}
class Child extends Parent {
#Override public void methodOfParentToBeOverriden() {}
public void methodOfChild() {}
}
Parent obj = new Child();
obj.methodOfParent(); //this is OK
obj.methodOfParentToBeOverriden(); // this is OK too
obj.methodOfChild(); //this gives error
((Child)obj).methodOfChild(); //this is OK too here.
Please note that when you call obj.methodOfParentToBeOverriden() it will be called implementation from Child class. Independence did you cast this object to Parent type or not.

There is a difference between calling an overridden method of parent and calling a method of child. If a method is declared in class T, you can call it on a variable statically typed as T, regardless of where the method is actually implemented.
In your example, if obj.methodOfParent() happens to be a method override from Child, the method in Child will run, even though obj's static type is Parent.
Same mechanism is in play with anonymous classes: the reason that you are allowed to call obj.m1() is that m1() has been declared in the parent class.

Related

Cannot resolve method 'childMethod' in 'Sup3r'

Consider the following two classes:
public class Sup3r {
public void sup3rMethod() {}
}
public class Child extends Sup3r {
public void childMethod() {}
}
and the following three statements:
s.sup3rMethod();
c.childMethod();
s.childMethod();
The last statement gives
Cannot resolve method 'childMethod' in 'Sup3r'
Why?
because the method childMethod only exists in the subclass Child. Sup3r is not inheriting this method from Child therefore the childMethod cannot be called using s.
If the reference variable s contains a Child instance then you can make it work by casting s to a
Child type first and then calling the method on s.
((Child)s).childMethod();
If the reference variable s does not in fact contain a Child instance then you will get a ClassCastException instead.
EDIT:
There is one other way you could make it work and that is by making the superclass Sup3r abstract and adding the abstract method childMethod()
to the class like so:
public abstract class Sup3r {
public void sup3rMethod() {}
public abstract void childMethod();
}
public class Child extends Sup3r {
public void childMethod() {} //implementation code here, the empty block would suffice too however.
}
abstract means that you leave the implementation of the method childMethod() to one of Sup3rs implementing subclasses. If you make this change to your code then you should be able to call childMethod() on s without having to cast to Child first. But the result of childMethod() will depend on the specific childMethod() method implementation of the subclass instance that s references.

How can we access super class's method which a sub class has overidden? Hows that possibly on memory level?

I saw an example where a super class's original method was accessed from the subclass's method which is an overridden method. But a sub class's instance will only have a method that's an overridden method and not the superclass's method.But how come subclass is able to access super class's method.
Reference which says an sub class instance has only overiden method
// A Java program to demonstrate that overridden
// method can be called from sub-class
// Base Class
class Parent
{
void show()
{
System.out.println("Parent's show()");
}
}
// Inherited class
class Child extends Parent
{
// This method overrides show() of Parent
#Override
void show()
{
super.show();
System.out.println("Child's show()");
}
}
// Driver class
class Main
{
public static void main(String[] args)
{
Parent obj = new Child();
obj.show();
}
}
OUTPUT:
Parent's show()
Child's show()
A class probably has a table of function pointers to its implementation methods. It probably has a reference (implicit by class layout or explicit via a pointer or some sort of reference) to its super class and has indirectly access to that class's table of function pointers. All these are implementation details not specified in the Java language.
An analogy can be found http://www.faq3.de/OrganizeMe/pg/pdf/inside.the.c++.object.model.pdf on page 93
Calling super.show() logically moves to the super class's (Parent) table of function pointers and calls that class's show() method.

Overriding private method

We can not override a private method then why does the followng code does not give an error. Instead it produces the output.
class A {
private void fun() {
System.out.println("ths is a private method");
}
}
class B extends A {
void fun() {
System.out.println("ths is wrng");
}
}
class C {
public static void main(String args[]) {
B ob = new B();
ob.fun();
}
}
private methods are not inherited. In your main method you're invoking the fun() method on a variable of type B. The fun() method of type B seems to be accessible, assuming your class B and class C are in the same package.
Had you done this
A ob = new B();
ob.fun();
Then you would have gotten your compilation error.
B#fun() is completely unrelated to A#fun().
Both are completely different methods and not related to each other. As private methods are not inherited there is no concept of overriding here.
Method fun() is not overridden in B class because it was never inherited from class A.
What you are invoking in your code is method of B class and that has no relation with class A and method A#fun().
To check this, Add a #Override annotation and you will get compile time error.
// Compilation error.
Class B extends A{
#Override
void fun(){
System.out.println("ths is wrng");
}
}
Now this code will not compile.
First of all, private methods are not inherited in child classes. If you still try to write a method with same name as that of parent class, java compiler will consider the method in child class as a completely new method and will not throw any exception. Its like the new method in child class shadows the private method in parent class.

How to create custom class from variable? (not Object)

I know I can do do the following :
String className = "A";
Object o= Class.forName(className).newInstance();
But consider this case (simplification):
class Parent {
public void action() {...};
}
class A extends Parent {
#Override
public void action() {...};
}
class B extends Parent {
#Override
public void action() {...};
}
class C extends Parent {
#Override
public void action() {...};
}
Now I would like to create a class that can be either of those 3 cases.
If I use the above code and create an Object, I wouldn't be able to call the action method.
I would like to be able to create an object that extends Parent from a string.
In my actuall case I have multiple different parents, and the class is extented from a class that's extended from a class and about 4 layers of inhertiance. Would regular casting work?
Casting would work, but is unnecessary. Class#newInstance() returns an instance of type T, which is the class' generic type. This means that because Class.forName("A") returns an instance of Class<A>, you can declare your instance as Parent due to A's inheritance, as newInstance() is returning an object of type A.
Parent p = Class.forName("A").newInstance();
p.action();
Since all your classes extend Parent you can cast result of newInstance() to this type and then call all methods declared in Parent. The "right" implementation will run.
Parent p = (Parent)Class.forName(className).newInstance();
p.action();

calling parent class method from child class object in java

I have a parent class which has a method, in the child class I override that parent class's method. In a third class I make an object of child and by using that object I want call the method of parent class. Is it possible to call that parent class method ? If yes, then how?
If you override a parent method in its child, child objects will always use the overridden version. But; you can use the keyword super to call the parent method, inside the body of the child method.
public class PolyTest{
public static void main(String args[]){
new Child().foo();
}
}
class Parent{
public void foo(){
System.out.println("I'm the parent.");
}
}
class Child extends Parent{
#Override
public void foo(){
//super.foo();
System.out.println("I'm the child.");
}
}
This would print:
I'm the child.
Uncomment the commented line and it would print:
I'm the parent.
I'm the child.
You should look for the concept of Polymorphism.
Use the keyword super within the overridden method in the child class to use the parent class method. You can only use the keyword within the overridden method though. The example below will help.
public class Parent {
public int add(int m, int n){
return m+n;
}
}
public class Child extends Parent{
public int add(int m,int n,int o){
return super.add(super.add(m, n),0);
}
}
public class SimpleInheritanceTest {
public static void main(String[] a){
Child child = new Child();
child.add(10, 11);
}
}
The add method in the Child class calls super.add to reuse the addition logic.
First of all, it is a bad design, if you need something like that, it is good idea to refactor, e.g. by renaming the method.
Java allows calling of overriden method using the "super" keyword, but only one level up in the hierarchy, I am not sure, maybe Scala and some other JVM languages support it for any level.
Say the hierarchy is C->B->A with A being the base class.
I think there's more to fixing this than renaming a method. That will work but is that a fix?
One way is to refactor all the functionality common to B and C into D, and let B and C inherit from D: (B,C)->D->A Now the method in B that was hiding A's implementation from C is specific to B and stays there. This allows C to invoke the method in A without any hokery.
NOTE calling parent method via super will only work on parent class,
If your parent is interface, and wants to call the default methods then need to add interfaceName before super like IfscName.super.method();
interface Vehicle {
//Non abstract method
public default void printVehicleTypeName() { //default keyword can be used only in interface.
System.out.println("Vehicle");
}
}
class FordFigo extends FordImpl implements Vehicle, Ford {
#Override
public void printVehicleTypeName() {
System.out.println("Figo");
Vehicle.super.printVehicleTypeName();
}
}
Interface name is needed because same default methods can be available in multiple interface name that this class extends. So explicit call to a method is required.

Categories