Inheritance Questions
Frank Salter <[email protected]>
| Newsgroups | gmane.comp.lang.eiffel.smalleiffel |
|---|---|
| Message-ID | <[email protected]> |
I would like to ask you to examine the following facts and consider
their implications.
The following program compiles correctly and produces the expected output.
=========================================================
class TEST
creation program
feature
program
is
do
create staff.make;
staff.add_last(create {EMPLOYEE}.with_salary(25000));
staff.add_last(create {EMPLOYEE}.with_salary(22500));
staff.add_last(create {EMPLOYEE}.with_salary(20000));
staff.do_all(agent show_employee(?));
std_output.put_real_format(staff.salary_bill, 2);
std_output.put_new_line;
end
staff : STAFF_LIST;
show_employee (e : EMPLOYEE)
is
do
std_output.put_integer(e.staff_number);
std_output.put_new_line;
end
end
class EMPLOYEE
creation {TEST} with_salary
feature {TEST}
with_salary (initial_salary : like salary)
is
do
staff_number_allocator.increment;
staff_number := staff_number_allocator.value
salary := initial_salary;
end
staff_number : INTEGER;
feature {TEST, STAFF_LIST}
salary : REAL;
feature {NONE}
staff_number_allocator : COUNTER is once create Result; end
end
class STAFF_LIST
inherit LINKED_LIST[EMPLOYEE]
creation make
feature {TEST}
salary_bill : REAL
is
local employees : ITERATOR[EMPLOYEE];
do
from employees := get_new_iterator;
until employees.is_off
loop
Result := Result + employees.item.salary;
employees.next;
end
end
end
---------------------------------------------------------------------------------------------
1
2
3
67500.00
==============================================================
If the class STAFF_LIST attempts to "insert" rather than "inherit" the
LINKED_LIST, the program fails to compile with the following message:
compile test -o test
****** Fatal Error: Cannot pass `other' which is of type STAFF_LIST
into formal type COLLECTION[EMPLOYEE].
Line 190 column 20 in LINKED_LIST (/opt/SmartEiffel/lib/storage/collection/linked_list.e):
from_collection(other)
^
Line 284 column 26 in LINKED_LIST (/opt/SmartEiffel/lib/storage/collection/linked_list.e):
from_collection (model: COLLECTION[like item]) is
^
------
File "test.make" not found. Error(s) during `compile_to_c'.
Compilation exited abnormally with code 1 at Thu Apr 14 09:13:29
==============================================================
Now if the following export clause is applied to the inherited
LINKED_LIST then the compiler produces 69 messages. This
output is elided as all the messages are similar and originate in the
library classes.
export {COLLECTION, GENERAL, LINKED_LIST, NONE} all;
{LINKED_LIST, TEST} make, add_last, do_all
end
----------------------------------------------------------------------------------------------
compile test -o test
****** Warning: The client list computed from the "export" clauses
is narrower than the one from the conforming parent(s). This can
lead to catcalls! The final export list is {COLLECTION, GENERAL,
LINKED_LIST, NONE} .
Line 96 column 9 in COLLECTION (/opt/SmartEiffel/lib/storage/collection.e):
feature {ANY} -- Writing:
^
Line 107 column 2 in COLLECTION (/opt/SmartEiffel/lib/storage/collection.e):
swap (i1, i2: INTEGER) is
^
Line 3 column 21 in STAFF_LIST (/home/.../staff_list.e):
export {COLLECTION, GENERAL, LINKED_LIST, NONE} all;
^
------
...
...
****** Warning: The client list computed from the "export" clauses
is narrower than the one from the conforming parent(s). This can
lead to catcalls! The final export list is {COLLECTION, GENERAL,
LINKED_LIST, NONE} .
Line 122 column 9 in GENERAL (/opt/SmartEiffel/lib/kernel/general.e):
feature {ANY} -- Basic operations:
^
Line 130 column 2 in GENERAL (/opt/SmartEiffel/lib/kernel/general.e):
is_default: BOOLEAN is
^
Line 3 column 21 in STAFF_LIST (/home/.../staff_list.e):
export {COLLECTION, GENERAL, LINKED_LIST, NONE} all;
^
------
****** 69 warnings.
Compilation finished at Thu Apr 14 09:02:17
==============================================================
Quite clearly there are many other ways in which the functionality of
the above program code could be achieved. Many of these would avoid
the difficulties I am considering as they seem to indicate that further
thinking is required.
Working program
demonstrates that the basic functionality is valid.
Version with "insert"
From a SmartEiffel programmers point of view, should the version
using "insert" also be expected to be valid? The errors would then be
seen as a library implementation problem, rather than a problem with
inheritance?
Version with the export clause
The export clause is clearly intended to restrict access to the
features of the STAFF_LIST and would appear to be a perfectly desirable
method of re-using existing classes. Imagine using this technique in a
substantial program in which it occurs frequently. Any warnings about
the actual programmer's code would be swamped in these messages!
So I would like to pose the following questions particularly to the
theorists.
Does the above demonstrate a missing Eiffel inheritance
facility akin to "inherit" and "insert"?
As the above seeks to impose restrictions on the inheritance,
would the use of a further facility
such as "restrict" improve the ability of a compiler to work.
Regards
Frank Salter