Instance method #
In many object-oriented languages (like Java), methods are implemented within classes.
An instance method is called via an instance of the class where the method is declared.
In Java #
Example. Consider an instance method
myMethod()declared in a classMyClass:public class MyClass { ... public MyClass(){ ... } public void myMethod(){ ... } }This method can be called by appending
.to a variablemyVarof typeMyClass, as follows:MyClass myVar = new MyClass(); myVar.myMethod();
The object used to call an instance method can be accessed within this method.
Example (continued). The object referenced by the variable
myVaris accessible withinmyMethod(even though it is not passed as argument).
Benefit. This intuitively lets us write a method with one less argument.
Example. Recall the imaginary game introduced earlier. The method
meetsthat we implemented is not and instance method.Instead, we can implement it as instance method
meetsWith, as follows:public abstract class NPC { int xp; ... public void meetsWith(NPC contact){ // same implementation as for `meet` int tmp = xp; xp += contact.xp; contact.xp += tmp; } }This method may be called as follows:
Unicorn u = new Unicorn(3); Butterfly b = new Butterfly(5); u.meetsWith(b);
Overriding #
Terminology. A same instance method $m$ can be declared in a class $C$ and a subclass $S$ or $C$. In this case, we say that $S$ overrides $m$.
When such a method is called, the most specific applicable version is executed.
Example (continued). Let us extend our example with an instance method
learn, declared in bothNPCandMobileNPC, as follows:
public abstract class NPC { int xp; ... public void learn(){ if(xp < 10){ xp += 2; } } }$\qquad$
public abstract class MobileNPC extends NPC { ... public void learn (){ if(xp < 10){ xp += 2; } xp += 1; } }The following increases the XP of (the object referenced by)
uby3, becauseUnicornis a subclass ofMobileNPC.Unicorn u = new Unicorn(3); u.learn(); // the implementation of `MobileNPC` is executedIn contrast, the following increases the XP of (the object referenced by)
fby2, becauseFloweris a subclass ofNPC, but not a subclass ofMobileNPC.Flower f = new Flower(); f.learn(); // the implementation of `NPC` is executed
Syntax. We can use the annotation
@Overrideto indicate an overriding method, as follows:public abstract class MobileNPC extends NPC { ... @Override public void learn(){ if(xp < 10){ xp += 2; } xp += 1; } }This is not necessary, but considered good practice.
A benefit is that the program will not compile if the overridden and overriding methods have different signatures.
Dynamic dispatch (a.k.a. runtime polymorphism) #
Dynamic dispatch determines at run time which version of a method must be executed, if this cannot be determined by the compiler. This is a feature of most (class-based) object-oriented languages.
Example (continued). Assume a method
generateRandomNPCsthat generates a random array of NPCs (butterflies, unicorns or flowers).Then call the method
learnfor each NPC in such an array:NPC[] ramdomNPCs = generateRandomNPCs(); for (NPC c: randomNPCs){ c.learn(); }The most specific applicable version of the method
learnwill be executed for each NPC, based on its type, even though this type cannot be determined at compile time.For instance, if the array contains an instance of
Unicorn, then the methodMobileNPC.learn()will be executed for it (rather than the methodNPC.learn()).
Code factorization #
An overriding method often extends the functionality of the overridden one. This is a possible source of duplicate code.
Example (continued). Both implementations of
learn()contain:if(xp < 10){ xp += 2; }
A common way to factorize this consists in calling the overridden method inside the overriding one.
Syntax. The keyword
super(seen earlier for constructors) lets us to distinguish an overridden method from an overriding one (since they have the same name).
Example (continued). We can avoid duplicate code in the overriding method, as follows:
public abstract class MobileNPC extends NPC { ... @Override public void learn() { super.learn(); xp += 1; } }
In this example, what would be the effect of replacing super.learn() with learn()?
Extend our model with a method that lets an NPC spy on an NPC, such that:
- the spying NPC gains the XP of the one being spied on,
- a flower cannot be spied on, and
- when spying, a butterfly also gets to learn (by executing the method
learn()).