Named Inheritance

Research: This page describes research about Eiffel, not the actual language specification.

Motivation:

  • Remove the need for adapter classes.
  • Reconcile the relatively loose conventions around agents in to the more strict conventions of inheritance.

Similarity between adapter classes and agents


Take the starting classes A and B:

class A
feature
process_1
do
 -- Operate on value_1
end
value_1: INTEGER
test_1: BOOLEAN
process_2
do
 -- Different operation on value_2
end
value_2: INTEGER
test_2: BOOLEAN
end
deferred class B
feature
process
deferred
end
value: INTEGER
deferred
end
test: BOOLEAN
deferred
end
end

And adapters C and D:

class C
inherit
B
feature
make (sourceA: A)
do
source := sourceA
end
source: A
process
do
source.process_1
end
value: INTEGER
do
result := source.process_1
end
test: INTEGER
do
result := source.test_1
end
end
class D
inherit
B
feature
make (sourceA: A)
do
source := sourceA
end
source: A
process
do
source.process_2
end
value: INTEGER
do
result := source.value_2
end
test: BOOLEAN
do
result := source.test_2
end
end

Using these adapters, if A wanted to provide clients access to itself in 2 different ways through B, the following features could be added to A:

class A
--Same features as above--
feature
one: B
do
result := create {C}.make (current)
end
two: B
do
result := create {D}.make (current)
end
end

Another way A could provide access to itself similar to B is by use of agents:

class A
--Same features as above--
feature
one: TUPLE [process: PROCEDURE [ANY, []], value: FUNCTION[ANY, [], INTEGER], test: FUNCTION[ANY, [], BOOLEAN]]
do
result.process := agent process_1
result.value := agent value_1
result.test := agent test_1
end
two: TUPLE [process: PROCEDURE [ANY, []], value: FUNCTION[ANY, [], INTEGER], test: FUNCTION[ANY, [], BOOLEAN]]
do
result.process := agent process_2
result.value := agent value_2
result.test := agent test_2
end
end

Disadvantages of adapters:

  • Requires 1 new class for every way a class wishes to provide facilities to clients.

Disadvantages of agents:

  • Requires a new, though already implemented, language construct `agents'.
  • Strongly typed contracts related to agents are not defined.

Implementation of A using named inheritance:


class A
inherit
one: B
rename
process as process_1,
value as value_1,
test as test_1
end
two: B
rename
process as process_2,
value as value_2,
test as test_2
end
feature
process_1
do
 -- Operate on value_1
end
value_1: INTEGER
test_1: BOOLEAN
process_2
do
 -- Different operation on value_2
end
value_2: INTEGER
test_2: BOOLEAN
end

A client of A could make use of the named inheritance functionality as such:

class APPLICATION
feature
make
local
obj: A
one: B
two: B
do
create obj
one := obj.one
two := obj.two
end
end