| re: Where to put attribute when using Inheritance
"Tony Johansson" <johansson.andersson@telia.com> wrote in message
news:lJ9ce.22851$d5.167648@newsb.telia.net...[color=blue]
> Hello!!
>
> Assume we have one base class called Vehicle and two derived classes[/color]
called[color=blue]
> Car and Bus.
> I would be able to call method getName on an object of class Car or Bus[/color]
and[color=blue]
> return back the name that is set for this class. Asking getName on an[/color]
object[color=blue]
> of class Vehicle is of no interest. Assume we have an attribute called[/color]
name[color=blue]
> of type string.
>
> Now to my question do you think it's right to put the name attribute in[/color]
each[color=blue]
> of class Car and Bus. I think so.
> I think putting the name attribute in class Vehicle is wrong because the
> name is different in class Car and Bus.[/color]
Nothing prevents you to support a common attribute and a specialized
attribute.
[color=blue]
>
> The name attribute is set in the c-tor for class Car and Bus.
> This getName is made pure virtual so polymorfism can be used to call the
> right getName depending of the object type
>
> I'm I right in my thoughts.
>
> Many thanks
> //Tony
>[/color]
Yes, your choice to place the name attribute in each derived class is an
option. Placing a common attribute in the abstract class is another option.
Same goes for an Engine class. Its a different Engine but its still an
Engine.
Since name isn't a clear attribute, lets consider a common license number
attribute for all vehicles. Let Cars have a car-type attribute and Trucks a
truck-classification attribute. I can implement the pure-virtual display()
member function, overload display() in both Car and truck and still call the
abstract display() through an access specifier.
// CarTest.cpp : Defines the entry point for the console application.
//
#include <iostream>
#include <string>
#include <vector>
using std::cout;
using std::endl;
class Vehicle
{
std::string m_license;
protected:
Vehicle(std::string s) : m_license(s) { }
public:
virtual ~Vehicle() { }
virtual void display() const = 0
{
cout << "vehicle license: " << m_license;
cout << "\t";
}
};
class Car : public Vehicle
{
std::string m_type;
public:
Car(std::string s, std::string t) : Vehicle(s), m_type(t) { }
~Car() { }
void display() const
{
Vehicle::display();
cout << "car type: " << m_type;
cout << endl;
}
};
class Truck : public Vehicle
{
std::string m_classification;
public:
Truck(std::string s, std::string t) : Vehicle(s), m_classification(t)
{ }
~Truck() { }
void display() const
{
Vehicle::display();
cout << "truck classification: " << m_classification;
cout << endl;
}
};
int main()
{
std::vector<Vehicle*> v_vehicles;
v_vehicles.push_back(new Car("M1111", "sportscar"));
v_vehicles.push_back(new Truck("G2222", "2 Tons"));
v_vehicles.push_back(new Car("L3333", "coupe"));
v_vehicles.push_back(new Truck("D4444", "4 Tons"));
typedef std::vector<Vehicle*>::iterator ITER;
ITER it = v_vehicles.begin();
for ( it = v_vehicles.begin(); it != v_vehicles.end(); ++it)
{
(*it)->display();
}
for ( it = v_vehicles.begin(); it != v_vehicles.end(); ++it)
{
delete *it;
}
return 0;
} |