IS A and HAS A relationships

60 views
Skip to first unread message

Mats Helander

unread,
Nov 17, 2001, 11:43:49 AM11/17/01
to
I have a question on IS A and HAS A relationships:

If a class "A" HAS A (sorry for the caps, don't mean to yell, but I'm under
the impression that's how you write'em relationships, yes?) class B, and it
declares that it "Implements" class B and then it delegates all the calls to
"Implemented" members in class A to the members of its instance of B (well,
static members would forward to class B, but you get what I mean,
right?)...Then, sure there was more work for me to obtain all this, but for
a user of my object A - will there be any "real" difference to if class A
had an IS A relationship to class B? I'm gathering that that the work
described above is more or less what the compiler does for you automagically
when you declare an IS A relationship...?

Sort of "academic" question, so I can't give you better example of the
programming situation I'll need to know about (don't have one) - so, if the
answere is so big that you would need to know that to answere me, suffice it
to say instead that there are indeed substantial differences...But of
course, I'll be glad to try to formulate my question more clearly if it was
muddy!

/Thanks in advance, Mats Helander


Scott W. Ambler

unread,
Nov 18, 2001, 8:36:47 AM11/18/01
to
If all that A does is delegate messages to B then the only difference is a
slight performance improvement from using inheritance (IS A) because you're
now directly invoking the operations on B instead of going through the
wrapper operations of A.

However, you never actually see such an extreme "pure wrapper" use of
aggregation (HAS A) so as you point out the question is sort of academic.
The important differences of inheritance and aggregation, assuming proper
application of them, focus on maintainability of your code.

- Scott
"Mats Helander" <ma...@urbantalk.se> wrote in message
news:3bf6...@news.wineasy.se...

Leonardo Azpurua

unread,
Nov 18, 2001, 2:06:00 PM11/18/01
to

<brou...@yahoo.com> escribió en el mensaje
news:esnfvt8dbuunbftuv...@4ax.com...

> "Mats Helander" <ma...@urbantalk.se> wrote:
>
> >Then, sure there was more work for me to obtain all this, but for
> >a user of my object A - will there be any "real" difference to if class A
> >had an IS A relationship to class B? I'm gathering that that the work
> >described above is more or less what the compiler does for you
automagically
> >when you declare an IS A relationship...?
>
> Inheritance (is-a) is more tightly coupling than containment (has-a).
> Coupling isn't necessarily a bad thing. But it can be. Most coding
> guidelines suggest to prefer solutions that are as loosely coupled as
> possible. In some situations, more coupling is desired. Just depends on
> the individual situation.

I perceive the "is-a" relation like a sort of definitory property of the
class. If classB "is-a" classA, then it has to implement all of the public
interface of a classA (in order to fulfill the Liskov Principle).

The has-a, on the other hand, simply states that a set of attributes of the
contained class, are available -either directly, by means of delegation- or
explicitly (i.e. instanceOfB.memberA.Property) to clientsof the container
class. Also, the "has-a" relation between an aggreted class and its members
might be exclusively private, thus belonging to the internal class
definition.

If a Class A is only a container of only one instance of ClassB,there is no
sense in the existence of ClassA (just ClassB is enough), unless it is a
generic container class, in which case the "hasA" relation is polymorphic.

"Is-a" is a concept relative to the subordinate class, while "has-a" belongs
to the definition of the parent class. They are concepts applicable to two
different categories.


Graham Perkins

unread,
Nov 19, 2001, 6:55:38 AM11/19/01
to

Mats Helander wrote:
>
> I have a question on IS A and HAS A relationships:
>
> If a class "A" HAS A (sorry for the caps, don't mean to yell, but I'm under
> the impression that's how you write'em relationships, yes?) class B, and it
> declares that it "Implements" class B and then it delegates all the calls to
> "Implemented" members in class A to the members of its instance of B (well,
> static members would forward to class B, but you get what I mean,
> right?)...Then, sure there was more work for me to obtain all this, but for
> a user of my object A - will there be any "real" difference to if class A
> had an IS A relationship to class B? I'm gathering that that the work
> described above is more or less what the compiler does for you automagically
> when you declare an IS A relationship...?

What you describe here is the Decorator Pattern. See "Design Patterns"
by Gamma, Helm, Johnson and Vlissides. The clients of A may as well be
clients of B except for the fact that they get a little extra
functionality
that you have put in A.

It is definitely NOT what the compiler does automagically when you
declare IS-A relationship. The crucial difference in IS-A is that your
new
class adds extra attributes and methods, all of which are present in the
same scope.

Under the scheme you mention, there are two separate scopes. The B and
A
instances cannot access or update each other's encapsulated parts. In
fact,
the B object can't get at anything at all in A unless you pass a ref to
A
across in all the calls from A to B. But that would require B to be
designed to handle A, even before A had been thought of.

-------------+ http:/www.gperkins.co.uk/

Mats Helander

unread,
Nov 19, 2001, 8:22:37 AM11/19/01
to
> What you describe here is the Decorator Pattern. See "Design Patterns"
> by Gamma, Helm, Johnson and Vlissides. The clients of A may as well be
> clients of B except for the fact that they get a little extra
> functionality
> that you have put in A.
>
> It is definitely NOT what the compiler does automagically when you
> declare IS-A relationship. The crucial difference in IS-A is that your
> new
> class adds extra attributes and methods, all of which are present in the
> same scope.
>
> Under the scheme you mention, there are two separate scopes. The B and
> A
> instances cannot access or update each other's encapsulated parts. In
> fact,
> the B object can't get at anything at all in A unless you pass a ref to
> A
> across in all the calls from A to B. But that would require B to be
> designed to handle A, even before A had been thought of.
>
I must have gotten something very seriously wrong...

I thought an instance of the subclass and the instance of its superclass
did -not- share scope. Private members are not inherited and can be declared
again in the subclass with no conflict, right?

Let's say B is the superclass of A, and that B has a private method called
"testMe()". Now, if I add a method "testMe()" to the subclass A, then I
wouldn't actually be overriding the "testMe()" member of A, since only
public members are inherited, yes?
And if I don't inherit it, I can't access it via "super.testMe()", right?

And if I override a public member, I can still call the original via
'super', yes?

And the 'super', in it's turn, will have no way of accessing the members of
the "subobject", just like you correctly observe will be the case in my
scheme...All of this is, in my book, the same as saying that they do not
share scope...

What am I missing???

/Best Regards, Mats Helander


John A. Byerly

unread,
Nov 19, 2001, 10:35:02 AM11/19/01
to
"Mats Helander" <ma...@urbantalk.se> wrote in message
news:3bf6...@news.wineasy.se...


No offence, but I was having trouble following your question. So if this
answer does not appear to be appropriate, feel free to ignore it!

The is-a relationship is one in which one object can be treated as another.
After all, if B is-a A, when you need an A, supplying an B should be
acceptable. For instance, if I have a Printer class, I can say that a
Lexmark is-a Printer. Any function that needs to operate on a Printer will
accept a Lexmark with no problem.

The has-a relationship simply means that one object needs to access another.
If the relationship between A and B is simply that A delegates to B, this
certainly could be a has-a relationship. Of course, there are degress of
has-a as well. For instance, does A _own_ B, or does it just have a
reference to B? In other words, should B cease to exist when A is
destroyed? If so, then A owns B, otherwise, A just has a reference to B.
But A owning B does not mean that B is-a A.

The long and short of it is this: Determine what makes sense conceptually.
I have found that this approach helps to answer the type of question you
pose.

JAB

--
--------------------------------------------------------
John A. Byerly
Engineered Software Solutions, Ltd.
http://www.ess-quality.com

Graham Perkins

unread,
Nov 19, 2001, 11:09:52 AM11/19/01
to
Mats Helander wrote:
> I thought an instance of the subclass and the instance of its superclass
> did -not- share scope.

Quite right. However, *all* methods within instance of a subclass,
including inherited methods, share the same scope. Which is, the
set of all methods and attributes declared in that subclass and all
its superclasses.

> Private members are not inherited and can be declared
> again in the subclass with no conflict, right?

In C++ and Java private members ARE inherited but cannot be accessed,
altered, or overriden. The subclass instance still has methods which
use those private members, so they must still be there!

In Eiffel and Smalltalk there is no such construct.

> Let's say B is the superclass of A, and that B has a private method called
> "testMe()". Now, if I add a method "testMe()" to the subclass A, then I
> wouldn't actually be overriding the "testMe()" member of A,

That's right.

> since only public members are inherited, yes?

Nope! All members are inherited, but only public and protected members
accessible. You have created an overload, with class membership being
used to disambiguate references.

> And if I don't inherit it, I can't access it via "super.testMe()", right?

You can't access it via "super.testMe()" because the rule for private
says you can's access it via "super.testMe()". But it's still there,
so you must have inherited it!

> And if I override a public member, I can still call the original via
> 'super', yes?

Yes.

> And the 'super', in it's turn, will have no way of accessing the
> members of the "subobject",

Yes it will. If it invokes a method that it knows about, but which
has been overridden in the subclass, then the override will be invoked.
That is how Template Pattern works.

> All of this is, in my book, the same as saying that they do not
> share scope...

I hope I've explained the small error in each of your statements that
leads one to conclude that they share scope.

Of course, separate instances of different classes don't share
scope, regardless of whether they are related by inheritance or not.

I'm saying that all methods of a class, including inherited ones,
share the same scope. And that shared scope includes all the members
of that class, including the inherited ones.

"private" visibility is a minor wrinkle that effects how new
code can refer to previous declarations, but it doesn't affect
the presence or absence of the "private" features.

-------------+ http:/www.gperkins.co.uk/

Dave Harris

unread,
Nov 19, 2001, 1:25:00 PM11/19/01
to
gper...@gperkins.co.uk (Graham Perkins) wrote (abridged):

> > Private members are not inherited and can be declared
> > again in the subclass with no conflict, right?
>
> In C++ and Java private members ARE inherited but cannot be accessed,
> altered, or overriden. The subclass instance still has methods which
> use those private members, so they must still be there!

Actually, in C++, private members can be overridden. Eg:

class Base {
public:
void publicMethod() {
privateMethod();
}

private:
virtual void privateMethod();
};

class Derived : public Base {
private:
void privateMethod() {
cout << "How did I get here?"
}
};

Base *pBase = new Derived();
pBase->publicMethod();

will print the message. Even though Derived::privateMethod() is private
and not declared virtual. "Private" is leaky.

Some people see this as a virtue; ie that access control and overriding
are orthogonal. In my view it means C++ does not provide full information
hiding. There is no easy way for Derived to declare a function that will
ensure Base cannot call it.

Java, however, works as you describe.

Dave Harris, Nottingham, UK | "Weave a circle round him thrice,
bran...@cix.co.uk | And close your eyes with holy dread,
| For he on honey dew hath fed
http://www.bhresearch.co.uk/ | And drunk the milk of Paradise."

@objectmentor.com Robert C. Martin

unread,
Nov 19, 2001, 11:53:58 PM11/19/01
to
On 17 Nov 2001 19:43:49 CET, "Mats Helander" <ma...@urbantalk.se>
wrote:

>I have a question on IS A and HAS A relationships:
>
>If a class "A" HAS A (sorry for the caps, don't mean to yell, but I'm under
>the impression that's how you write'em relationships, yes?) class B, and it
>declares that it "Implements" class B and then it delegates all the calls to
>"Implemented" members in class A to the members of its instance of B (well,
>static members would forward to class B, but you get what I mean,
>right?)...Then, sure there was more work for me to obtain all this, but for
>a user of my object A - will there be any "real" difference to if class A
>had an IS A relationship to class B? I'm gathering that that the work
>described above is more or less what the compiler does for you automagically
>when you declare an IS A relationship...?

The difference is in the details. At a very general level the two
forms are equivalent. But at the detailed level they are not. For
example, you could tell the two apart in C++ is you used dynamic_cast.
In Java you could tell the two apart if you used instanceof or a cast.

Having said that, some OO languages, use the mechanism you describe to
implement inheritance.


Robert C. Martin | "Uncle Bob" | Software Consultants
Object Mentor Inc. | rma...@objectmentor.com | We'll help you get
PO Box 5757 | Tel: (800) 338-6716 | your projects done.
565 Lakeview Pkwy | Fax: (847) 573-1658 | www.objectmentor.com
Suite 135 | | www.XProgramming.com
Vernon Hills, IL, | Training and Mentoring | www.junit.org
60061 | OO, XP, Java, C++, Python|

"One of the great commandments of science is:
'Mistrust arguments from authority.'" -- Carl Sagan

@objectmentor.com Robert C. Martin

unread,
Nov 20, 2001, 12:00:41 AM11/20/01
to
On 17 Nov 2001 19:43:49 CET, "Mats Helander" <ma...@urbantalk.se>
wrote:

>I have a question on IS A and HAS A relationships:

The ISA and HASA relationships are poorly named IMHO. They came from
the AI folks twenty years ago, and migrated into the OO domain because
the relationships between OO structures had certain similarities to
the knowledge networks the AIers were using.

Unfortunately, the term ISA and HAS are not well defined; and their
english connotation is not appropriate for OO relationships. ISA, for
example, is not a good name for inheritance. There are many cases
where the sentence "A ISA B" does not imply that A inherits from B.
The same can be said for "HASA". If you use the terms you have to use
them with poetic license.

I know we've been through the dreaded circle/elipse problem too many
times to count; but it's a perfect example of where the English
connotation of ISA fails. It makes perfect sense to say that a circle
ISA elipse (even though the grammar is pretty poor). On the other
hand, most of us agree that a circle class should not inherit from an
elipse class; since it is a violation of the LSP (Liskov Substitution
Principle).

HASA has its own similar problems. What does HAS mean. Is it
strongly related to the verb "to have"; or is there some other
connotation? Does it imply ownership? Does it imply responsibility?
Does it reply internal containment; or simply containment of a
reference?

Shayne Wissler

unread,
Nov 20, 2001, 12:01:52 AM11/20/01
to
Why do you ask this question? Are you simply trying to understand how the
compiler implements inheritance?

"Mats Helander" <ma...@urbantalk.se> wrote in message
news:3bf6...@news.wineasy.se...

Shayne Wissler

unread,
Nov 20, 2001, 12:13:30 AM11/20/01
to

"Robert C. Martin" <rmartin @ objectmentor . com> wrote in message
news:1fojvto7krsqhflkk...@4ax.com...

> Unfortunately, the term ISA and HAS are not well defined; and their
> english connotation is not appropriate for OO relationships. ISA, for
> example, is not a good name for inheritance. There are many cases
> where the sentence "A ISA B" does not imply that A inherits from B.

For example?

> The same can be said for "HASA". If you use the terms you have to use
> them with poetic license.

Example?

> I know we've been through the dreaded circle/elipse problem too many
> times to count; but it's a perfect example of where the English
> connotation of ISA fails. It makes perfect sense to say that a circle
> ISA elipse (even though the grammar is pretty poor). On the other
> hand, most of us agree that a circle class should not inherit from an
> elipse class; since it is a violation of the LSP (Liskov Substitution
> Principle).

1. Circles and ellipses aren't software, so the example isn't relevant
without more information about the system that has so-called "circles" and
"ellipses".
2. The reason for the LSP is so we can reason--using the concept "isa" in
the sense we normally do--about software. If "isa" isn't valid, then neither
is LSP.
3. If we presume a graphics system, there is no necessary violation of LSP
to derive circle from ellipse. It depends on your implementation.

> HASA has its own similar problems. What does HAS mean. Is it
> strongly related to the verb "to have"; or is there some other
> connotation? Does it imply ownership? Does it imply responsibility?
> Does it reply internal containment; or simply containment of a
> reference?

In Java there is no way to express "has". In C++, it is quite obvious what
"has" means:

class X {
int a;
double b[100];
}

X has a and b. I.e., the elements a and b are part of and integral to X.
There's no difference semantically than what we mean when we say a car has a
door.


Shayne Wissler

univ...@radix.undonet

unread,
Nov 20, 2001, 2:15:56 AM11/20/01
to

RMartin's take, or rather inability to take like the averager person or
programmer, is an obvious symptom and perhaps cause of his inability to
"embrace" a model of holistic system design prior to the bulk of high
level implementation.

Elliott
--
http://www.radix.net/~universe ~*~ Enjoy! ~*~
Hail OO Modelling! * Hail the Wireless Web!
@Elliott 2001 my comments ~ newsgroups+bitnet OK


Mats Helander

unread,
Nov 19, 2001, 11:28:30 AM11/19/01
to

John A. Byerly <jbyerly@ess-quality_remove.com> skrev i
diskussionsgruppsmeddelandet:tvi9t7o...@corp.supernews.com...

Absolutely no offence taken! I got a reply from Graham Perkins that set my
thinking straight. Apart from my inabilites with respects to expressing
myself, I had gotten the whole thing wrong...no wonder it didn't make much
sense!

Your response, however, does. And it points to one thing I'd forgotten, the
need for the constructor and deconstructor of the subclass to create and
destroy the delegated-to instance of the superclass.

Thanks!

/Best Regards, Mats Helander

Mats Helander

unread,
Nov 19, 2001, 11:17:37 AM11/19/01
to

Graham Perkins <gper...@gperkins.co.uk> skrev i
diskussionsgruppsmeddelandet:3BF92ECF...@gperkins.co.uk...

> Mats Helander wrote:
> > I thought an instance of the subclass and the instance of its superclass
> > did -not- share scope.
>
> Quite right. However, *all* methods within instance of a subclass,
> including inherited methods, share the same scope. Which is, the
> set of all methods and attributes declared in that subclass and all
> its superclasses.
>

I didn't quite get it just yet, but reading the rest of your reply did, see
below...

> > Private members are not inherited and can be declared
> > again in the subclass with no conflict, right?
>
> In C++ and Java private members ARE inherited but cannot be accessed,
> altered, or overriden. The subclass instance still has methods which
> use those private members, so they must still be there!
>
> In Eiffel and Smalltalk there is no such construct.
>
> > Let's say B is the superclass of A, and that B has a private method
called
> > "testMe()". Now, if I add a method "testMe()" to the subclass A, then I
> > wouldn't actually be overriding the "testMe()" member of A,
>
> That's right.
>
> > since only public members are inherited, yes?
>
> Nope! All members are inherited, but only public and protected members
> accessible. You have created an overload, with class membership being
> used to disambiguate references.

<Angel choir>
This is the point where it all became clear to me! Thank you so much! I've
not been able to get that from any OO book I've read! This will cause many
changes in my use of the vocabulary, and suddenly it all seems more
intelligeble...I'm awed. So that's how it's seen....

> > And if I don't inherit it, I can't access it via "super.testMe()",
right?
>
> You can't access it via "super.testMe()" because the rule for private
> says you can's access it via "super.testMe()". But it's still there,
> so you must have inherited it!

I'm nat going against this, given my newfound wisdom (see above), but to
show where I went wrong, I thought that it was (as you say) because the
rules said so, but (again) I thought this was because you were only
"secretly" holding a reference to a separate super object, to which the
calls in the inherited members were delegated. But now I've seen the light
(I think).

> > And if I override a public member, I can still call the original via
> > 'super', yes?
>
> Yes.

Overloading again? super.someMethod() is actually represented in the
subclass as overloading this.someMethod()? Again, I thought it was just a
delegational call (but stand corrected)...

> > And the 'super', in it's turn, will have no way of accessing the
> > members of the "subobject",
>
> Yes it will. If it invokes a method that it knows about, but which
> has been overridden in the subclass, then the override will be invoked.
> That is how Template Pattern works.

I'm with you.

> > All of this is, in my book, the same as saying that they do not
> > share scope...
>
> I hope I've explained the small error in each of your statements that
> leads one to conclude that they share scope.

Yes. Indeed. Again, thanks! My book is now updated accordingly.

> Of course, separate instances of different classes don't share
> scope, regardless of whether they are related by inheritance or not.
>
> I'm saying that all methods of a class, including inherited ones,
> share the same scope. And that shared scope includes all the members
> of that class, including the inherited ones.
>
> "private" visibility is a minor wrinkle that effects how new
> code can refer to previous declarations, but it doesn't affect
> the presence or absence of the "private" features.
>

So, basically, all the inherited members are also "reimplemented" in the
subclass, making it "self-contagious"...Right?

/Best Regards, Mats Helander.


Warren Zeigler

unread,
Nov 20, 2001, 11:39:37 AM11/20/01
to
"Mats Helander" <ma...@urbantalk.se> wrote in message
news:3bf9...@news.wineasy.se...


From the various posts, I think you are closer to "getting it, but still
having a vew probems"

>I thought that it was (as you say) because the
>rules said so, but (again) I thought this was because you were only
>"secretly" holding a reference to a separate super object, to which the
>calls in the inherited members were delegated. But now I've seen the light

New OO people seem to always trip up on this. Our discussing "accessing
methods of the parent class," etc, is really not true. We access methods
DEFINED in the parent class, but once you do "new," they are all part of one
object.

I can't count the number of times programmers have asked "Is it accessing a
hidden instance of the parent object?"

To clarify - think of it this way:
When you say "new" to the concrete class that inherits:
1) As far as allocation of memory for the various variables, all of the
class definitions are consolidated (collapsed) into a single concrete class.
It is as if you did a cut and past, putting everything in the concrete
class. If you have name duplicates, BOTH exist.
2) As far as visibility is concerned, the language rules apply for private
and protected data members, and private, protected, overridden and
polymorphic methods, but don't let that confuse you. There is only one
object created. You are not accessing members of the parent object if the
method or data were defined there. You are accessing data in the one and
only one object created by new, parts of which happened to be defined in the
parent class.

"new" has nothing to do with method inheritance. All code is generated for
all methods, whether they were defined in the parent or concrete class.
Which code (method) is accessed depends on language rules (including the
type of the reference in some languages) and any runtime polymorphic
mechanism that may exist.

One last perspective:
1) When "new" executes, memory is allocated for the variables in the object.
The variables created are the sum total of the variables defined in the
concrete class and all classes inherited by the concrete class. They are
allocated in ONE block, creating ONE object, with parts defined in different
classes. (Most runtime polymorphism mechanisms also take a little space, but
it is all part of the one allocated object.)
2) The methods used to access this data is defined by language rules for
visibility, overloading, overriding and polymorphism.

Did this help?

--
Warren R. Zeigler Sr.
Understanding Objects - The most complete object basics class today.
It's the class knowledgeable managers have been looking for.
URL: http://www.UnderstandingObjects.com


L. F. Hall

unread,
Nov 20, 2001, 12:40:20 PM11/20/01
to
From: Robert C. Martin <rmartin @ objectmentor . com>
Message-ID: <1fojvto7krsqhflkk...@4ax.com>

[snip]


> I know we've been through the dreaded circle/elipse problem too many
> times to count; but it's a perfect example of where the English
> connotation of ISA fails. It makes perfect sense to say that a circle
> ISA elipse (even though the grammar is pretty poor). On the other
> hand, most of us agree that a circle class should not inherit from an
> elipse class;

Okay.

> since it is a violation of the LSP (Liskov
Substitution
> Principle).

No. This is a repeat of the blemish in your 1996 paper on LSP. ISA
does not violate Barbara Liskov's statement of the LSP. Please,
stand tall and write "oops" about that minor defect in a valid work, so
we better understand sound program design advice.

Supporting citation for my blunt response:
From Re: On LSP *is_a*, rel_P*: was Re: "is a" relationship
between enumerated types? on clcm in July 2001.

>From: "Jake Holland" <jhol...@ixiacom.com>

> > "L. F. Hall" <p...@eot.com> wrote in message
> > news:ZugZ6.1629$oF3.4...@news7.onvoy.net...
> > [snip]
> > > LSP is *not* violated in Robert Martin's sample code. His explanation
> > > may be "clear," but it is not in accord with LSP. Instead, his design
> > > principle that classes should not be corrupted if mistakenly passed to
> > > their base class member functions is violated. So, he has made a

> > [snip]
> > Ah, I think I see the source of confusion.
> > http://www.objectmentor.com/publications/lsp.pdf, Page 4, paragraph 3
> > (right under the "f" function), where he says "This is a clear violation
> > of LSP." The f function doesn't violate LSP, it violates the Square
> > class invariant, and therefore it looks like there's an error in the
> > paper. If that's what you're saying, I agree.

> That's what I'm saying. Preservation of the Square class invariant in
> this example is a more restrictive (protective) design guideline than LSP.

> > The "fix" proposed for illustration, in which Rectangle::SetWidth and
> > SetHeight are virtual, is the version which actually violates the LSP,
> > as demonstrated by the "g" function on page 5, according to my
> > understanding. It was this part of the paper (extending on to page 6)
> > to which I was referring when I said his sample code violates the LSP
> > and that this was clearly explained. Sorry for the confusion.

> Agreed. The virtual functions modify the base class behavior through
> the derived class. RM, himself, notes the "fix" violates the Open-Closed
> principle as he introduces it on pg 4b.

Please do not consider this acrimonious squabbling. Some of the history
of science is cooperative building of understanding among persons of
good will. Many of us would benefit from your correction of this minor
blemish and its removal from present discussions.

Tnx for the moments,
Len


Shayne Wissler

unread,
Nov 20, 2001, 1:05:26 PM11/20/01
to

<univ...@radix.UNDOnet> wrote in message
news:9tcvvc$bb3$1...@news1.Radix.Net...

> RMartin's take, or rather inability to take like the averager person or
> programmer, is an obvious symptom and perhaps cause of his inability to
> "embrace" a model of holistic system design prior to the bulk of high
> level implementation.
>
> Elliott

If you want to write a post on what "holistic system design" is and why it
relates to an "inability to talk like the average person" (and why this
matters), then write it. Otherwise, all you've done is devalued this
newsgroup by making inappropriate, gratuitous ad hominems.


Shayne Wissler

Mats Helander

unread,
Nov 20, 2001, 2:26:31 PM11/20/01
to
Thank you! Most enlightening! And I'm very happy to get this straight,
because I always thought it was a bit wierd...

Actually, I've read a few books on the topic, and what I've fouund on the
web...do you have any suggested book (notice the lack of pluralis) or url:s
that put things as clearly as you just have?

/Best Regards, Mats Helander

Mats Helander

unread,
Nov 20, 2001, 2:34:36 PM11/20/01
to
>
> The difference is in the details. At a very general level the two
> forms are equivalent. But at the detailed level they are not. For
> example, you could tell the two apart in C++ is you used dynamic_cast.
> In Java you could tell the two apart if you used instanceof or a cast.
>
> Having said that, some OO languages, use the mechanism you describe to
> implement inheritance.
>

Really? Could you name a few?

/Best Regards, Mats Helander


Mats Helander

unread,
Nov 20, 2001, 2:58:46 PM11/20/01
to

Shayne Wissler <thal...@yahoo.com> skrev i
diskussionsgruppsmeddelandet:4tlK7.32633$RG1.16...@news1.rdc1.sfba.home.c
om...

> Why do you ask this question? Are you simply trying to understand how the
> compiler implements inheritance?

Well, I'm building an OO tool, and here comes the funny part:

You know what I got wrong about inheritence. But as I said, I always found
it strange. So strange, in fact, that I decided I couldn't have it! So I
built the tool on the principle you've described instead, thinking "OO
purists may call me their names, but I'll be darned if I'll do it any other
way..."

I thought to myself that I could motivate in the documentation why I made
these choises. Then I came here to gain a better understanding of the issue
(thus my question) so I wouldn't sound too confused in that doc.

Obviously, I'm very pleased with my recent learnings! Thank you all!

If I may bore you further, I'd like to ask one more question:

The reason I got to thinking about these things has very much to do with you
remarks about the object being just one block of memory. I'm making a tool
that maps objects to rdbms, and so I have to think about the same aspect.

I decided that a concrete object should have all their properties collected
at the table level (just like the one-memory-block principle) or their would
be no end to the horrors that would follow.

But now, to my question: If you have a part in the constructor of a class
that creates an entry to a table, say like this

<Part of Person class's constructor>
conn.Execute "INSERT INTO tblPerson...."

Then with the (as I understand it to be) common practice of calling the
parent's constuctor from the constructor of the subclass, as:

<Part of Employee class's constructor>
<Call super's constructor>
conn.Execute "INSERT INTO tblEmployee...."

Then the employee object will be represented in two different tables in the
database, breaching the concept of the "one-lump object".

Is this realistic, or am I missing something in how it's normally done? As I
said, I went through pains to make my tools make sure that two tables aren't
used like this (and I had to do it just by avoiding simply calling up a
hidden instance of the superclass and delegate, all inherited members had to
be modified), so I'm happy to learn that it doesn't violate OO principles!

/Best Regards, Mats Helander


Warren Zeigler

unread,
Nov 20, 2001, 8:28:11 PM11/20/01
to
"Mats Helander" <ma...@urbantalk.se> wrote in message
news:3bfa...@news.wineasy.se...

> Thank you! Most enlightening! And I'm very happy to get this straight,
> because I always thought it was a bit wierd...
>
> Actually, I've read a few books on the topic, and what I've fouund on the
> web...do you have any suggested book (notice the lack of pluralis) or
url:s
> that put things as clearly as you just have?
>
> /Best Regards, Mats Helander

Your welcome, and thanks for the kind words.

No, this is a gap in the book and training market. Now that I am done w/ my
manual, I am about to convert it to a book.

@objectmentor.com Robert C. Martin

unread,
Nov 21, 2001, 1:01:33 AM11/21/01
to
On Tue, 20 Nov 2001 05:13:30 GMT, "Shayne Wissler"
<thal...@yahoo.com> wrote:

>
>"Robert C. Martin" <rmartin @ objectmentor . com> wrote in message
>news:1fojvto7krsqhflkk...@4ax.com...
>
>> Unfortunately, the term ISA and HAS are not well defined; and their
>> english connotation is not appropriate for OO relationships. ISA, for
>> example, is not a good name for inheritance. There are many cases
>> where the sentence "A ISA B" does not imply that A inherits from B.
>
>For example?

An integer ISA complex number. However, no sane programmer would
normally build an integer class that inherits from a complex class.
At least not in any of the conventional OO languages that are
currently in use; or were in use when the term ISA was mapped to OO.

>> I know we've been through the dreaded circle/elipse problem too many
>> times to count; but it's a perfect example of where the English
>> connotation of ISA fails. It makes perfect sense to say that a circle
>> ISA elipse (even though the grammar is pretty poor). On the other
>> hand, most of us agree that a circle class should not inherit from an
>> elipse class; since it is a violation of the LSP (Liskov Substitution
>> Principle).
>
>1. Circles and ellipses aren't software, so the example isn't relevant
>without more information about the system that has so-called "circles" and
>"ellipses".

I have actually reviewed designs of system where there was, indeed, a
circle class that tried to inherit from an arc class. The domain was
computational geometry. The authors felt that the ISA rule meant that
a Circle should inherit from an Arc. Clearly there are problems with
this view. An Arc must have an angle variable, that a Circle doesn't
need.

Regardless of whether circle/elipse is a software problem or not, it
has many analogs in other software domains. The issues are still
relevant. Circle/Elipse is just an example of the kinds of problems
that assuming ISA means inheritance can cause.

>2. The reason for the LSP is so we can reason--using the concept "isa" in
>the sense we normally do--about software. If "isa" isn't valid, then neither
>is LSP.

If you define "isa" to mean LSP then the issue goes away. If, on the
other hand, you define ISA to mean "is a" as in english; and then
equate it to inheritance, you end up with circle/elipse problems.

>3. If we presume a graphics system, there is no necessary violation of LSP
>to derive circle from ellipse. It depends on your implementation.

There are ways to avoid the LSP violation; but they are very
constraining. One has to make the classes immutable; or employ some
other draconian measure. This seems like a lot of inconvenience just
to keep the use of ISA consistent with English "is a" and implemented
with inheritance.

>> HASA has its own similar problems. What does HAS mean. Is it
>> strongly related to the verb "to have"; or is there some other
>> connotation? Does it imply ownership? Does it imply responsibility?
>> Does it reply internal containment; or simply containment of a
>> reference?
>
>In Java there is no way to express "has". In C++, it is quite obvious what
>"has" means:
>
>class X {
> int a;
> double b[100];
>}

That's one definition. It's not the definition Booch used in "Object
Oriented Analysis and Design". It's also not the definition that the
three amigos used in the early versions of UML.

Booch and early UML defined HASA to mean "able to send messages to".
This was most often implemented as an instance variable holding a
pointer, or a reference. It was sometimes implemented as an instance
variable holding a value, as above. It was even implemented as an
argument to a method on rare occasions.


>
>X has a and b. I.e., the elements a and b are part of and integral to X.
>There's no difference semantically than what we mean when we say a car has a
>door.

Using simple english transtive verbs to describe OO relationships is,
IMHO, naive. OO relationships have very particular semantics that map
only very crudely to those english verbs.

@objectmentor.com Robert C. Martin

unread,
Nov 21, 2001, 1:15:40 AM11/21/01
to


I'm having trouble seeing the flaw. The violation in both cases is in
the Square class. Square is not substitutable for valid clients of
Rectangle. Both f and g are valid clients of Rectangle that do not
violate any of Recatangles implied contracts. Neither f nor g know
anything at all about Square, nor should they. Yet if a Square is
passed into these functions, in the guise of a Rectangle; confusion
results. Either the Square is corrupted (in the f case) or the
client's expectations are violated. It is not g nor f that violate
the LSP. Those functions don't violate anything at all. It is the
implementation of Square that violate the LSP.

Shayne Wissler

unread,
Nov 21, 2001, 2:34:32 AM11/21/01
to

"Robert C. Martin" <rmartin @ objectmentor . com> wrote in message
news:tsfmvtc7ceviu7oaj...@4ax.com...

> >For example?
>
> An integer ISA complex number. However, no sane programmer would
> normally build an integer class that inherits from a complex class.

You're confusing a software integer with a mathematical integer. They are
two entirely different things. I don't see how this discussion can go
anywhere if you won't distinguish between software units and other kinds of
units.


Shayne Wissler

Shayne Wissler

unread,
Nov 21, 2001, 11:18:38 AM11/21/01
to

"Robert C. Martin" <rmartin @ objectmentor . com> wrote in message
news:tsfmvtc7ceviu7oaj...@4ax.com...

> If you define "isa" to mean LSP then the issue goes away. If, on the
> other hand, you define ISA to mean "is a" as in english; and then
> equate it to inheritance, you end up with circle/elipse problems.

What do you think "is a" in English means?


Shayne Wissler

univ...@radix.undonet

unread,
Nov 21, 2001, 12:16:04 PM11/21/01
to
Robert C. Martin <rmartin @ objectmentor . com> wrote:
> On Tue, 20 Nov 2001 05:13:30 GMT, "Shayne Wissler"
> <thal...@yahoo.com> wrote:
>
>>
>>"Robert C. Martin" <rmartin @ objectmentor . com> wrote in message
>>news:1fojvto7krsqhflkk...@4ax.com...
>>
>>> Unfortunately, the term ISA and HAS are not well defined; and their
>>> english connotation is not appropriate for OO relationships. ISA, for
>>> example, is not a good name for inheritance. There are many cases
>>> where the sentence "A ISA B" does not imply that A inherits from B.

>>For example?

> An integer ISA complex number.

In whose math? I've never heard that in 2nd year calculus, linear
algebra, statistics, etc.

If anything complex is built from real and imaginary numbers.

And it really depends on math, or other domain context, as to what the
relationship should be.

> However, no sane programmer would
> normally build an integer class that inherits from a complex class.
> At least not in any of the conventional OO languages that are
> currently in use; or were in use when the term ISA was mapped to OO.

For A and B of *any 2 things* in some cases B shouldn't be inherited from
A, B should be inherited from A, or B should be an object instance of A.

Aside from how integer relates to complex, inheriting one thing from
another depends on the actual domain, project use cases, potential
hardware, potential software, etc.

univ...@radix.undonet

unread,
Nov 21, 2001, 12:25:50 PM11/21/01
to

Good point. Commonality is commonality, is commonality.

While LSP demands a strict interpretation of commonality, commonality is
clearly the underlying idea in "everyday" English. That shouldn't be hard
for people to realize, but XP/Agility folk never fail to surprise.

Graham Perkins

unread,
Nov 21, 2001, 12:28:01 PM11/21/01
to
> Actually, in C++, private members can be overridden. Eg:

Good grief! I've just checked ARM and you're quite correct
of course. What a foolish piece of design!

Moreover, I see you can override any method ande declare
different visibility in the derived class.

What is the point? If you're reducing the visibility,
client can simply upcast to increase again.

> In my view it means C++ does not provide full information
> hiding. There is no easy way for Derived to declare a function
> that will ensure Base cannot call it.

nor vice-versa.


-------------+ http:/www.gperkins.co.uk/

Graham Perkins

unread,
Nov 21, 2001, 12:37:02 PM11/21/01
to
> So, basically, all the inherited members are also "reimplemented"
> in the subclass, making it "self-contagious"...Right?

In the case of C++, the term "self contagious" seems ideal :-)

But yes, you can think of it as "re-implemented". Personally
I find it easy to think of all the methods as "re-implemented"
per instance.

In the case of instances, there is hidden "this" reference
going along with all the method calls in order to provide
a scope so that each instance behaves as if it had its own
methods.

In the case of subclasses, the virtual method table is copied
and then extended with extra references to the code for the
new functions. (or old references are replaced, in the case
of overrides). Also, the attribute template is copied and
extended.

More dynamic systems like Smalltalk have to be different
'cos they allow you to edit a superclass while its subclass
instances are still live.

good luck,
graham

-------------+ http:/www.gperkins.co.uk/

Mats Helander

unread,
Nov 21, 2001, 10:43:29 AM11/21/01
to
>Yet if a Square is
> passed into these functions, in the guise of a Rectangle; confusion
> results. Either the Square is corrupted (in the f case) or the
> client's expectations are violated.

The way I program (not out to say right or wrong, just to say that you can
see it differently) I wouldn't have problems with Squares passed to
functions expecting Rectangles, but I might the other way around.

I don't see it to be 'necessary' OO practice to subclass in order to add
members, some situations justify adding subclasses to 'incapacitate' members
through, well, call it business rules.

To me, a Square inherits from a rectangle, and adds the business rule (in
the property accessor methods, most likely) that whenever you change either
the Width or Height, both will take the supplied value. Why would I want to
do it like that?

Because I can't imagine all the uses clients of my objects might think up.
For instance: I probably wouldn't forget to add an "getArea()" method to my
Square and Rectangle classes. But assume that I did, in order to show how
clients may need to use my objects in unforseen ways. So, a function that
accepts a Square object and that needed the area would obviously take either
the Width or Height and square it. A function that accepted a Rectangle
would multiply the Height with the Width, and this wouldn't be a problem if
a Square was passed to it. But if you are able to pass a Rectangle to the
function that expects a Square, the function will proceed to use a false
value for the area.

Additionally, the function that accepts a Rectangle might make a check on
the object to see if it is actually a Square, and then tweak the area-calcs
to optimise it a bit (read just Height OR Width). It would then be checking
for a class above the expected one in the hierarchy, and so it could
reasonably know about it (it was obviously there before the subclass was
defined). On the other hand, If you want Rectangle to inherit from Square,
the function that expects a Square MUST include (if I forgot to include a
getArea() method) this kind of tweak, AND it must look downwards in the
hierarchy, in other words it must be prepared for classes that might have
yet to be defined.

That's the way I see it, I'm sure there's plenty of views....

/Best Regards, Mats Helander


Richard MacDonald

unread,
Nov 21, 2001, 12:48:42 PM11/21/01
to
<univ...@radix.UNDOnet> wrote in message
news:9tgngk$fs9$1...@news1.Radix.Net...

> Robert C. Martin <rmartin @ objectmentor . com> wrote:
> > On Tue, 20 Nov 2001 05:13:30 GMT, "Shayne Wissler"
> > <thal...@yahoo.com> wrote:
> >
> >>
> >>"Robert C. Martin" <rmartin @ objectmentor . com> wrote in message
> >>news:1fojvto7krsqhflkk...@4ax.com...
> >>
> >>> Unfortunately, the term ISA and HAS are not well defined; and their
> >>> english connotation is not appropriate for OO relationships. ISA, for
> >>> example, is not a good name for inheritance. There are many cases
> >>> where the sentence "A ISA B" does not imply that A inherits from B.
>
> >>For example?
>
> > An integer ISA complex number.
>
> In whose math? I've never heard that in 2nd year calculus, linear
> algebra, statistics, etc.

Perhaps you shouldn't have slept through high school algebra then.

> If anything complex is built from real and imaginary numbers.

Nope. 1+0i is a complex number. Note the integer(s).

> And it really depends on math, or other domain context, as to what the
> relationship should be.

Quite so. In this case, I think Robert was referring to the math domain.


Shayne Wissler

unread,
Nov 21, 2001, 2:51:53 PM11/21/01
to

<univ...@radix.UNDOnet> wrote in message
news:9tgo2u$fs9$2...@news1.Radix.Net...

> Shayne Wissler <thal...@yahoo.com> wrote:
> >
> > "Robert C. Martin" <rmartin @ objectmentor . com> wrote in message
> > news:tsfmvtc7ceviu7oaj...@4ax.com...
> >
> >> If you define "isa" to mean LSP then the issue goes away. If, on the
> >> other hand, you define ISA to mean "is a" as in english; and then
> >> equate it to inheritance, you end up with circle/elipse problems.
>
> > What do you think "is a" in English means?
>
> Good point. Commonality is commonality, is commonality.

Right--though I'd use the term "similarity." Commonality denotes common
parts, whereas "is a" implies similarity.


Shayne

Mats Helander

unread,
Nov 21, 2001, 12:51:37 PM11/21/01
to

Graham Perkins <gper...@gperkins.co.uk> skrev i
diskussionsgruppsmeddelandet:3BFBE63E...@gperkins.co.uk...

> > So, basically, all the inherited members are also "reimplemented"
> > in the subclass, making it "self-contagious"...Right?
>
> In the case of C++, the term "self contagious" seems ideal :-)
>
> But yes, you can think of it as "re-implemented". Personally
> I find it easy to think of all the methods as "re-implemented"
> per instance.
>
> In the case of instances, there is hidden "this" reference
> going along with all the method calls in order to provide
> a scope so that each instance behaves as if it had its own
> methods.

If I get this right, that means that:

myInstance.doStuff()

is in reality:

ClassOfMyInstance.doStuff(this) 'static method

where myInstance is passed to the 'this' parameter?


> In the case of subclasses, the virtual method table is copied
> and then extended with extra references to the code for the
> new functions. (or old references are replaced, in the case
> of overrides). Also, the attribute template is copied and
> extended.

Aha! So for a non-overriden inherited method, the virtual method table
points to the same address as for the method in the superclass, right? Thus
Scott Ambler's remark earlier that the "delegation" approach will cost an
extra jump for methods?

> More dynamic systems like Smalltalk have to be different
> 'cos they allow you to edit a superclass while its subclass
> instances are still live.

I created a (rather simple) OO system that allowed you to do that. The
lesson I learned was to never use something like that again! ;-) No,
seriously, it works fine for RAD prototyping, but IMO it's not as useful for
something that you're actually gonna deploy.

> good luck,
> graham

Thank you. And rest assured that your answers go promptly towards minimizing
my dependancy on luck, which I apreciate greatly!

> -------------+ http:/www.gperkins.co.uk/


@objectmentor.com Robert C. Martin

unread,
Nov 21, 2001, 4:26:47 PM11/21/01
to

And folks who insist that Circle classes must inherit from Elipse
classes are confusing geometric shapes with software.

This is precisely the point of the whole argument. The term ISA can
be applied to various domains, like mathematics and geometry. There
are concepts in those domains that can be mapped to software. A
geometric circle can be mapped to become class Circle in a software
application. However, the relationships in one domain may not map
well into the software domain. The ISA relationship between Circle
and Elipse in the geometry domain does not map well into the software
domain.

@objectmentor.com Robert C. Martin

unread,
Nov 21, 2001, 4:32:44 PM11/21/01
to

I think you need to ask Mr. Clinton.

It can mean a whole bunch of things.

* It can mean congruence: "That is an equilateral triangle".
* It can mean "is like": "comp.object is a pain in the ass."
* It can equality: "1+1 is 2"
* It can mean equivalence. "The man in that video is me."
* It can mean allegory: "Superman is me."

It's a term that can be used in many varicolored ways.

Shayne Wissler

unread,
Nov 21, 2001, 4:32:42 PM11/21/01
to

"Robert C. Martin" <rmartin @ objectmentor . com> wrote in message
news:uq6ovtskv7bqsqv0c...@4ax.com...

> >You're confusing a software integer with a mathematical integer. They are
> >two entirely different things. I don't see how this discussion can go
> >anywhere if you won't distinguish between software units and other kinds
of
> >units.
>
> And folks who insist that Circle classes must inherit from Elipse
> classes are confusing geometric shapes with software.
>
> This is precisely the point of the whole argument. The term ISA can
> be applied to various domains, like mathematics and geometry. There
> are concepts in those domains that can be mapped to software. A
> geometric circle can be mapped to become class Circle in a software
> application. However, the relationships in one domain may not map
> well into the software domain. The ISA relationship between Circle
> and Elipse in the geometry domain does not map well into the software
> domain.

There are many points here I disagree with. But the most important and
fundamental is the implicit assumption that "is a" doesn't apply to
software. Again, precisely what do you think the english usage means?


Shayne Wissler

@objectmentor.com Robert C. Martin

unread,
Nov 21, 2001, 4:57:55 PM11/21/01
to
On Wed, 21 Nov 2001 17:28:01 +0000, Graham Perkins
<gper...@gperkins.co.uk> wrote:

>> Actually, in C++, private members can be overridden. Eg:
>
>Good grief! I've just checked ARM and you're quite correct
>of course. What a foolish piece of design!
>
>Moreover, I see you can override any method ande declare
>different visibility in the derived class.
>
>What is the point? If you're reducing the visibility,
>client can simply upcast to increase again.

You can increase the accessibility of an element of a derivative; but
you cannot decrease it. That is, you cannot make an inherited member
less accessible than it's base.

Shayne Wissler

unread,
Nov 21, 2001, 4:58:00 PM11/21/01
to

"Robert C. Martin" <rmartin @ objectmentor . com> wrote in message
news:u07ovtg659tutb5av...@4ax.com...

> >What do you think "is a" in English means?

> It can mean a whole bunch of things.


>
> * It can mean congruence: "That is an equilateral triangle".
> * It can mean "is like": "comp.object is a pain in the ass."
> * It can equality: "1+1 is 2"
> * It can mean equivalence. "The man in that video is me."
> * It can mean allegory: "Superman is me."
>
> It's a term that can be used in many varicolored ways.

My, the imagination. You left out the relevant sense, interestingly enough:

* - A bird is a living organism.
- A mouse is a mammal.
- A toyota celica is a car.
- A car is a vehicle.

Now, precisely what do you think this sense of "is a" means?


Shayne Wissler

Mats Helander

unread,
Nov 21, 2001, 10:40:58 PM11/21/01
to
Ok, I warned you, I said it was thought provoking, so these thoughts are
highly unpolished...

I've been thinking about the "typing" issue and the limitations of the
standard "is a" inheritence, and I had some (moronic?) ideas that I don't
know if they're just plain nutty or if there's already plenty of work done
on this...What set me off was thinking about the statement "If it is a
Customer and it has purchased for more than 20.000$, it is a
ValuedCustomer..."

The basic idea is this: Could you have some sort of "conditional" or
"dynamic" types?

Could I create (in some experimental language, or perhaps in some
commonplace language, maybe I'm just ignorant) a type ValuedCustomer that
was defined to be "All objects of the type Customer that happen to satisfy
this.getTotalPurchasesSum() > 20.000" so that I can define a function that
accepted objects of type ValuedCustomer, whereupon the runtime makes a
"type" check to see if the conditions are met on the object that is passed
to the function...of course you wouldn't be able to catch any compile-time
errors this way, but nevertheless...

The possible value I would see to such a feature would be that you could add
more (implementation-independent) logic to the (pre-implementation) model.

Just a thought...

/Best Regards, Mats Helander

>
> Martin Fowler <fow...@acm.org> skrev i
> diskussionsgruppsmeddelandet:3bfc6829.2405790624@news.ne.mediaone.net...


> > On Wed, 21 Nov 2001 16:18:38 GMT, "Shayne Wissler"
> > <thal...@yahoo.com> wrote:
> >
> > >What do you think "is a" in English means?
> >

> > The confusion over "is a" is an old knotty problem in logic.
> >
> > Consider the following statements
> >
> > 1) Shep is a Border Collie
> > 2) A Border Collie is a Dog
> > 3) A Dog is an Animal
> > 4) A Border Collie is a Breed
> > 5) A Dog is A Species
> >
> > If I combine (1) and (2) I get Shep is a dog
> > (2) and (3) -> Border Collies are animals
> > (1), (2), (3) -> Shep is an animal
> >
> > these all make sense
> >
> > but
> >
> > (1), (4) -> Shep is a Breed
> > (2), (5) -> Border Collie is a species
> >
> > do not
> >
> > The reason some combinations work and some don't is because "is a"
> > means something different in the five statements. Some are
> > classifications (Shep is an instance of Border Collie) while some are
> > generalizations (Border Collie is a kind of Dog). The rules for
> > combining them are rigorous once you realize there are two different
> > relationships.
> >
> > (And yes, "is a" can mean other things too.)
> >
> > Apparantly it was only surprisingly recently ( 19th or 20th century,
> > if I remember correctly) before this was properly understood. It had
> > tangled up logic for a while.
> >
> > Martin
> >
>
>


Shayne Wissler

unread,
Nov 22, 2001, 12:53:41 AM11/22/01
to
The reason why you can't combine 1,4 and 2,5 is that the concepts Animal,
Dog, and Border Collie all denote the entity Shep (in this context), but the
concepts Breed and Species denote *concepts*: Border Collie and Dog,
respectively.

Take the standard syllogism:

All men are mortal
Socrates is a man
Therefore, Socrates is mortal.

The reason you can make the deduction that Socrates is mortal is that it is
implict in the major premise: "All men" is already referring to Socrates, as
he is one.

Your combining (1) and (2) amounts to this syllogism:

All Border Collies are Dogs (this refers to every Border Collie that has,
does, or ever will exist)


Shep is a Border Collie

Therefore, Shep is a Dog.

However, your (1) and (4) combination is trying to make this syllogism:

(All) Border Collie is a Breed (this refers to the Border Collie qua type of
Breed, not to all or even to any particular Border Collie)


Shep is a Border Collie

Therefore, Shep is a Breed.

This makes no sense, because the referent of Border Collie in the major
premise is not referred to in the minor premise. The major premise is
referring to the *type* Border Collie, not a group of actual Border Collies,
but the minor premise is referring to an actual Border Collie.

So basically your last two examples commit a logical fallacy (I don't know
the name of it offhand). The problem isn't the concept "is a", but not
keeping track of what the "is a"'s are referring to.


Shayne Wissler

"Martin Fowler" <fow...@acm.org> wrote in message
news:3bfc6829.2405790624@news.ne.mediaone.net...


> On Wed, 21 Nov 2001 16:18:38 GMT, "Shayne Wissler"
> <thal...@yahoo.com> wrote:
>
> >What do you think "is a" in English means?
>

Mats Helander

unread,
Nov 21, 2001, 11:08:46 PM11/21/01
to

peter_douglass <bai...@gis.net> skrev i
diskussionsgruppsmeddelandet:3bfd0315$1@tobjects....

>
> "Mats Helander" wrote:
>
> > Ok, I warned you, I said it was thought provoking, so these thoughts are
> > highly unpolished...
> >
> > I've been thinking about the "typing" issue and the limitations of the
> > standard "is a" inheritence, and I had some (moronic?) ideas that I
don't
> > know if they're just plain nutty or if there's already plenty of work
done
> > on this...What set me off was thinking about the statement "If it is a
> > Customer and it has purchased for more than 20.000$, it is a
> > ValuedCustomer..."
> >
> > The basic idea is this: Could you have some sort of "conditional" or
> > "dynamic" types?
>
> Yes, they are called dependent types. There is at least one experimental
> language that I know of with dependent types, called Cayenne
>
> http://www.cs.chalmers.se/~augustss/cayenne/
>
> --PeterD
>
> p.s. I hope you can read this. My posts from totally objects don't seem
to
> go everywhere, just some places :-(
>

I can read it! Thanks for the link, I'll follow it promptly! So I wasn't
mad, then... ;-)

/Best Regards, Mats Helander


Warren Zeigler

unread,
Nov 21, 2001, 9:35:52 PM11/21/01
to
> > In my view it means C++ does not provide full information
> > hiding. There is no easy way for Derived to declare a function
> > that will ensure Base cannot call it.
> nor vice-versa.
> -------------+ http:/www.gperkins.co.uk/

Stroustrup did not design the protection mechanism as a secure defense
mechanism, just a help.

Martin Fowler

unread,
Nov 21, 2001, 10:01:12 PM11/21/01
to
On Wed, 21 Nov 2001 16:18:38 GMT, "Shayne Wissler"
<thal...@yahoo.com> wrote:

>What do you think "is a" in English means?

The confusion over "is a" is an old knotty problem in logic.

Universe

unread,
Nov 21, 2001, 10:46:00 PM11/21/01
to
Robert C. Martin <rmartin @ objectmentor . com> wrote:
> On Wed, 21 Nov 2001 07:34:32 GMT, "Shayne Wissler"
> <thal...@yahoo.com> wrote:
>
>>
>>"Robert C. Martin" <rmartin @ objectmentor . com> wrote in message
>>news:tsfmvtc7ceviu7oaj...@4ax.com...
>>
>>> >For example?
>>>
>>> An integer ISA complex number. However, no sane programmer would
>>> normally build an integer class that inherits from a complex class.
>>
>>You're confusing a software integer with a mathematical integer. They are
>>two entirely different things. I don't see how this discussion can go
>>anywhere if you won't distinguish between software units and other kinds of
>>units.

> And folks who insist that Circle classes must inherit from Elipse
> classes are confusing geometric shapes with software.

Anybody who insists on anything regardless of context, just as you do by
insisting that all of reality can't be modelled in software, regardless of
software used, is confused at best.

Who are these people insisting Circle must inherit from Ellipse anyway?
I've never seen it.

Inheriting Circle from Ellipse can indeed work when properly designed
and coded. The lines of approach taken by Cauvin and Helander are highly
effective and doable ways of precisley inheriting Circle from Ellipse if
your domain and or use cases require that.

> This is precisely the point of the whole argument. The term ISA can
> be applied to various domains, like mathematics and geometry. There
> are concepts in those domains that can be mapped to software. A
> geometric circle can be mapped to become class Circle in a software
> application.

> ...However, the relationships in one domain may not map


> well into the software domain. The ISA relationship between Circle
> and Elipse in the geometry domain does not map well into the software
> domain.

You have not shown us this at all.

Your faulty, technocratic worldview that OO doesn't originate, or exist in
reality is what prompts you to periodically insist that certain things can
not be inherited from another.

But a) you haven't demonstrated it, and b) if it really exists or is a
good way to model a domain, and or use cases it can be done with enough
*fore*thought in design and coding. And c) most OO practioners
fundamentally see OO as Booch does in the first 3 chapters of his OOA&D,
which you have always disliked and argued against. Given this,
anything you did contribute to Booch methodology was ancillary and
secondary at best.

Universe

unread,
Nov 21, 2001, 10:52:30 PM11/21/01
to
Universe <univ...@radix.undonet> at RadixNet Internet


Robert C. Martin <rmartin @ objectmentor . com> wrote:

> "Shayne Wissler" wrote:

>>"Robert C. Martin" <rmartin @ objectmentor . com> wrote in message

>>> "Shayne Wissler" wrote:
>>> >For example?

>>> An integer ISA complex number. However, no sane programmer would
>>> normally build an integer class that inherits from a complex class.
>>> normally build an integer class that inherits from a complex class.

>>You're confusing a software integer with a mathematical integer. They are
>>two entirely different things. I don't see how this discussion can go
>>anywhere if you won't distinguish between software units and other kinds of
>>units.

> And folks who insist that Circle classes must inherit from Elipse
> classes are confusing geometric shapes with software.

Anybody who insists on anything regardless of context, just as you do
by insisting that all of reality can't be modelled in software,
regardless of software used, is confused at best.

BTW, who are these people insisting Circle must inherit from Ellipse
anyway? I've never read it.



Inheriting Circle from Ellipse can indeed work when properly designed
and coded. The lines of approach taken by Cauvin and Helander are

highly effective and doable ways of precisely inheriting Circle from


Ellipse if your domain and or use cases require that.

> This is precisely the point of the whole argument. The term ISA can
> be applied to various domains, like mathematics and geometry. There
> are concepts in those domains that can be mapped to software. A
> geometric circle can be mapped to become class Circle in a software
> application.

> ...However, the relationships in one domain may not map
> well into the software domain. The ISA relationship between Circle
> and Elipse in the geometry domain does not map well into the software
> and Elipse in the geometry domain does not map well into the software
> domain.

You have not shown us this at all.

Your faulty, technocratic world view that OO doesn't originate, or


exist in reality is what prompts you to periodically insist that
certain things can not be inherited from another.

But:
A.) you haven't demonstrated it, and
B.) if it really exists or is a good way to model a domain, and or


use cases it can be done with enough *fore*thought in design and

coding., and
C.) most OO "practioners" fundamentally see OO as Booch does in the


first 3 chapters of his OOA&D, which you have always disliked and
argued against.

Finally, given C.), anything you did contribute to Booch methodology

Mats Helander

unread,
Nov 21, 2001, 8:53:52 PM11/21/01
to
Now, this was thought provoking...

Just a thought though: the statement "A Dog is A Species" might not be
agreed upon so intuitively by non-OO:ers - perhaps we swallow statements
like that more easily because we are so used to the lack of better
resolution in the "is a" relationship?

/Best Regards, Mats Helander

Martin Fowler <fow...@acm.org> skrev i
diskussionsgruppsmeddelandet:3bfc6829.2405790624@news.ne.mediaone.net...

Mats Helander

unread,
Nov 21, 2001, 10:14:56 PM11/21/01
to
>
> Inheriting Circle from Ellipse can indeed work when properly designed
> and coded. The lines of approach taken by Cauvin and Helander are
> highly effective and doable ways of precisely inheriting Circle from
> Ellipse if your domain and or use cases require that.

It is a very important extention you add that I forgot in my post, the "if
your domain and or use cases require that"...

That's what it's all about.

/Best Regards, Mats Helander


@objectmentor.com Robert C. Martin

unread,
Nov 22, 2001, 12:25:33 PM11/22/01
to

It means "is a member of the set of"

A bird is a member of the set of living organisms.
A mouse is a member of the set of mammals.
etc...

Shayne Wissler

unread,
Nov 22, 2001, 1:10:38 PM11/22/01
to

"Robert C. Martin" <rmartin @ objectmentor . com> wrote in message
news:s5dqvt8fu0r6udg3p...@4ax.com...

> >* - A bird is a living organism.
> > - A mouse is a mammal.
> > - A toyota celica is a car.
> > - A car is a vehicle.
> >
> >Now, precisely what do you think this sense of "is a" means?
>
> It means "is a member of the set of"
>
> A bird is a member of the set of living organisms.
> A mouse is a member of the set of mammals.
> etc...

I think that meaning should do. So what's wrong with that sense as it
applies to inheritance? Is it that you don't see how to apply it, or is
there some other issue?


Shayne Wissler

Universe

unread,
Nov 22, 2001, 8:26:20 PM11/22/01
to
"Shayne Wissler" <thal...@yahoo.com> wrote:

><univ...@radix.UNDOnet> wrote in message

>> Shayne Wissler <thal...@yahoo.com> wrote:

>> > "Robert C. Martin" <rmartin @ objectmentor . com> wrote in message
>> >

>> >> If you define "isa" to mean LSP then the issue goes away. If, on the
>> >> other hand, you define ISA to mean "is a" as in english; and then
>> >> equate it to inheritance, you end up with circle/elipse problems.

>> > What do you think "is a" in English means?

>> Good point. Commonality is commonality, is commonality.

>Right--though I'd use the term "similarity." Commonality denotes common
>parts, whereas "is a" implies similarity.

I see that the concept of "commonality" underlies that of
"similarity". You can base "similarity" upon "commonality", but not
"commonality" upon "similarity", as I see it.

Things that are similar are similar because in some way they have
properties or features which can be abstracted out, to at minimum a
very basic, simple (high level) commonality.

Elliott
--
http://www.radix.net/~universe ~*~ Enjoy! ~*~
Hail OO Modelling! * Hail the Wireless Web!

@Elliott 2001 my comments ~ newsgroups+bitnet quote ok

@objectmentor.com Robert C. Martin

unread,
Nov 23, 2001, 1:04:57 AM11/23/01
to

Inheritance is not equivalent to set membership. Inheritance is a
relationship between two classes whereby the variables and functions
of the base class are accessible to the derived class as though they
were defined within the derived class.

One can say that all derivatives are members of the set of classes
that have the variables and functions of their base class. However
this is a very constrained form of set membership. No such constraint
is implied by "isa". Thus, while we can say that all circles are
elements of the set of all elipses, we cannot use that as proof, or
even evidence, that inheritance can or ought to be used between the
software class that represents a circle, and the software class that
represents an elipse.

The LSP further constrains those classes that conform to it, by
insisting that all derived classes be members of the set of classes
that can be used by clients of the base class. But once again this is
a very constrained form of set membership, and does not mean that all
ISA relationships can, or should, be represented by inheritance.

Graham Perkins

unread,
Nov 23, 2001, 6:29:36 AM11/23/01
to
> >Moreover, I see you can override any method and declare

> >different visibility in the derived class.
> >
> >What is the point? If you're reducing the visibility,
> >client can simply upcast to increase again.
>
> You can increase the accessibility of an element of a derivative; but
> you cannot decrease it. That is, you cannot make an inherited member
> less accessible than it's base.

Yes, I know that is the sensible language design decision, and the
one that Java and Eiffel enforce. But for C++ the ARM says otherwise,
and gives an example in which a public method is overriden as private.
It is then inaccessible to clients of the derived class unless they
upcast.

Perhaps I have an out-of-date edition :-(


-------------+ http:/www.gperkins.co.uk/

Graham Perkins

unread,
Nov 23, 2001, 6:43:39 AM11/23/01
to
Mats Helander wrote:

> If I get this right, that means that:
> myInstance.doStuff()
> is in reality:
> ClassOfMyInstance.doStuff(this) 'static method
> where myInstance is passed to the 'this' parameter?

Yes. Just about. That is the effect. But you could not
simulate objects directly in a modular language with such
a direct substitution. Between "myInstance.doStuff()" and
"ClassOfMyInstance.doStuff( myInstance )" there is the
problem of finding what exactly is the class of myInstance.

> Aha! So for a non-overriden inherited method, the virtual method table
> points to the same address as for the method in the superclass, right? Thus
> Scott Ambler's remark earlier that the "delegation" approach will cost an
> extra jump for methods?

Yes. With dynamic binding, every function call is a "gosub" to
an address retrieved from the VMT. Whereas in static binding each
function call is a gosub to an address known at compile time.

ISE's Eiffel compiler is very good at optimising many apparently
polymorphic calls into static binding.

The smalltalk approach has to be different since its dynamic
nature prevents compile-time analysis of static/dynamic binding.
However, at runtime the various loaders and JIT native coders
can "corral" lumps of code and optimise it.

[ re: runtime editing ]


> I created a (rather simple) OO system that allowed you to do that. The
> lesson I learned was to never use something like that again! ;-) No,
> seriously, it works fine for RAD prototyping, but IMO it's not as useful for
> something that you're actually gonna deploy.

I think smalltalkers would disagree!
For a start, the iterative prototyping approach can be used
for real development, not just RAD prototyping. Eg, see the
Objectory methodology. One thing I really like is that it
is extremely easy to develop deliverable code and test drivers
in parallel. In particular, we can build an object structure
to run tests against, and keep testing as we add more methods.
No need to rebuild the entire target object structure every
time we edit/add the methods.

And for another, the ability to update a system while it is
executing is quite an asset in some circumstances.


-------------+ http:/www.gperkins.co.uk/

Mats Helander

unread,
Nov 23, 2001, 5:09:50 AM11/23/01
to

Graham Perkins <gper...@gperkins.co.uk> skrev i
diskussionsgruppsmeddelandet:3BFE366B...@gperkins.co.uk...

> Mats Helander wrote:
>
> > If I get this right, that means that:
> > myInstance.doStuff()
> > is in reality:
> > ClassOfMyInstance.doStuff(this) 'static method
> > where myInstance is passed to the 'this' parameter?
>
> Yes. Just about. That is the effect. But you could not
> simulate objects directly in a modular language with such
> a direct substitution. Between "myInstance.doStuff()" and
> "ClassOfMyInstance.doStuff( myInstance )" there is the
> problem of finding what exactly is the class of myInstance.

Right....Well I guess you'd be able to do it by using a cetral dispatcher
and add some maniac global hash list for associating variables with "made-up
types" (for the dispatcher to use), but hey....I'm glad I don't have to. But
I take your point to be "It's not exactly fair to call
'myInstance.doStuff()' a pure 'syntactig suger' improvement over
'ClassOfMyInstance.doStuff( myInstance )'", which I duely note...

> > Aha! So for a non-overriden inherited method, the virtual method table
> > points to the same address as for the method in the superclass, right?
Thus
> > Scott Ambler's remark earlier that the "delegation" approach will cost
an
> > extra jump for methods?
>
> Yes. With dynamic binding, every function call is a "gosub" to
> an address retrieved from the VMT. Whereas in static binding each
> function call is a gosub to an address known at compile time.
>
> ISE's Eiffel compiler is very good at optimising many apparently
> polymorphic calls into static binding.
>
> The smalltalk approach has to be different since its dynamic
> nature prevents compile-time analysis of static/dynamic binding.
> However, at runtime the various loaders and JIT native coders
> can "corral" lumps of code and optimise it.

How do they do that? Do they guess based on previous uses of the code, and
then discard the guesses if there is unanticipated use? If I get you right,
you're saying that the JIT compilers will "pre-bind" loosely bound types
(basically, guess which VMT to use) in order to gain speed...or did I get it
wrong?

> [ re: runtime editing ]
> > I created a (rather simple) OO system that allowed you to do that. The
> > lesson I learned was to never use something like that again! ;-) No,
> > seriously, it works fine for RAD prototyping, but IMO it's not as useful
for
> > something that you're actually gonna deploy.
>
> I think smalltalkers would disagree!
> For a start, the iterative prototyping approach can be used
> for real development, not just RAD prototyping. Eg, see the
> Objectory methodology. One thing I really like is that it
> is extremely easy to develop deliverable code and test drivers
> in parallel. In particular, we can build an object structure
> to run tests against, and keep testing as we add more methods.
> No need to rebuild the entire target object structure every
> time we edit/add the methods.
>
> And for another, the ability to update a system while it is
> executing is quite an asset in some circumstances.

Well, the OO system is still used by happy customers, and it sure is fun
when some of them (still) call and wants updates that I can do it (add and
modify classes and objects) from home directly in my browser while their
system is still running....so, OK, it's useful. And anyway, I really like
using tools like that to keep a "RAD version" of my project in which I do
most of the experimenting.

Thanks again for all the help!

/Best Regards, Mats Helander

>
> -------------+ http:/www.gperkins.co.uk/


S Perryman

unread,
Nov 18, 2001, 6:20:10 PM11/18/01
to

Robert C. Martin <rmartin @ objectmentor . com> wrote in message
news:uq6ovtskv7bqsqv0c...@4ax.com...

>folks who insist that Circle classes must inherit from Elipse
>classes are confusing geometric shapes with software.

>This is precisely the point of the whole argument. The term ISA can
>be applied to various domains, like mathematics and geometry. There
>are concepts in those domains that can be mapped to software. A
>geometric circle can be mapped to become class Circle in a software
>application. However, the relationships in one domain may not map
>well into the software domain. The ISA relationship between Circle
>and Elipse in the geometry domain does not map well into the software
>domain.

The ISA relationship maps very well indeed to the impl space.

I have no problems doing so, and I have yet to be presented with any
'posers' on the circle/ellipse topic that cannot be easily swept away
with simple and elegant solutions, Or by actually applying the
*fundamentals* of CS + sw eng. However, I have seen people
proclaim things that show a misunderstanding of the fundamentals.


Regards,
Steven Perryman


Dave Harris

unread,
Nov 23, 2001, 9:32:00 AM11/23/01
to
rmartin @ objectmentor . com (Robert C. Martin) wrote (abridged):

> You can increase the accessibility of an element of a derivative; but
> you cannot decrease it. That is, you cannot make an inherited member
> less accessible than it's base.

You can in C++. Eg:

class Base
{
public:
virtual void member();
};

class Derived : public Base
{
private:
virtual void member();
};

void test()
{
Derived d;
// d.member(); // Won't compile.
Base &b = d;
b.member();
}

This compiles. Removing the "virtual" makes no difference. If we uncomment
the commented line, it won't compile because D::member() really is
private.

The next two lines show that, as Graham Perkins says, the protection isn't
reliable as the member is accessable via the base class, without needing
to use a cast or other nasty tricks.

Dave Harris, Nottingham, UK | "Weave a circle round him thrice,
bran...@cix.co.uk | And close your eyes with holy dread,
| For he on honey dew hath fed
http://www.bhresearch.co.uk/ | And drunk the milk of Paradise."

Dave Harris

unread,
Nov 23, 2001, 9:32:00 AM11/23/01
to
ma...@urbantalk.se (Mats Helander) wrote (abridged):

> The basic idea is this: Could you have some sort of "conditional" or
> "dynamic" types?

Yes. The language Cecil has these under the name "predicate type". It has
been discussed here before. I expect a search for those words will turn up
more.

Mats Helander

unread,
Nov 23, 2001, 7:41:38 AM11/23/01