"is A" VS "is Like A" relationships, what does each one mean and how do they differ?
Asked Answered
M

1

6

First an example to discuss:

class Foo
{
    // Attributes:
    int attribute1, attribute2;

    // Methods:
    virtual void Foo1()
    {   /* With or without Implementation   */  }
    virtual void Foo2()
    {   /* Also with or without Implementation */ }
};

class ExactDuplicate: Foo   // No New Attributes or Methods
{   
    virtual void Foo1()
    {   /* A new Implementation */  }

    // Also there might be new Implementations to other methods
};

class ExtraMethods: Foo     // Having New Methods
{
    virtual void Foo3()
    {   /* Implementation   */  }
};

class ExtraAttributes: Foo  // Having New Attributes
{
    int attribute3;
};

I had a discussion -with my teacher- about the "is A" and the "is Like A" relationships and how do they differ.

My Opinion (which I read somewhere I can't remember) is that the "is A" relationship is between a Parent Class and a Child Class which is inherited form it, and it's not affected by adding new methods or attributes, so any instance from the child class "is A" Parent class, in the above exmple, every ExactDuplicate, ExtraMethods, or ExtraAttributes "is A" Foo. While the "is Like A" relationship is between two Child classes inherited from the same Parent class, in the above exmple, every ExactDuplicate "is Like" every ExtraMethods or ExtraAttributes, and the reverse.

My Teacher's Opinion was that the "is A" relationship is between a Parent Class and only the Child classes which do not add any extra methods or attributes, so in the above example there is only one "is A" relationship between Foo and ExactDuplicate. While the "is Like A" relationship is between a Parent Class and the Child Classes which add extra methods or attributes, so in the above example, there is an "is Like A" relationship between Foo and each of ExtraMethods and ExtraAttributes.

I think that, the "is A" relationship as defined by my teacher is not really useful because in most cases there is no reason to change the implementation if nothing is added. This is a point. Another, a Car "is NOT Like a" Vehicle, it actually "is A" Vehicle, while a Van "is Like A" Car, since both associate some characteristics.

So which is correct and why?, I would highly appreciate explaining.

Also if my teacher's opinion is the true one, does adding only Attributes make the relationship an "is Like A" relationship, or it needs adding new methods to become an "is Like A" relationship? and what (if exists) is the relationship between the Child Classes.

Hope my questoin is clear and understandable.

Any Help would be Greatly Appreciated :)

Merras answered 4/10, 2011 at 19:41 Comment(0)
I
3

As the terms are typically used, you're right and your teacher's wrong.

Is-A does allow extension. The child can have attributes, operations, etc., not allowed by the parent. From an OOP point of view, the crucial point is that an instance of the child can be used in place of an instance of the parent under any circumstance (Edit: which, yes, I should probably mention is called the Liskov Substitution Principle, often abbreviated to LSP, named after its originator Barbara Liskov).

Is-like-A is used mostly to describe mistakes -- when somebody tries to have square inherit from rectangle (or vice versa), for an obvious example. Neither is really an extension of the other, because neither has all the characteristics of the other. Neither should inherit from the other because there may be a circumstance in which substituting one for the other either doesn't work (the proposed child doesn't meet the requirements of being a parent) or could break something (a change allowed by the parent would break an invariant of the child).

Iberian answered 4/10, 2011 at 19:48 Comment(6)
Definitely, all subclasses have the "is a" relationship with the parent class. You can use a parent class reference for a subclass, so it fits the bill. It "is a" instance of the parent class.Skirting
it is called a Liskov Substitution Principle, googling it will give you more details.Tenpenny
Well mathematically speaking a square "is a" rectangle, however inheritence doesn't work so well when restricting rather than extending.Haphazard
(also, correct me if I'm wrong, but doesn't the square inherits from rectangle only fail the LSP if mutability is involved?)Haphazard
An immutable Square could be defined as a subtype of an immutable Rectangle. It most likely wouldn't save any space, since the rectangle would need height and width fields, and subtypes can't omit fields from their parent types, but such a subtype could be useful if there were operations that could be done on squares that couldn't be done on rectangles. The only potential trickiness would concern equality, since a square would most likely be considered "unequal" to a rectangle with similar properties.Whitefish
@Davy8: Yes, if make them immutable, you can get away with more substitutions like square/rectangle and circle/ellipse. I don't really like doing this, but it can be made to work (at least maintain class invariants).Iberian

© 2022 - 2024 — McMap. All rights reserved.