Calling Super's Super Method

Calling super's super method

This is not recommended, but what you want is possible like this:

grandparent = self.class.superclass.superclass
meth = grandparent.instance_method(:the_method)
meth.bind(self).call

This works by first getting the grandparent class, then calling instance_method on it to get an UnboundMethod representing the grandparent's version of the_method. It then uses UnboundMethod#bind and Method#call to call the grandparent's method on the current object.

How to call super method from grandchild class?

Well, this is one way of doing it:

class Grandparent(object):
def my_method(self):
print "Grandparent"

class Parent(Grandparent):
def my_method(self):
print "Parent"

class Child(Parent):
def my_method(self):
print "Hello Grandparent"
Grandparent.my_method(self)

Maybe not what you want, but it's the best python has unless I'm mistaken. What you're asking sounds anti-pythonic and you'd have to explain why you're doing it for us to give you the happy python way of doing things.

Another example, maybe what you want (from your comments):

class Grandparent(object):
def my_method(self):
print "Grandparent"

class Parent(Grandparent):
def some_other_method(self):
print "Parent"

class Child(Parent):
def my_method(self):
print "Hello Grandparent"
super(Child, self).my_method()

As you can see, Parent doesn't implement my_method but Child can still use super to get at the method that Parent "sees", i.e. Grandparent's my_method.

Why is super.super.method(); not allowed in Java?

It violates encapsulation. You shouldn't be able to bypass the parent class's behaviour. It makes sense to sometimes be able to bypass your own class's behaviour (particularly from within the same method) but not your parent's. For example, suppose we have a base "collection of items", a subclass representing "a collection of red items" and a subclass of that representing "a collection of big red items". It makes sense to have:

public class Items
{
public void add(Item item) { ... }
}

public class RedItems extends Items
{
@Override
public void add(Item item)
{
if (!item.isRed())
{
throw new NotRedItemException();
}
super.add(item);
}
}

public class BigRedItems extends RedItems
{
@Override
public void add(Item item)
{
if (!item.isBig())
{
throw new NotBigItemException();
}
super.add(item);
}
}

That's fine - RedItems can always be confident that the items it contains are all red. Now suppose we were able to call super.super.add():

public class NaughtyItems extends RedItems
{
@Override
public void add(Item item)
{
// I don't care if it's red or not. Take that, RedItems!
super.super.add(item);
}
}

Now we could add whatever we like, and the invariant in RedItems is broken.

Does that make sense?

Calling super super class method

You can't even use reflection. Something like

Class superSuperClass = this.getClass().getSuperclass().getSuperclass();
superSuperClass.getMethod("foo").invoke(this);

would lead to an InvocationTargetException, because even if you call the foo-Method on the superSuperClass, it will still use C.foo() when you specify "this" in invoke. This is a consequence from the fact that all Java methods are virtual methods.

It seems you need help from the B class (e.g. by defining a superFoo(){ super.foo(); } method).

That said, it looks like a design problem if you try something like this, so it would be helpful to give us some background: Why you need to do this?

Calling a method on super.super in objective c?

You should be able to do this:

Method method = class_getInstanceMethod([ParentParentClass class], @selector(myMethod));
IMP imp = method_getImplementation(method);
((void (*)(id, SEL))imp)(self, @selector(myMethod)); // cast the function to the correct signature

You may need to #import <objc/runtime.h> in order for this to compile.

This gets the actual C function that the method is translated to at compile time, which you can then call. When the Objective-C compiler compiles your code, all methods are translated into plain C functions, which take self as their first argument, and _cmd, the selector for the current method as the second argument, followed by all of the other arguments that the Objective-C method takes. class_getInstanceMethod obtains the runtime representation of the given method (including various metadata), and method_getImplementation gets the plain C function pointer from that method.

If you look at the Objective-C runtime header, you'll see that the IMP type is defined as typedef id (*IMP)(void);, so you need to cast it to the actual type of the method implementation function, which will be (return_type (*)(id, SEL, method_arguments_in_order)) — the function takes self and the method selector as its first two arguments, followed by the ObjC method parameters.

So, once you have the standard C function pointer, you can simply call it as you would call a function.

I wouldn't go so far as to call this approach hacky, but it certainly is non-standard, as made clear by the need to use the underlying runtime methods directly to achieve what you want. I would definitely consider this a better solution, in terms of design, reliability and making sense, than adding bridging methods in the superclass that call its superclass' methods.

How to call a method of super.super?

In your particular example, +superclass is actually the way to go:

+ (id)someClassMethod {
return [[[self superclass] superclass] someClassMethod];
}

since it is a class method, hence self refers to the class object where +someClassMethod is being defined.

On the other hand, things get a tad more complicated in instance methods. One solution is to get a pointer to the method implementation in the supersuper (grandparent) class. For instance:

- (id)someInstanceMethod {
Class granny = [[self superclass] superclass];
IMP grannyImp = class_getMethodImplementation(granny, _cmd);
return grannyImp(self, _cmd);
}

Similarly to the class method example, +superclass is sent twice to obtain the supersuperclass. IMP is a pointer to a method, and we obtain an IMP to the method whose name is the same as the current one (-someInstaceMethod) but pointing to the implementation in the supersuperclass, and then call it. Note that you’d need to tweak this in case there are method arguments and return values different from id.

Calling a method of a super-super class

While I question the design that requires you to do this, you can easily acieve this by getting the original method of A.prototype and using call:

class C extends B { 
notify() { alert("C") }

callA() {
A.prototype.notify.call(this);
}
}

How to call super.super method in Ruby

You can get the move instance method of Animal, bind it to self, then call it:

class Penguin < Bird
def move
m = Animal.instance_method(:move).bind(self)
m.call
end
end

Java Inheritance - calling superclass method

You can do:

super.alphaMethod1();

Note, that super is a reference to the parent class, but super() is its constructor.

Difference between super keyword vs class name to call method from super class

Calling a method using class name directly means that you want to call a static method, which is not related to any object of the class but the class it self.
That is why the compiler tells you that the method must be static.

As for your question, when you create an object of a child class (Bike class in this example) an object of its parent is always created, on the base of which the particular child object is created.

Its like, when ever you create a Bike, a backing Vehicle is always created, based on which the Bike is created. Otherwise the Bike wouldn't be a Vehicle.

So calling a method by super means, you're telling the compiler to call this method on the class which was used as base(parent) for making this Bike class, from which I'm calling this method.

when you're calling the method by class name, you're telling the compiler to call this method of Vehicle class which is not related to any Vehicle object/instance (and obviously not related to any child (e.g. Bike object or instance as well)



Related Topics



Leave a reply



Submit