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:
Car
can't accept arguments, andMercedes.prototype.constructor
is wrongBecause
Car
assigns an object (new Horn
) tothis
, 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 onCar.prototype
. If it isn't stateless, that creates hard-to-diagnose cross-talk betweenCar
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
Pandas Group by and Find First Non Null Value for All Columns
Accessing Attributes on Literals Work on All Types, But Not 'Int'; Why
Generating Matplotlib Graphs Without a Running X Server
Find First Sequence Item That Matches a Criterion
Python Attributeerror: 'Module' Object Has No Attribute 'Serial'
Python: Platform Independent Way to Modify Path Environment Variable
Matplotlib: How to Plot Images Instead of Points
If Range() Is a Generator in Python 3.3, Why How to Not Call Next() on a Range
Scipy: Savefig Without Frames, Axes, Only Content
Convert Variable Name to String
How to Hide the Console Window in a Pyqt App Running on Windows
How to Create a Datetime in Python from Milliseconds
How to Get Flask to Run on Port 80
Importing Modules: _Main_ VS Import as Module
Replacing Text in a File with Python
Matplotlib Savefig() Plots Different from Show()
Getting Rid of Console Output When Freezing Python Programs Using Pyinstaller