2CPP12 - Method Overriding

Post on 01-Nov-2014

72 views 2 download

Tags:

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 of 2CPP12 - Method Overriding

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.