Ale
Ale

Reputation: 23

Is this a correct approach of using abstract classes with an OO approach?

Say we have 2 classes A and B. Both are subclasses of C, the superclass. Now let's assume that C defines a method areYouA(), that is a method that asks the object if it's an object of the A class.

So a possible code, in c++, would be:

C object1 = A()

C object2 = B()

if (object1.areYouA()==true){//crazy code here regarding if it's an A object}

if (object2.areYouA()==false){//crazy code here regarding if it's a B object}

From an OO POV is it correct to add a method to the B and C classes to ask their respective objects if they're of the A class??? If it's not correct, then what could be another approach to this???? My objective is obvious i have 2 classes A and B that i need, at some point i have portions of binary data that could be of the A class or the B class, also an object would initially be of the A class, as it gets full, it's structure needs to change and also some of it's behaviour, therefore becoming an object of the B class. So my approach to this was thinking of an abstract class as parent, and initially declaring a C object but storing an A object, and later storing a B object as it changes. Is there another approch to this, like a pattern???

ADDITIONAL INFO:

I think i wasnt very clear about this. Let's say i want to store information from an A object in file1, and info from a B object in file2. If use its mother class as an interface, then how can i tell if it's an A object or a B object to store in the respective files?? Should i add an atribute to each object for their filename they belong too??? That means if i need to change the name of the file, then every object needs to change too.

Upvotes: 1

Views: 104

Answers (3)

Luchian Grigore
Luchian Grigore

Reputation: 258618

First off,

C object1 = A();
C object2 = B();

slices the objects. They are no longer of type A or B, they are C.

You can use pointer for this:

C* object1 = new A();
C* object2 = new B();

Although C pointers, they point to instances of A and B respectively.

Second, your approach is wrong. It seems like you're not taking advantage of polymorphism. If you have functionality that is shared between the classes, it should be implemented in C. If it changes, you should have virtual methods.

Knowledge about the type of an object is usually at least a code smell. You can alter the behavior simply by using polymorphism. Although if it really is necessary, the correct way would be using dynamic_cast:

C* object1 = new A();
A* pA = dynamic_cast<A*>(object1);

pA will be NULL if object1 doesn't point to an object of type A.

Upvotes: 4

Kerrek SB
Kerrek SB

Reputation: 477338

The correct way is to use virtual functions to implement polymorphic behaviour:

struct C
{
    virtual void do_crazy_stuff() { } // (see text below)
    virtual ~C() { }                  // always have a virtual d'tor for polymorphic bases
};

struct A : C
{
    virtual void do_crazy_stuff() { /* your crazy code for A */ }
};

struct B : C
{
    virtual void do_crazy_stuff() { /* your crazy code for B */ }
};

Now you can use the same interface everywhere:

void process_data(C & x)  // <-- Note: take argument by reference!!
{
    x.do_crazy_stuff();
}

This works on any object of a type derived from C:

int main()
{
    A x;
    B y;
    process_data(x);  // calls x.A::do_crazy_stuff
    process_data(y);  // calls x.B::do_crazy_stuff
}

If you like, you can even declare the base function C::do_crazy_stuff as pure virtual; this makes the base class abstract (so it cannot be instantiated).

Upvotes: 4

AlexTheo
AlexTheo

Reputation: 4184

This is a design issue in my opinion you have to analyze your problem better. Why do you need to know the type of your object? Why you don't implement the interface method in your A and B classes, which will do whatever you need with a binary data? Take a look on visitor design pattern to get an image of how to implement it in this way.

Upvotes: 1

Related Questions