Inheritance and abstract classes

T

Tony Johansson

Hello!

Assume you have an abstract class called Body and a derived class called
cylinder.
When you have an abstract class you can't instansiate an object.
As you can see in the abstract class there are one data member called
density that you can't access because there will not be any object of class
Body. The data member density will be inheritated and all the member
functions.
So when you have an instance of class Cylinder and you access setDensity you
will access the density that is inheritated from Body.

Now to my question: When you can't access any data member in an abstact
class is it then any point to declare any data member in such class. Why not
just declare them in the derived class instead?

class Body
{
public
virtual ~Body(){}
virtual const double getVolume() const = 0;
virtual const double getArea() const = 0;
double getDensity();
void setDensity(double);

private:
int density;
};

class Cylinder : public Body
{
public:
virtual const double getVolume();
virtual const double getArea();

private:
double radie, length;
};

//Tony
 
R

Rolf Magnus

Tony said:
Hello!

Assume you have an abstract class called Body and a derived class called
cylinder.
When you have an abstract class you can't instansiate an object.
Right.

As you can see in the abstract class there are one data member called
density that you can't access because there will not be any object of
class Body.

Well, each Cylinder is also a Body.
The data member density will be inheritated and all the member
functions.
So when you have an instance of class Cylinder and you access setDensity
you will access the density that is inheritated from Body.
Yes.

Now to my question: When you can't access any data member in an abstact
class is it then any point to declare any data member in such class. Why
not just declare them in the derived class instead?

A good thing about deriving from a class is that you inherit members so you
can put everything in the base class that is shared between all classes
derived from it. This is also true in this case. If every class derived
from Body has a density, why put it in each class separately? Just put it
once in the base class, and all the others inherit it.
Consequently, if each derived class has its own getDensity() and
setDensity(), you cannot call those functions through a pointer or
reference to Body, since Body doesn't have them. You'd always need to know
the right class and cast to that class.
 
C

codigo

Tony Johansson said:
Hello!

Assume you have an abstract class called Body and a derived class called
cylinder.
When you have an abstract class you can't instansiate an object.
As you can see in the abstract class there are one data member called
density that you can't access because there will not be any object of class
Body. The data member density will be inheritated and all the member
functions.
So when you have an instance of class Cylinder and you access setDensity you
will access the density that is inheritated from Body.

Now to my question: When you can't access any data member in an abstact
class is it then any point to declare any data member in such class. Why not
just declare them in the derived class instead?

You certainly can access an abstract class's members and member functions.

The key is how you invoke the abstract ctor in the derived ctor's
initialisation list in order to generate a Cylinder instance.

Defining the abstract's pure-virtual member function(s) will save having to
provide that code in each derivative. The derived instance needs only call
the abstract base class's pure-virtual member functions with access
specifiers (ie: Body::getVolume()). See getVolume() in Body and Cylinder
below...

The abstract class is no longer abstract once its been derived from and an
instance of the derived type is instantiated (abstract means "i can't exist
*unless* i'm inherited"). Also, nothing prevents you from defining the body
of a pure-virtual member-function (unlike Java's interface). The abstract
concept only applies to the instantiation of an abstract type itself. Not to
a derivative.

Note the output of the allocation invocations for Body and Cylinder.
Cylinder calculates the volume for the Body base using the Cylinder's ctor's
initialization list. Now its a tad easier to then derive from Body to create
a Block or Wedge class.

#include <iostream>
using std::cout;
using std::endl;

class Body
{
double density;
double volume;
public:
Body(double d, double v)
: density(d), volume(v) // init list
{
cout << "Body ctor invoked\n";
}
virtual ~Body()
{
cout << "Body d~tor invoked\n";
}
// member functions
double getDensity() const
{
return density;
};
virtual double getVolume() const = 0
{
return volume;
};
}; // abstract class Body

class Cylinder : public Body
{
double radie;
double length;
public:
Cylinder(double d, double r, double l)
: Body(d, 3.1416 * r * r * l),
radie(r), length(l) // init list
{
cout << "Cylinder ctor invoked\n";
}
virtual ~Cylinder()
{
cout << "Cylinder d~tor invoked\n";
}
// member functions
double getVolume() const
{
return Body::getVolume(); // by access specifier
}
}; // class Cylinder

int main()
{
// Cylinder(density, radius, length)
Cylinder cylinder(1.4, 8.0, 16.0);

cout << "density = " << cylinder.getDensity();
cout << endl;
cout << "volume = " << cylinder.getVolume();
cout << endl;

return 0;
}
 
C

Cy Edmunds

Tony Johansson said:
Hello!

Assume you have an abstract class called Body and a derived class called
cylinder.
When you have an abstract class you can't instansiate an object.
As you can see in the abstract class there are one data member called
density that you can't access because there will not be any object of
class Body. The data member density will be inheritated and all the member
functions.
So when you have an instance of class Cylinder and you access setDensity
you will access the density that is inheritated from Body.

Now to my question: When you can't access any data member in an abstact
class is it then any point to declare any data member in such class. Why
not just declare them in the derived class instead?

class Body
{
public
virtual ~Body(){}
virtual const double getVolume() const = 0;
virtual const double getArea() const = 0;
double getDensity();
void setDensity(double);

private:
int density;
};

Now everybody who uses Body as a base class has to use your implementation
of getDensity(). What do you care how it's implemented? An abstract class
should be abstract: no constructor, no data items, and no non-virtual
methods. Of course sometimes you would like to provide a partial
implementation as a convenience. But you can have your cake and eat it too:

class Body
{
public: // note the colon
virtual ~Body() {}
virtual double getVolume() const = 0; // no need for const double
virtual double getArea() const = 0;
virtual double getDensity() const = 0; // should be const method
};

class BaseBody : public Body
{
private:
double m_density;
public:
BaseBody(double i_density=0.0) : m_density(i_density) {}
void setDensity(double i_density) {m_density = i_density;}
virtual double getDensity() const {return m_density;}
};

Now your client can use BaseBody if he is satisfied with your implementation
but can also derive directly from Body.

[snip]
 

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

Forum statistics

Threads
473,768
Messages
2,569,575
Members
45,051
Latest member
CarleyMcCr

Latest Threads

Top