473,395 Members | 1,466 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,395 software developers and data experts.

Is adding public methods to base classes bad design?

Hi All,
Sorry if this is off topic, but I could not seem to find a suitable OO
Design newsgroup. If there is one feel free to let me know.

Here is a simplification of a general design problem I face.

Say you have:

class Car {
virtual void speedup();
virtual void slowdown();
};

class BondCar {
virtual void self_destruct();
};

Now storing a std::list<Car *> and calling speedup/slowdown is fine, however
if you wanted to self_destruct all BondCars in the list I can think of a few
ways to do it:

1) Use dynamic_cast, this is obviously not a good solution for more complex
designs.
2) Bring self_destruct down into the base class, making a 'fat' interface
3) Storing two lists, one std::list<Car *> and the other std::list<BondCar
*>, but then if I want to speed up all cars I have to iterate over two lists

None of these solutions seems very well suited to more complex designs, and
I have come across this problem over and over again. As it says in the c++
faq lite, inheritance is for old code to call new code, and NOT for code
reuse, so it almost seems to me that adding new public methods to derived
classes is wrong.

Could someone please enlighten me?
Andy
Jul 19 '05 #1
5 2414

Andrew Ward <an***@ihug.co.nz> wrote in message
news:EP**********************@news.xtra.co.nz...
Hi All,
Sorry if this is off topic, but I could not seem to find a suitable OO
Design newsgroup. If there is one feel free to let me know.
comp.object
Here is a simplification of a general design problem I face.

Say you have:

class Car {
virtual void speedup();
virtual void slowdown();
};

class BondCar {
virtual void self_destruct();
};

Now storing a std::list<Car *> and calling speedup/slowdown is fine,
No it isn't. Those members are private.
however
if you wanted to self_destruct all BondCars in the list I can think of a few ways to do it:

1) Use dynamic_cast, this is obviously not a good solution for more complex designs.
I always wince at having any dynamic_cast, but it's still the best of a bad
choice of solutions in some cases.
2) Bring self_destruct down into the base class, making a 'fat' interface
If 'self_destruct' makes sense for all Cars, then it should be in Car. If it
only makes sense for BondCars, then it should only be in BondCar. I don't
think its location should be dictated by your application without regard for
its proper place. I don't have a problem with "fat" interfaces. In fact, the
more abstract the class in which you can put a member, the better, as long
as the member makes sense in that class.
3) Storing two lists, one std::list<Car *> and the other std::list<BondCar
*>, but then if I want to speed up all cars I have to iterate over two lists

A variation on 3) is to have one list with all Cars, including BondCars, and
another with just BondCars. It's harder to delete a BondCar, as it has to be
removed from both lists, but you don't need any downcasts and you don't need
to put members in the wrong class.

It's impossible to choose without knowing your application better.
None of these solutions seems very well suited to more complex designs, and I have come across this problem over and over again. As it says in the c++
faq lite, inheritance is for old code to call new code, and NOT for code
reuse, so it almost seems to me that adding new public methods to derived
classes is wrong.
I thought it was to represent IS-A relationships, but maybe I'm behind the
times.

There's nothing wrong with adding anything to anything as long as it solves
your problem, makes sense, and doesn't cause a maintenance nightmare.
Could someone please enlighten me?


That's about the best I can do.

DW

Jul 19 '05 #2

"Andrew Ward" <an***@ihug.co.nz> wrote in message
news:EP**********************@news.xtra.co.nz...
Hi All,
Sorry if this is off topic, but I could not seem to find a suitable OO
Design newsgroup. If there is one feel free to let me know.

Here is a simplification of a general design problem I face.

Say you have:

class Car {
virtual void speedup();
virtual void slowdown();
};

class BondCar {
virtual void self_destruct();
};
I'm assuming those are supposed to be public functions.
Now storing a std::list<Car *> and calling speedup/slowdown is fine, however if you wanted to self_destruct all BondCars in the list I can think of a few ways to do it:
First, I think you should take a step back and ask yourself about the
implications of a design where you would even consider having a list of base
class objects, and then attempting to do subclass functions on only some of
those objects. This isn't a trivial subject.
None of these solutions seems very well suited to more complex designs, and I have come across this problem over and over again. As it says in the c++
faq lite, inheritance is for old code to call new code, and NOT for code
reuse, so it almost seems to me that adding new public methods to derived
classes is wrong.


Generally speaking, I can't imagine why public methods in subclasses could
be wrong. Inheritance is used often, even when there is no such thing as
"old" code and "new" code. i.e. it's used right in the original design.
Anyway, I don't think you have a fundamental OO problem with inheritance, I
think you have a specific design issue related to lists of things. You can
do more reading in this area. The C++ FAQs book by Cline is a short start
(is bag-of-apple a kind-of bag-of-fruit?, etc.)
Jul 19 '05 #3
"Andrew Ward" <an***@ihug.co.nz> wrote in message
news:EP**********************@news.xtra.co.nz...
Hi All,
Sorry if this is off topic, but I could not seem to find a suitable OO
Design newsgroup. If there is one feel free to let me know.

Here is a simplification of a general design problem I face.

Say you have:

class Car {
virtual void speedup();
virtual void slowdown();
};

class BondCar {
virtual void self_destruct();
};

Now storing a std::list<Car *> and calling speedup/slowdown is fine, however
if you wanted to self_destruct all BondCars in the list I can think of a few
ways to do it:

1) Use dynamic_cast, this is obviously not a good solution for more complex
designs.
2) Bring self_destruct down into the base class, making a 'fat' interface
3) Storing two lists, one std::list<Car *> and the other std::list<BondCar
*>, but then if I want to speed up all cars I have to iterate over two lists

None of these solutions seems very well suited to more complex designs, and
I have come across this problem over and over again. As it says in the c++
faq lite, inheritance is for old code to call new code, and NOT for code
reuse, so it almost seems to me that adding new public methods to derived
classes is wrong.

Could someone please enlighten me?
Andy


I've encountered a similar situation where self_destruct() makes sense only
for BondCar. I'm considering introduction of a member which tells me to what
class a specific object belongs. Then I can check the member before applying
self_destruct() to an object. It's not the OO way, my code would look ugly,
but I expect it'll work. Any suggestion please?

--
ES Kim
Jul 19 '05 #4

"ES Kim" <es***@svd.co.kr> wrote in message
news:bi**********@news1.kornet.net...
"Andrew Ward" <an***@ihug.co.nz> wrote in message
news:EP**********************@news.xtra.co.nz...
Hi All,
Sorry if this is off topic, but I could not seem to find a suitable OO
Design newsgroup. If there is one feel free to let me know.

Here is a simplification of a general design problem I face.

Say you have:

class Car {
virtual void speedup();
virtual void slowdown();
};

class BondCar {
virtual void self_destruct();
};

Now storing a std::list<Car *> and calling speedup/slowdown is fine, however if you wanted to self_destruct all BondCars in the list I can think of a few ways to do it:

1) Use dynamic_cast, this is obviously not a good solution for more complex designs.
2) Bring self_destruct down into the base class, making a 'fat' interface 3) Storing two lists, one std::list<Car *> and the other std::list<BondCar *>, but then if I want to speed up all cars I have to iterate over two lists
None of these solutions seems very well suited to more complex designs, and I have come across this problem over and over again. As it says in the c++ faq lite, inheritance is for old code to call new code, and NOT for code
reuse, so it almost seems to me that adding new public methods to derived classes is wrong.

Could someone please enlighten me?
Andy
I've encountered a similar situation where self_destruct() makes sense

only for BondCar. I'm considering introduction of a member which tells me to what class a specific object belongs. Then I can check the member before applying self_destruct() to an object. It's not the OO way, my code would look ugly, but I expect it'll work. Any suggestion please?


It would be better to use dynamic_cast.

john
Jul 19 '05 #5
"ak" <ak @ workmail.com> wrote in message
news:ra********************************@4ax.com...
On Fri, 22 Aug 2003 14:01:13 +1200, "Andrew Ward" <an***@ihug.co.nz> wrote:
|1) Use dynamic_cast, this is obviously not a good solution for more complex |designs.
|2) Bring self_destruct down into the base class, making a 'fat' interface
|3) Storing two lists, one std::list<Car *> and the other std::list<BondCar |*>, but then if I want to speed up all cars I have to iterate over two lists |
|None of these solutions seems very well suited to more complex designs, and |I have come across this problem over and over again. As it says in the c++ |faq lite, inheritance is for old code to call new code, and NOT for code
|reuse, so it almost seems to me that adding new public methods to derived
|classes is wrong.
I would go for (2), having a virtual self_destruct() in base class which does nothing but implemented in the derived class.


So where you have:
pCar->self_destruct();

the car will refuse unless it's a BondCar? A self-destruct that leaves the
car intact.

DW

Jul 19 '05 #6

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

19
by: qazmlp | last post by:
class base { // other members public: virtual ~base() { } virtual void virtualMethod1()=0 ; virtual void virtualMethod2()=0 ; virtual void virtualMethod3()=0 ;
175
by: Ken Brady | last post by:
I'm on a team building some class libraries to be used by many other projects. Some members of our team insist that "All public methods should be virtual" just in case "anything needs to be...
3
by: MIGUEL | last post by:
Hi all, I'm quite lost with how adding web references to a project creates proxy classes. I've developed a web service with two classes inside and that contains three references to three...
34
by: Asfand Yar Qazi | last post by:
Hi, I'm creating a library where several classes are intertwined rather tightly. I'm thinking of making them all use pimpls, so that these circular dependancies can be avoided easily, and I'm...
86
by: jopperdepopper | last post by:
Hi, finally giving php 5 a go, and going over the new approach to classes. Can someone clarify the public, private and protected to me? I quote the php manual: "The visibility of a property or...
11
by: Pete Kane | last post by:
Hi All, does anyone know how to add TabPages of ones own classes at design time ? ideally when adding a new TabControl it would contain tab pages of my own classes, I know you can achieve this with...
12
by: Bob Jones | last post by:
I have an odd business requirement and I think that the implementation is not correct in the terms of OOP development. Any help on the concepts would be very appreciated! We currently have a...
23
by: Chris Gordon-Smith | last post by:
Hello All I have a base class called Action_Request, and a set of classes corresponding to different kinds of Action_Request, each of which inherits from Action_Request. Eg:- class ...
2
by: fgh.vbn.rty | last post by:
Hi, I'm not sure if i'm asking the question correctly but anyway here it is. Say I have 3 classes - class A, class B, class R. 1) A and B are the building blocks and R is like a repository...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.