NivaarExam PrepOfficial exam papers ↗

19-Soft-B17 Data Visualization · December 2014

Question 4 of 10

Nivaar worked solution (AI-drafted; not reviewed by a licensed engineer)

Notes on this paper

04-Soft-B17, Programming Language Paradigm — National Exams, December 2014 (3 hours, open book, 10 questions of equal value, essay-format answers).

Reference texts: Sebesta, Concepts of Programming Languages, 12th ed. (object-oriented language design, subtyping, functional programming, exception handling, lambda expressions); Sommerville, Software Engineering, 10th ed. (object-oriented design, modularity); Gamma et al. (GoF), Design Patterns, 1st ed. (composition-over-inheritance, Liskov Substitution Principle in practice).

Check: this paper's printed course title and all ten questions are exclusively about object-oriented and functional programming-language concepts (classes, subtyping, overriding/overloading, exceptions, functional vs. procedural style, actor model, lambda expressions, immutability) — there is no data-visualization content anywhere in the paper. This solution follows the exam as printed ("04-SOFT-B17: Programming Language Paradigm").

Question 4 (10%)

Question text not reproduced: the examination questions are © Engineers and Geoscientists BC. Open the official past paper (linked at the top of this page) to read the question, then follow the worked solution below.

Method overriding occurs when a subclass provides a new implementation for a method that is already defined, with the identical signature (same name, same parameter types and count, compatible return type), in one of its superclasses. Which implementation actually runs is resolved at run time, based on the actual (dynamic) type of the object the method is called on, regardless of the declared (static) type of the reference used to call it — this is dynamic dispatch, and it is the mechanism that makes runtime polymorphism possible: code written against a base-class reference automatically picks up whichever subclass's behaviour the actual object provides. Method overloading, by contrast, occurs when a single class (or a class and its superclass together) declares multiple methods that share the same name but differ in their parameter lists (different number, order, or types of parameters). Which overload is invoked is resolved at compile time, purely from the static types of the arguments supplied at the call site — there is no run-time decision involved, and the return type alone is not enough to distinguish overloads in most languages.

A concrete example makes the distinction sharp. Consider a base class Shape with a method double area(), and a subclass Circle extends Shape that also declares double area() with the exact same signature but computes πr² instead of the base class's default (say, zero). This is overriding: given Shape s = new Circle(3);, the call s.area() invokes Circle's implementation at run time, even though the compile-time type of s is Shape — the object's actual (dynamic) type governs. Now consider the same Shape class declaring two different methods both named resize: void resize(double factor) and void resize(double newWidth, double newHeight). This is overloading: calling shape.resize(2.0) versus shape.resize(4.0, 3.0) is decided purely by how many arguments (and of what type) are written at the call site, at compile time, with no relationship to inheritance or dynamic dispatch at all — indeed, a class need not have any subclasses whatsoever to use overloading.

The two mechanisms serve fundamentally different purposes: overriding supports polymorphism — "the same call, different behaviour depending on what kind of object you actually have" — while overloading supports convenience/readability — "the same conceptual operation, offered with several different parameter shapes so the caller can supply whichever inputs are most natural." A common point of confusion is that both let you call "the same-named method" and get different behaviour, but overriding depends on the receiver's run-time type while overloading depends only on the compile-time types of the arguments at the call site — which is also why overloading, unlike overriding, requires no inheritance relationship at all.