Design problem with inheritance

  • Thread starter srinivasarao_moturu
  • Start date
S

srinivasarao_moturu

class ABC
{
public :
virtual void operation1();
virtual void operation2();
virtual int GetValue();
virtual char GetValue();
virtual void SetValue(int);
virtual void SetValue(char);
}

class intABC : public ABC
{
public :
virtual void operation1();
virtual void operation2();
void SetValue(int);
int GetValue();
private:
int val;
}

class charABC : public ABC
{
public :
virtual void operation1();
virtual void operation2();
void SetValue(char);
char GetValue();
private :
char val;
}

class Controler
{
public :
//constructors and destructors
void somefunc() //this function handles container member
private :
vector<ABC*> val;
}

client Controler class manipulates ABC derived classes polymorphically

I feel, In the above design surely it is not following Lispov
substitution principle.

here ABC is a fatty interface since intABC does not require char
version of get/set members
and charABC does not require int version of get/set members.

If I remove Get/Set members from ABC class and put int versions in
intABC and char versions in charABC then I have to use downcasting to
call specific versions.

so is there a good design to remove fatty interface from the ABC and at
the same time i should not use downcasting and another constraint is I
should use ABC polymorphically?

With Regards,
Sri.
 
M

mlimber

class ABC
{
public :
virtual void operation1();
virtual void operation2();
virtual int GetValue();
virtual char GetValue();
virtual void SetValue(int);
virtual void SetValue(char);

Don't forget the virtual destructor.
}

class intABC : public ABC
{
public :
virtual void operation1();
virtual void operation2();
void SetValue(int);
int GetValue();
private:
int val;
}

class charABC : public ABC
{
public :
virtual void operation1();
virtual void operation2();
void SetValue(char);
char GetValue();
private :
char val;
}

class Controler
{
public :
//constructors and destructors
void somefunc() //this function handles container member
private :
vector<ABC*> val;
}

client Controler class manipulates ABC derived classes polymorphically

I feel, In the above design surely it is not following Lispov
substitution principle.

here ABC is a fatty interface since intABC does not require char
version of get/set members
and charABC does not require int version of get/set members.

If I remove Get/Set members from ABC class and put int versions in
intABC and char versions in charABC then I have to use downcasting to
call specific versions.

so is there a good design to remove fatty interface from the ABC and at
the same time i should not use downcasting and another constraint is I
should use ABC polymorphically?

This is bad. You could use templates to make it better without doubling
the code to maintain.

template<typename T>
class ABC
{
public :
typedef T Type;

virtual void operation1() = 0;
virtual void operation2() = 0;
virtual Type GetValue() const = 0;
virtual void SetValue(Type) = 0;
};

class intABC : public ABC<int>
{
public :
virtual void operation1();
virtual void operation2();
virtual void SetValue(Type);
virtual Type GetValue() const;
private:
Type val;
};

Which could be used polymorphically like this:

template<typename T>
void Foo( const ABC<T>& abc )
{
abc.operation1();
cout << abc.GetValue() << endl;
}

Cheers! --M
 
J

joosteto

mlimber said:
template<typename T>
class ABC
{
public :
typedef T Type;

virtual void operation1() = 0;
virtual void operation2() = 0;
virtual Type GetValue() const = 0;
virtual void SetValue(Type) = 0;
};

class intABC : public ABC<int>
{
public :
virtual void operation1();
virtual void operation2();
virtual void SetValue(Type);
virtual Type GetValue() const;
private:
Type val;
};
But now intABC and charABC don't have the same base type anymore,
right? OP wanted to put pointers to intABC and charABC in one vector,
and I fail to see how the above makes that possible.
 
M

mlimber

But now intABC and charABC don't have the same base type anymore,
right? OP wanted to put pointers to intABC and charABC in one vector,
and I fail to see how the above makes that possible.

They don't, but static polymorphism can still be employed, as with my
Foo() function. There are other ways to solve the problem, of course,
but that one may work for the OP.

Cheers! --M
 
N

Noah Roberts

class ABC
{
public :
virtual void operation1();
virtual void operation2();
virtual int GetValue();
virtual char GetValue();

Can't be done. Can't overload return types of a function. A subclass
is allowed to override iff its new return type is a derivative of the
one it is overriding.
virtual void SetValue(int);
virtual void SetValue(char);
}

class intABC : public ABC
{
public :
virtual void operation1();
virtual void operation2();
void SetValue(int);
int GetValue();
private:
int val;
}

class charABC : public ABC
{
public :
virtual void operation1();
virtual void operation2();
void SetValue(char);
char GetValue();
private :
char val;
}

See what your plan is...don't do it. Not only because it would be
better with templates but because you should never have functions in a
base that are only used by some of its derivatives. A derivative
should use ALL of the interface of its base or it isn't a "base". In
other words, if you have a class named Vehicle and you have a function
"changeOil()" then a bicycle isn't a Vehicle because it has no engine
to put oil into (you can grease it but no oil). But if you have a base
class Vehicle and no "changeOil()" function in it you can have an
"Auto" class that does and then bicycle probably is a vehicle.

Public inheritance is always the IS-A relationship so these things are
important. Read about oop principles (search google for oop principles
- adding object mentor or wiki to the search string turns up good
sources).
class Controler
{
public :
//constructors and destructors
void somefunc() //this function handles container member
private :
vector<ABC*> val;
}

client Controler class manipulates ABC derived classes polymorphically

I feel, In the above design surely it is not following Lispov
substitution principle.

Definately not because your ABC derivatives are not ABCs.
here ABC is a fatty interface since intABC does not require char
version of get/set members
and charABC does not require int version of get/set members.

If I remove Get/Set members from ABC class and put int versions in
intABC and char versions in charABC then I have to use downcasting to
call specific versions.

so is there a good design to remove fatty interface from the ABC and at
the same time i should not use downcasting and another constraint is I
should use ABC polymorphically?

templates. If you really need run-time poly then this actually becomes
somewhat difficult to work out. I have a feeling though that templates
will do it for you.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,982
Messages
2,570,185
Members
46,736
Latest member
AdolphBig6

Latest Threads

Top