Override a Method at Instance Level

Override a method at instance level

Please do not do this as shown. You code becomes unreadable when you monkeypatch an instance to be different from the class.

You cannot debug monkeypatched code.

When you find a bug in boby and print type(boby), you'll see that (a) it's a Dog, but (b) for some obscure reason it doesn't bark correctly. This is a nightmare. Do not do it.

Please do this instead.

class Dog:
def bark(self):
print "WOOF"

class BobyDog( Dog ):
def bark( self ):
print "WoOoOoF!!"

otherDog= Dog()
otherDog.bark() # WOOF

boby = BobyDog()
boby.bark() # WoOoOoF!!

C# override instance method

You can't. You can only override a method when defining a class.

The best option is instead to use an appropriate Func delegate as a placeholder and allow the caller to supply the implementation that way:

public class SomeClass
{
public Func<string> Method { get; set; }

public void PrintSomething()
{
if(Method != null) Console.WriteLine(Method());
}
}

// Elsewhere in your application

var instance = new SomeClass();
instance.Method = () => "Hello World!";
instance.PrintSomething(); // Prints "Hello World!"

Is it possible to do dynamic method overriding from a method of another class? If so, How?

The key is to pass the right arguments to the method.
Let's have a closer look at the error you're getting in the first place:

TypeError: unbound method do_something() must be called with 
OtherPerson #instance as first argument (got nothing instead)

When you look at OtherPerson.do_something, it's clear that it's expecting an instance as its first parameter.
So now p.do_something refers to OtherPerson.do_something, it needs that first parameter.
Therefore, a correct call, in the current state, would be:

p.do_something(p)

Of course, this is not really nice, since you have to specify the instance twice.
That's because the method is now unbound: it does not know of the instance on which it is called, ie it does not know self.

The solution I'm proposing consists in making p.do_something refer to a function that calls OtherPerson.fo_something with p as first argument.


Let's have two classes, Foo and Bar, defined as follow:

class Foo:
def __init__(self, x):
self.x = x

def speak(self):
print("Foo says:", self.x)

class Bar:
def __init__(self, x):
self.x = x

def speak(self):
print("Bar says:", self.x)

Suppose you have a foo instance from the Foo class.
Now, you want to dynamically override its speak method, so that it calls Bar's instead.
You can simply reassign foo.speak to a function that calls Bar.speak.

>>> foo = Foo(2)
>>> foo.speak()
Foo says: 2
>>> foo.speak = lambda: Bar.speak(foo)
>>> foo.speak()
Bar says: 2

You can make it even more generic.
For the sake of example, let's write a function that takes an instance, a method name, and a target class, and overrides the instance's matching method with the target class':

def override(instance, method_name, target_class):
class_method = getattribute(target_class, method_name)

def new_method(*args, **kwargs):
return class_method(instance, *args, **kwargs)

setattribute(instance, method_name, new_method)

You can observe the same expected behaviour:

>>> foo = Foo(2)
>>> override(foo, "speak", Bar)
>>> foo.speak()
Bar says: 2

possible to Java override functions at an instance level?

Background:

This is called anonymous class. It is a class that extends a non final class or implements a single interface and you're creating a single instance of this class.

Now, to your questions:

1) Are these functions overwritten at an instance level?

No, they are at level class. You have a new subclass of the desired class and this subclass overrides the method. Then, you create a new instance of the subclass.

2) Does this language feature have a name?

Yes, it is anonymous class.

Override method for just one instance in JavaScript

The usual thing here would be to parameterize the Horn class so that it accepts the sound to make:

function Horn(sound) {
this.sound = sound !== undefined ? sound : "Düdelüüüü!";
this.level = '123dB';
}

Horn.prototype.doTutut = function() {
return this.sound;
};

Then within, say, Mercedes, you'd either pass the sound to the Car super constructor or set it afterward on this.horn.


If you have an entire method you need to rewrite, you can just assign it to this.horn.theMethod:

function Mercedes() {
Car.call(this); // See below, important to do this first
this.horn.theMethod = function() {
// New implementation here
};
}

...but it's important that you fix the inheritance stuff below first.

Of course, if you want all Mercedes instances (for instance) to share a single Horn instance, just put the horn with the appropriate method on Mercedes.prototype.


Side note: Your inheritance setup is using an oft-repeated anti-pattern. Don't do this:

Mercedes.prototype = new Car();

If you do that, there are two problems:

  1. Car can't accept arguments, and

  2. Mercedes.prototype.constructor is wrong

  3. Because Car assigns an object (new Horn) to this, all your instances of each subclass (Mercedes, Audi, etc.) end up sharing the same object (one horn). If that object is stateless, that's great, but it should have been on Car.prototype. If it isn't stateless, that creates hard-to-diagnose cross-talk between Car instances.

Also, Mercedes is never calling Car, which it should be doing to give Car the chance to initialize its parts of the instance.

In ES5, this is the correct way to do it:

function Mercedes() {
// Gives `Car` its chance to do init; could pass on args here if appropriate
Car.call(this);
this.color = 'blue';
}

// Set up the prototype chain
Mercedes.prototype = Object.create(Car.prototype);
Mercedes.prototype.constructor = Mercedes;

Mercedes.prototype.drive = function() {
return "...BrumBrum...";
};

Of course, in ES2015 and above (which you can use now with transpiling), it's just:

class Mercedes extends Car {
drive() {
return "...BrumBrum...";
}
}

...unless the Mercedes constructor accepts parameters Car doesn't need/use.


Here's an example with updated inheritance and a shared horn across all instances of subclasses:

// Horn with generic defaultfunction Horn(sound) {    this.sound = sound !== undefined ? sound : "Düdelüüüü!";    this.level = '123dB';}
Horn.prototype.doTutut = function() { return this.sound;};
// Car using a single generic horn across all Car instancesfunction Car() {}Car.prototype.honk = function() { return this.horn.doTutut();};Car.prototype.horn = new Horn();
// Mercedes with its own special hornfunction Mercedes() { Car.call(this);}Mercedes.prototype = Object.create(Car.prototype);Mercedes.prototype.constructor = Mercedes;Mercedes.prototype.horn = new Horn("Mercedes Honk!");
// Audi with its own special hornfunction Audi() { Car.call(this);}Audi.prototype = Object.create(Car.prototype);Audi.prototype.constructor = Audi;Audi.prototype.horn = new Horn("Audi Honk!");
// Usagevar c = new Car();console.log(c.honk());var m = new Mercedes();console.log(m.honk());var a = new Audi();console.log(a.honk());

Is it possible to call an overridden method in an instance of child class ES 2015?

It's JavaScript, so you can. There's no classes anyway, just prototypal inheritance with some syntactic sugar over it.

Which one do you want to call: Car's emitsCarbon specifically? That'll be

Car.prototype.emitsCarbon.call(car1);

Your object's class' direct ancestor class' emitsCarbon in general?

car1.__proto__.__proto__.emitsCarbon.call(car1);

(You're not supposed to directly access __proto__, but there's nothing actually stopping you besides the general good practice and guidelines).

Also, hybrids do emit carbon. Just a side note.



Related Topics



Leave a reply



Submit