Exercise 6 Multiple Inheritance, Multiple Dispatch and Linearization November 3, 2017

Similar documents
Exercise 6 Multiple Inheritance, Multiple Dispatch and Linearization November 4, 2016

Exercise 6 Multiple Inheritance, Multiple Dispatch and Linearization November 3, 2017

Last name:... First name:... Department (if not D-INFK):...

Exam Duration: 2hrs and 30min Software Design

ECE 461 Fall 2011, Final Exam

Practice for Chapter 11

Exercise 8 Parametric polymorphism November 18, 2016

Outline. Java Models for variables Types and type checking, type safety Interpretation vs. compilation. Reasoning about code. CSCI 2600 Spring

HAS-A Relationship. Association is a relationship where all objects have their own lifecycle and there is no owner.

INSTRUCTIONS TO CANDIDATES

Advanced Systems Programming

Fall CS 101: Test 2 Name UVA ID. Grading. Page 1 / 4. Page3 / 20. Page 4 / 13. Page 5 / 10. Page 6 / 26. Page 7 / 17.

Rules and syntax for inheritance. The boring stuff

Exercise 3 Subtyping and Behavioral Subtyping October 13, 2017

Compiler Errors. Flash CS4 Professional ActionScript 3.0 Language Reference. 1 of 18 9/6/2010 9:40 PM

HAS-A Relationship. Association is a relationship where all objects have their own lifecycle and there is no owner.

17 Multiple Inheritance and ADT Extensions

Overview. Elements of Programming Languages. Objects. Self-Reference

CIS 120 Final Exam 15 December 2017

Lesson 10A OOP Fundamentals. By John B. Owen All rights reserved 2011, revised 2014

Exercise 9 Parametric Polymorphism and Information Hiding November 24, 2017

Exercise: Singleton 1

The Notion of a Class and Some Other Key Ideas (contd.) Questions:

Why use inheritance? The most important slide of the lecture. Programming in C++ Reasons for Inheritance (revision) Inheritance in C++

Java Object Oriented Design. CSC207 Fall 2014

Prelim 1. CS 2110, 13 March 2018, 5:30 PM Total Question Name Short answer

Last name:... First name:... Department (if not D-INFK):...

Overview. Elements of Programming Languages. Objects. Self-Reference

More Relationships Between Classes

JAVA OPERATORS GENERAL

Inheritance and Interfaces

OOPs Concepts. 1. Data Hiding 2. Encapsulation 3. Abstraction 4. Is-A Relationship 5. Method Signature 6. Polymorphism 7. Constructors 8.

More on Objects in JAVA TM

Contents. I. Classes, Superclasses, and Subclasses. Topic 04 - Inheritance

CS 231 Data Structures and Algorithms, Fall 2016

Class, Variable, Constructor, Object, Method Questions

The software crisis. code reuse: The practice of writing program code once and using it in many contexts.

16 Multiple Inheritance and Extending ADTs

CS201- Introduction to Programming Current Quizzes

University of Palestine. Mid Exam Total Grade: 100

Big software. code reuse: The practice of writing program code once and using it in many contexts.

Practice Questions for Final Exam: Advanced Java Concepts + Additional Questions from Earlier Parts of the Course

COMP322 - Introduction to C++ Lecture 09 - Inheritance continued

Inheritance (Part 2) Notes Chapter 6

Argument Passing All primitive data types (int etc.) are passed by value and all reference types (arrays, strings, objects) are used through refs.

CSCI-GA Final Exam

Instance Members and Static Members

The software crisis. code reuse: The practice of writing program code once and using it in many contexts.

15 Multiple Inheritance and Traits

Programming in C++: Assignment Week 6

PROGRAMMING LANGUAGE 2

Day 4. COMP1006/1406 Summer M. Jason Hinek Carleton University

Chapter 8 ( ) Control Abstraction. Subprograms Issues related to subprograms How is control transferred to & from the subprogram?

Type Hierarchy. Lecture 6: OOP, autumn 2003

Compiler construction 2009

Making New instances of Classes

1. Which of the following is the correct expression of character 4? a. 4 b. "4" c. '\0004' d. '4'

CSE 331 Summer 2017 Final Exam. The exam is closed book and closed electronics. One page of notes is allowed.

CSE351 Winter 2016, Final Examination March 16, 2016

Java Simple Data Types

5.6.1 The Special Variable this

Binghamton University. CS-140 Fall Dynamic Types

Inheritance. Unit 8. Summary. 8.1 Inheritance. 8.2 Inheritance: example. Inheritance Overriding of methods and polymorphism The class Object

FAQ: Classes & Objects

CIS 120 Midterm II November 8, Name (printed): Pennkey (login id):

Inheritance (Part 5) Odds and ends

COMP322 - Introduction to C++

CS1622. Semantic Analysis. The Compiler So Far. Lecture 15 Semantic Analysis. How to build symbol tables How to use them to find

CMSC 132: Object-Oriented Programming II

Java Simple Data Types

Lecture 3. COMP1006/1406 (the Java course) Summer M. Jason Hinek Carleton University

Conversions and Overloading : Overloading

Type Hierarchy. Comp-303 : Programming Techniques Lecture 9. Alexandre Denault Computer Science McGill University Winter 2004

ECE 462 Fall 2011, Second Exam

Java provides a rich set of operators to manipulate variables. We can divide all the Java operators into the following groups:

Graphical Interface and Application (I3305) Semester: 1 Academic Year: 2017/2018 Dr Antoun Yaacoub

First IS-A Relationship: Inheritance

Chapter 12: Inheritance

8 Understanding Subtyping

C++ Inheritance and Encapsulation

CSE115 / CSE503 Introduction to Computer Science I. Dr. Carl Alphonce 343 Davis Hall Office hours:

Generic programming POLYMORPHISM 10/25/13

Final CSE 131 Fall 2014

Kapil Sehgal PGT Computer. Science Ankleshwar Gujarat Chapter 6 Inheritance Extending a Class

CMSC131. Inheritance. Object. When we talked about Object, I mentioned that all Java classes are "built" on top of that.

Unit3: Java in the large. Prepared by: Dr. Abdallah Mohamed, AOU-KW

Exercise 12 Initialization December 15, 2017

CSE341: Programming Languages Lecture 11 Type Inference. Dan Grossman Spring 2016

ECE Fall 2014, Final Exam

Data Abstraction. Hwansoo Han

Software Engineering Design & Construction

Lesson 36: for() Loops (W11D1)

Inheritance, and Polymorphism.

CIS 120 Midterm II November 8, 2013 SOLUTIONS

Final exam. Final exam will be 12 problems, drop any 2. Cumulative up to and including week 14 (emphasis on weeks 9-14: classes & pointers)

COMPUTER SCIENCE DEPARTMENT PICNIC. Operations. Push the power button and hold. Once the light begins blinking, enter the room code

CS152: Programming Languages. Lecture 23 Advanced Concepts in Object-Oriented Programming. Dan Grossman Spring 2011

Exercise 13 Self-Study Exercise Sheet

Example: Count of Points

PIC 10A Objects/Classes

Transcription:

Concepts of Object-Oriented Programming AS 2017 Exercise 6 Multiple Inheritance, Multiple Dispatch and Linearization November 3, 2017 Task 1 (from a previous exam) Consider the following C++ program: class X X(int p) : fx(p) int fx; ; class Y Y(int p) : fy(p) int fy; ; class B : public virtual X,public Y B(int p) : X(p-1),Y(p-2) ; class C : public virtual X,public Y C(int p) : X(p+1),Y(p+1) ; class D : public B, public C D(int p) : X(p-1), B(p-2), C(p+1) ; int main() D* d = new D(5); B* b = d; C* c = d; std::cout << b->fx << b->fy << c->fx << c->fy; return 0; What is the output of running the program? (a) 5555 (b) 2177 (c) CORRECT: 4147 (d) 7177 (e) 7777

(f) None of the above Task 2 Consider the following C++ code: class Person Person *spouse; string name; Person (string n) name = n; spouse = nullptr; bool marry (Person *p) if (p == this) return false; spouse = p; if (p) p->spouse = this; return true; ; Person *getspouse () return spouse; string getname () return name; The method marry is supposed to ensure that a person cannot marry him-/herself. Without changing the code above, create a new object that belongs to a subclass of Person and marry it with itself. Hint: use multiple inheritance. Explain exactly what happens. The following C++ code breaks the invariant: class B : public Person B (string n) : Person (n) ; class C : public Person C (string n) : Person (n) ; class D : public B, public C D (string n) : B(n), C(n) ; void marrymyself () D me ("Me"); B *b = &me; C *c = &me; b->marry (c); if (b->getspouse ()) cout << b->getspouse ()->getname (); The object me contains an object of class B and an object of class C. The addresses of these objects are different and they are obtained using the assignments to b and c respectively. During the call b->marry(c), the condition p == this compares these two addresses and finds them not equal. Task 3 (from a previous exam) Consider the following Java classes:

class A public void foo (Object o) System.out.println("A"); class B public void foo (String o) System.out.println("B"); class C extends A public void foo (String s) System.out.println("C"); class D extends B public void foo (Object o) System.out.println("D"); class Main public static void main(string[] args) A a = new C(); a.foo("java"); C c = new C(); c.foo("java"); B b = new D(); b.foo("java"); D d = new D(); d.foo("java"); What is the output of the execution of the method main in class Main? (a) The code will print A C B D (b) CORRECT: The code will print A C B B (c) The code will print C C B B (d) The code will print C C B D (e) None of the above Task 4 Consider the following C# classes: public class Matrix public virtual Matrix add(matrix other) Console.WriteLine("Matrix/Matrix"); return null; public class SparseMatrix : Matrix public virtual SparseMatrix add(sparsematrix other) Console.WriteLine("SparseMatrix/SparseMatrix"); return null; public class MainClass public static void Main(string[] args) Matrix m = new Matrix(); Matrix s = new SparseMatrix(); add(m,m); add(m,s);

add(s,m); add(s,s); public static Matrix add(matrix m1, Matrix m2) return m1.add(m2); A) What is the output of this program? Please explain. The output is: Matrix/Matrix Matrix/Matrix Matrix/Matrix Matrix/Matrix In each case, C# statically chooses a method variant based on the static type of the receiver. This is only add(matrix other). Then at run-time, it will call the most-derived override of this method. However, because C# method arguments are invariant, add( SparseMatrix other) is not an override and we always end up calling the method from Matrix. B) Without breaking modularity, change only the body of MainClass.add to make it possible to always call the most specific add method from the matrix hierarchy. We could change MainClass to the following: public static Matrix add(matrix m1, Matrix m2) return (m1 as dynamic).add(m2 as dynamic); Now, the initial lookup for a method variant is also done at run-time, based not on the static, but on the dynamic type of the receiver. Thus in the third and fourth case there will be a choice between the two different add methods in class SparseMatrix. To also enable a dynamic look-up of the most-specific method based on the argument types, we additionally cast the argument as dynamic. Task 5 Java 8 allows interface methods to have a default implementation directly in the interface. A) What are some advantages of this feature? An advantage is obviously that default implementations can be reused in multiple classes. Another advantage (and the main reason this feature is added to Java) is that default method implementations will allow interface evolution. Without a default implementation,

adding new methods to an interface would break all existing classes that implement that interface, since they do not contain an implementation for the new methods. The new features removes this problem. B) What could be some problems with this feature? How can they be resolved? A problem could be inheriting two default implementations of the same method from unrelated interfaces. In that case we will have to either choose which implementation we prefer or write a new implementation that overrides both. Another issue is that interfaces can now suffer from the fragile base class problem. Compared to the usual issue with normal Java classes, this is even more dangerous for interfaces with default methods, since these methods will mostly call other methods of the interface which are overriden in implementing classes. A very restrictive here could be to prohibit calls to other methods of the interface, within the implementation of default methods. Alternatively we can deal with the problem just like Java deals with the issue in classes - do nothing and rely on the programmer to be careful. C) What problems of C++ multiple inheritance are avoided by this new design for Java interfaces? We still avoid problems with correct initialization of fields of super types, since only one super type (the extended class) can have fields, and we can directly call its constructor. Furthermore there are no problems with field duplication as in non-virtual C++ inheritance. D) Now suppose that, in addition to method implementations, Java also allowed interfaces to define fields. Interfaces would not have constructors and interface fields would always be initialized with a default value. This makes multiple inheritance in Java very similar to C++. What are some advantages of this feature? An advantage is that we can also reuse fields. This will enable more methods with default implementations in interfaces which could increase code reuse and reduce the effort required to create new classes. Given the restrictions above, are there any problems left with such an implementation of multiple inheritance? If so what are they? Propose a for each problem you have identified. These restrictions are somewhat similar to Scala traits, which also do not have specialized constructors (only a default constructor). In this way we manage to avoid

problems with initialization order. However a problem that still remains is: how many copies of a field exist? In particular: A class might implement the same interface multiple times (for example by implementing two different interfaces that are a subtype of the same interface). A here might be to only have a single copy of the field (as in C++ virtual inheritance). A class might implement two different interfaces that both declare the same field. Here we could either restrict interfaces to defining only private fields (which are invisible to the implementor), or we could require some disambiguation syntax when accessing fields, similar to C++ or the proposed syntax for disambiguating conflicting default methods in Java 8. Task 6 Consider the following declarations in Scala: class C trait T extends C trait U extends C class D extends C Find all the types that can be created with or without traits, as well as the subtype relations between them. Let X, Y be the two base classes from which we derive X and Y by mixing in traits. Let A be the set of all traits mixed in to the first class and B the set of all traits mixed in to the second class. The rule is as follows: X <: Y if and only if X <: Y and A B. Note: The above rule applies in our example, but it is not a general rule for subtyping in the presence of traits. Notice that D with T with U and D with U with T are equivalent types (subtypes of each other)! Since, as we saw, they can describe different behavior, this causes a subtle problem for behavioral subtyping! Task 7 Consider the following Scala code: class Cell private var x:int = 0 def get() = x def set(i:int) = x=i trait Doubling extends Cell override def set(i:int) = super.set(2*i) trait Incrementing extends Cell

override def set(i:int) = super.set(i+1) A) What is the difference between the following objects? val a = new Cell val b = new Cell with Incrementing val c = new Cell with Incrementing with Doubling val d = new Cell with Doubling with Incrementing Object a behaves like a normal cell. Object b is also a cell, but it increases the stored value by 1. The interesting difference is between c and d. They are both cells. They have mixed in exactly the same traits. However, calling set(i) has a different effect on them: it stores 2i+1 to the first one and 2(i+1) to the second one. B) We use the following code to implement a cell that stores the argument of the set method multiplied by four: val e = new Cell with Doubling with Doubling Why doesn t it work? What does it do? How can we make it work? Trait Doubling will not get mixed in twice, as perhaps the programmer would expect. Scala rejects this statically. The problem can be bypassed in an ugly way, by creating a new trait Doubling2 that behaves exactly like Doubling and then introducing e = new Cell with Doubling with Doubling2. Here is our first try: trait Doubling2 extends Doubling val e = new Cell with Doubling with Doubling2 The code passes through, but dynamically e behaves as if it were a Cell with Doubling. Scala lets the code go through, because Doubling2 may introduce new functionalities, but refuses to include Doubling twice in the linearization. Our last try, the ugliest of all, but the one which will finally work, is to create a whole new trait from scratch, reusing nothing: trait Doubling3 extends Cell override def set(i:int) = super.set(2*i) val e = new Cell with Doubling with Doubling3 And now e.set quadruples its argument as expected. C) Find a modularity problem in the above, or a similar, situation. Hint: a client that gets given a class C does not necessarily know if a trait T has been mixed in that class.

A problem is that a method that accepts Cell with Doubling with Incrementing as an argument could also be passed a class of the type Cell with Incrementing with Doubling - so what it can actually assume about its inputs is less than would be expected. D) We propose the following to support traits together with behavioral subtyping: Assume C is a class with specification S. Each time we create a new trait T that extends C, we must ensure that C with T also satisfies S. Show a counterexample that demonstrates that this approach does not work. Consider the following example: class C var x:int; def foo() = //ensures true trait T1 extends C override foo() = x=x+1 //ensures x>old(x) trait T2 extends C override foo() = x=x-1 //ensures x<old(x) Both C with T1 and C with T2 are behavioral subtypes of C. But C with T1 with T2 is not a behavioral subtype of C with T1. Task 8 (from a previous exam) Consider the following Scala code: class A def bar() = "" trait B extends A override def bar() = super.bar()+"b" trait C extends B override def bar() = super.bar()+"c" trait D extends B override def bar() = super.bar()+"d" object Main def main() foo(new A with D with C with B()) def foo(x:a with D) println(x.bar()) What would be the output of the call Main.main()? (a) BDB (b) BBDBC (c) BBCBD

(d) DB (e) CORRECT: BDC (f) BCD (g) None of the above Task 9 (from a previous exam) Consider the following C++ code (recall that default constructors, i.e., constructors without arguments, do not need to be called explicitly in C++): class A A(int i) std::cout << "A" << i; A() std::cout << "A1"; virtual int get()... ; class B: MODIFIER A B(int i) : A(i) std::cout << "B" << i; ; class C: MODIFIER A C(int i) : A(i) std::cout << "C" << i; ; class D: public B, public C D(int i) : B(i + 10), C(i + 20) std::cout << "D" << i; ; Now assume that MODIFIER is replaced by public. A) Why does the following client code not compile? void client() D* d = new D(5); std::cout << d->get(); The call d->get() is ambiguous because class D inherits two versions of A (and therefore of get()), one from B and one from C. B) Add a method to one of the classes so that client compiles. We can resolve the ambiguity by overriding get in class D, for example to return B::get() or any other integer value. The resulting code looks as follows: class D: public B, public C...

; virtual int get() return B::get(); C) What is the output resulting from the call new D(5) in method client? The code outputs A15 B15 A25 C25 D5 (without whitespace). D) Now, assume that MODIFIER is replaced by public virtual. What is the new output resulting from the call new D(5) in method client? The code outputs A1 B15 C25 D5 (without whitespace).