2cpp12 - method overriding
DESCRIPTION
This is an intermediate conversion course for C++, suitable for second year computing students who may have learned Java or another language in first year.TRANSCRIPT
METHOD OVERRIDINGMichael Heron
Introduction• In the last lecture we talked about method overloading.• In this one we are going to talk about method overriding.
• The two are often confused, but are entirely different systems.
• One is based on the idea of unique identification of methods.
• The other is based on being able to specialise behaviours through inheritance.
Method Overriding• When we override a method, we specialise it as the child
class as part of an inherited relationship.• The usual rules of virtual functions apply here for C++.
• Usually what we do here is subtly alter the functionality and then pass the results of our specialisation onto the parent method.
Method Overriding• The chain of invocation for a method in C++ depends on
its virtuality.• If it is not virtual, the base method gets called always.• If it is virtual, the most specialised implementation gets called.
• For virtual methods, we then have control over the chain of invocation.• We can decide how invocations filter up and down the chain.
The Chain of Invocation• This is a fancy way of saying ‘which functions get
executed when’.• A well over-ridden function will tend to pass function calls back onto
their parent classes.
• There is nothing to stop you entirely handling a function in the most specialised instance.• It’s generally not very good design.
• Violates the principles of encapsulation.
Employee (Base Class)
class Employee {private: int payscale;public: int query_payscale(); void set_payscale (int p); virtual bool can_hire_and_fire(); virtual bool has_authority (string);};
bool Employee::has_authority (string action) { if (action == "work") { return true; } return false;}
Clerical (Derived Class)class Clerical: public Employee {public: bool can_hire_and_fire(); void file_papers(); bool has_authority(string str);};
bool Clerical::has_authority (string action) { if (action == "paperwork") { return true; }
return Employee::has_authority (action);}
Manager (Derived Class)class Manager : public Employee {public: bool can_hire_and_fire(); bool has_authority (string);};
bool Manager::has_authority (string action) { if (action == "managing") { return true; } return Employee::has_authority (action);}
Main Programint main(int argc, char** argv) {
Employee *cler = new Clerical(); Employee *man = new Manager(); string actions[3] = {"paperwork", "work", "managing"};
for (int i = 0; i < 3; i++) { cout << "Managers authority for " << actions[i] << " " << man->has_authority (actions[i]) << endl; cout << "Clerical authority for " << actions[i] << " " << cler->has_authority (actions[i]) << endl; }}
Overriding in Java• Java provides a special keyword, super to refer to a
parent class.• C++ offers no equivalent due to its support of multiple inheritance.
• Otherwise works identically:• return super.has_authority (action);
• Overriding simplified by virtue of no virtual functions.
Notes on the Chain• No need for parent classes to define the method.
• Will be passed back up to the most specialised parent that does.
• Scope resolution is used to redirect function calls to parent classes.• You can bypass parents if you like, but this is not good practise.
Overriding and Encapsulation• Does overriding break encapsulation?
• Some say it does, and that child classes should not make calls to parent classes in this way.
• Inheritance is about specialisation.• Not replacement.
• Properly used, over-riding enhances encapsulation.• We don’t need to worry about how our methods will be interpreted,
just that they will be.
Overloading versus Overriding• Overriding only works as a mechanism of inheritance.
• You can only override a parent’s implementation.• You can’t override a method in the class in which it is defined.
• Overloading can work in conjunction with overriding.• The has_authority method we are using is overridden.• We could provide a second syntax for that that would be
overloaded.• This has implications for clean object design.
Common Overriding Errors• Mis-spelled function names
• Won’t be picked up when invoked.
• Mismatched parameter lists• Will overload rather than override.
• Failing to maintain the chain of invocation.• Make sure you always pass it on.• Make sure you always pass it on correctly.
• One of the things that super does is resolve to the parent class without you needing to specify it.
• If you change an inherit chain in C++, you also need to update all references.
Why Override Functions?• Information hiding ensures we don’t have access to
private data fields.• In many cases, we simply can’t configure objects without
overriding.
• No need to excessively duplicate functionality.• We handle what is new, and let the parent class handle the rest.
• Properly distributes authority through an object inheritance chain.
Binding and Polymorphism• All of this is made possible through the use of inheritance
and polymorphism.• It’s worth spending a few minutes talking about how this is
actually done.• C++ makes a distinction between the static type of an
object and its dynamic type.• Shape *myShape = new Circle();
• myShape has a static type of Shape• myShape has a dynamic type of Circle
Binding and Polymorphism• The static type is determined at compile time.• The dynamic type is determined at run-time.
• And it is determined on an ongoing basis.• This process is known as dynamic binding.
• Dynamic binding has a toll.• Virtual function lookups at runtime are expensive.• Virtual functions must be placed and maintained in a virtual
function table.
• Static binding is used for functions that are not virtual.• The function to be executed is decided at compile time and is not
changed.
Binding Styles• There is a trade-off between static and dynamic.
• Java makes all methods virtual by default.
• Static binding is more efficient.• The compiler can do all sorts of tricks to make it work more
efficiently.
• Dynamic binding is more flexible.• The interface is consistent but the implementation will change.
Static Methods in Java• Static methods in Java are the Java implementation of
static binding.• Static binding is used for static method calls.
• This is why Java has problems with people calling non-static methods from static contexts.• The non-static method is virtual.• The static method is static.
• You can’t even override a static method in Java.
Summary• Overriding is separate and distinct from overloading.
• Overloading is in addition• Overriding is instead of
• Maintaining the chain of invocation is important.• Overriding is predicated on effective use of inheritance
and polymorphism.