Inheritance: "abstract objects"?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • J.M.

    Inheritance: "abstract objects"?

    I have a question concerning inheritance: can an abstract (parent) class
    have an abstract object? I would like to make a concrete child inherit from
    this class by inheriting from this object. Let me try to make this clear by
    example: The following should be "abstract".

    "class motor" is abstract because it has a virtual member
    "virtual int calculate_horse power() = 0"

    "class car" should have
    "motor M;"
    "void print_info(){.. . M.calculate_hor sepower(); ..... };"

    The following should be concrete:

    "class diesel_motor : class motor" and should implement
    "virtual int calculate_horse power(){ calculate hp for diesel };"

    "class diesel_car : class car"

    For this class, we should have an object "diesel_mot or M;" as a child of
    "motor M;". In other words, in diesel_car I need an object M as a
    diesel_motor, but in the class car, I only need those attributes of M
    associated with a motor.

    It seems something of this sort is not possible, so maybe there is a
    different solution. Let me indicate what I need:

    Every car has a motor, either of diesel or gasoline type. Calculating
    horsepower is different for each of these, but I want to implement this
    method only once, once for each type of motor. For every car, I want to
    print the same standardised specifications, so I want one method to do
    that. This method only uses methods in available for all motors. In making
    a class diesel_car, I need to have a diesel_motor, which is a child of
    motor.

    Obviously, I could just not have a motor in car, but I need this to define
    print_info() - and I do not want to define this in every child....

    I hope it is clear, what I need. Thanks for any help in advance.

    Jan
  • Rolf Magnus

    #2
    Re: Inheritance: "abstra ct objects"?

    J.M. wrote:
    [color=blue]
    > I have a question concerning inheritance: can an abstract (parent) class
    > have an abstract object?[/color]

    No. The whole idea of an abstract class is that it can't be instantiated.
    [color=blue]
    > I would like to make a concrete child inherit from this class by
    > inheriting from this object. Let me try to make this clear by example: The
    > following should be "abstract".
    >
    > "class motor" is abstract because it has a virtual member
    > "virtual int calculate_horse power() = 0"[/color]

    It is abstract because it has a _pure_ virtual member. Make it just virtual,
    and the class won't be abstract anymore. But I guess what you really want
    is not store a motor in your car, but rather a pointer to motor, like the
    following simplified example:

    #include <iostream>

    class motor
    {
    public:
    virtual int calculate_horse power() = 0;
    virtual ~motor() {}
    };

    class diesel_motor : public motor
    {
    public:
    virtual int calculate_horse power()
    {
    std::cout << "lots of horses in that diesel\n";
    return 300;
    }
    };

    class car
    {
    public:
    car(motor* M)
    :M_(M)
    {}

    void print_info()
    {
    std::cout << M_->calculate_hors epower() << "HP\n";
    }
    ~car() { delete M_; }
    private:
    motor* M_;
    };

    int main()
    {
    car mercedes(new diesel_motor);
    mercedes.print_ info();
    }

    [color=blue]
    > "class car" should have
    > "motor M;"
    > "void print_info(){.. . M.calculate_hor sepower(); ..... };"
    >
    > The following should be concrete:
    >
    > "class diesel_motor : class motor" and should implement
    > "virtual int calculate_horse power(){ calculate hp for diesel };"
    >
    > "class diesel_car : class car"
    >
    > For this class, we should have an object "diesel_mot or M;" as a child of
    > "motor M;". In other words, in diesel_car I need an object M as a
    > diesel_motor, but in the class car, I only need those attributes of M
    > associated with a motor.[/color]

    Well, if you want to instantiate motor, simply don't make it abstract.
    [color=blue]
    > It seems something of this sort is not possible, so maybe there is a
    > different solution. Let me indicate what I need:
    >
    > Every car has a motor, either of diesel or gasoline type. Calculating
    > horsepower is different for each of these, but I want to implement this
    > method only once, once for each type of motor. For every car, I want to
    > print the same standardised specifications, so I want one method to do
    > that. This method only uses methods in available for all motors. In making
    > a class diesel_car, I need to have a diesel_motor, which is a child of
    > motor.[/color]

    Why exactly do you need a diesel_car? Just let your car have a pointer to
    motor, and it can have any motor that you have a class for.

    Comment

    • J.M.

      #3
      Re: Inheritance: &quot;abstra ct objects&quot;?

      Rolf Magnus schrieb:

      Thanks for your response.

      [color=blue]
      > J.M. wrote:
      >[color=green]
      >> I have a question concerning inheritance: can an abstract (parent) class
      >> have an abstract object?[/color]
      >
      > No. The whole idea of an abstract class is that it can't be instantiated.[/color]

      Yup. I figured that much -- as I indicated, I did not expect that to
      work ;-)[color=blue]
      >[color=green]
      >> I would like to make a concrete child inherit from this class by
      >> inheriting from this object. Let me try to make this clear by example:
      >> The following should be "abstract".
      >>
      >> "class motor" is abstract because it has a virtual member
      >> "virtual int calculate_horse power() = 0"[/color]
      >
      > It is abstract because it has a _pure_ virtual member. Make it just
      > virtual, and the class won't be abstract anymore.[/color]

      That would work, but that would require some sort of implementation, would
      it not? But without knowing the type of motor, I can't calculate the
      horsepower....
      [color=blue]
      > But I guess what you
      > really want is not store a motor in your car, but rather a pointer to
      > motor,[/color]

      Actually, I would like to store the motor.. Granted, a pointer would work
      too, sort of.. see below.

      [zap example]
      [color=blue]
      >[color=green]
      >> "class car" should have
      >> "motor M;"
      >> "void print_info(){.. . M.calculate_hor sepower(); ..... };"
      >>
      >> The following should be concrete:
      >>
      >> "class diesel_motor : class motor" and should implement
      >> "virtual int calculate_horse power(){ calculate hp for diesel
      >> };"
      >>
      >> "class diesel_car : class car"
      >>
      >> For this class, we should have an object "diesel_mot or M;" as a child of
      >> "motor M;". In other words, in diesel_car I need an object M as a
      >> diesel_motor, but in the class car, I only need those attributes of M
      >> associated with a motor.[/color]
      >
      > Well, if you want to instantiate motor, simply don't make it abstract.[/color]

      Well, I don't "really" want to instantiate it - I want it to be part of an
      abstract class :)
      [color=blue]
      >[color=green]
      >> It seems something of this sort is not possible, so maybe there is a
      >> different solution. Let me indicate what I need:
      >>
      >> Every car has a motor, either of diesel or gasoline type. Calculating
      >> horsepower is different for each of these, but I want to implement this
      >> method only once, once for each type of motor. For every car, I want to
      >> print the same standardised specifications, so I want one method to do
      >> that. This method only uses methods in available for all motors. In
      >> making a class diesel_car, I need to have a diesel_motor, which is a
      >> child of motor.[/color]
      >
      > Why exactly do you need a diesel_car? Just let your car have a pointer to
      > motor, and it can have any motor that you have a class for.[/color]

      Well, the class diesel_car and gasoline_car would have specific methods that
      car (or motor) would not have. For example
      "void refuel_octane_9 8(double volume_purchase d);"
      might be specific to a gasoline_car. It would not work as a method for car,
      because the type of fuel a car needs depends on the motor. On the other
      hand, I cannot let this method be associated with motor, because I want to
      check that volume_purchase d fits into the car - and that depends on the
      tank size and the current tank contents. So ideally, when defining the
      class "diesel_car " as derived from "car" the motor M in car should become a
      diesel_motor... . But I suppose there is no way of doing that.

      Jan

      Comment

      • Rolf Magnus

        #4
        Re: Inheritance: &quot;abstra ct objects&quot;?

        J.M. wrote:
        [color=blue][color=green][color=darkred]
        >>> "class motor" is abstract because it has a virtual member
        >>> "virtual int calculate_horse power() = 0"[/color]
        >>
        >> It is abstract because it has a _pure_ virtual member. Make it just
        >> virtual, and the class won't be abstract anymore.[/color]
        >
        > That would work, but that would require some sort of implementation, would
        > it not? But without knowing the type of motor, I can't calculate the
        > horsepower....[/color]

        Right.
        [color=blue][color=green][color=darkred]
        >>> "class car" should have
        >>> "motor M;"
        >>> "void print_info(){.. . M.calculate_hor sepower(); ..... };"
        >>>
        >>> The following should be concrete:
        >>>
        >>> "class diesel_motor : class motor" and should implement
        >>> "virtual int calculate_horse power(){ calculate hp for diesel
        >>> };"
        >>>
        >>> "class diesel_car : class car"
        >>>
        >>> For this class, we should have an object "diesel_mot or M;" as a child of
        >>> "motor M;". In other words, in diesel_car I need an object M as a
        >>> diesel_motor, but in the class car, I only need those attributes of M
        >>> associated with a motor.[/color]
        >>
        >> Well, if you want to instantiate motor, simply don't make it abstract.[/color]
        >
        > Well, I don't "really" want to instantiate it - I want it to be part of an
        > abstract class :)[/color]

        If it is part of a class (be it abstract or not), then this class will
        contain an instance of the motor (and exactly that).
        [color=blue][color=green]
        >> Why exactly do you need a diesel_car? Just let your car have a pointer to
        >> motor, and it can have any motor that you have a class for.[/color]
        >
        > Well, the class diesel_car and gasoline_car would have specific methods
        > that car (or motor) would not have. For example
        > "void refuel_octane_9 8(double volume_purchase d);"
        > might be specific to a gasoline_car. It would not work as a method for
        > car, because the type of fuel a car needs depends on the motor. On the
        > other hand, I cannot let this method be associated with motor, because I
        > want to check that volume_purchase d fits into the car - and that depends
        > on the tank size and the current tank contents. So ideally, when defining
        > the class "diesel_car " as derived from "car" the motor M in car should
        > become a diesel_motor... . But I suppose there is no way of doing that.[/color]

        Maybe you could work with templates, like:

        template <class T> class car
        {
        /*...*/
        protected:
        T M_;
        };

        class diesel_car: public car<diesel_moto r>
        {
        };

        Then you can derive from car, and every derived class will contain the motor
        that belongs to it.

        Comment

        • J.M.

          #5
          Re: Inheritance: &quot;abstra ct objects&quot;?

          Rolf Magnus schrieb:

          [color=blue][color=green]
          >> That would work, but that would require some sort of implementation,
          >> would it not? But without knowing the type of motor, I can't calculate
          >> the horsepower....[/color]
          >
          > Right.[/color]

          I suppose a dummy implementation could work, but I do not really like that.
          On the other hand, there is nothing wrong having a dummy implementation for
          a dummy motor ;-)))

          [color=blue][color=green][color=darkred]
          >>>
          >>> Well, if you want to instantiate motor, simply don't make it abstract.[/color]
          >>
          >> Well, I don't "really" want to instantiate it - I want it to be part of
          >> an abstract class :)[/color]
          >
          > If it is part of a class (be it abstract or not), then this class will
          > contain an instance of the motor (and exactly that).[/color]

          Yes, I know, which is why the really was in quotes ;-)
          [color=blue]
          >[color=green][color=darkred]
          >>> Why exactly do you need a diesel_car? Just let your car have a pointer
          >>> to motor, and it can have any motor that you have a class for.[/color]
          >>
          >> Well, the class diesel_car and gasoline_car would have specific methods
          >> that car (or motor) would not have. For example
          >> "void refuel_octane_9 8(double volume_purchase d);"
          >> might be specific to a gasoline_car. It would not work as a method for
          >> car, because the type of fuel a car needs depends on the motor. On the
          >> other hand, I cannot let this method be associated with motor, because I
          >> want to check that volume_purchase d fits into the car - and that depends
          >> on the tank size and the current tank contents. So ideally, when defining
          >> the class "diesel_car " as derived from "car" the motor M in car should
          >> become a diesel_motor... . But I suppose there is no way of doing that.[/color]
          >
          > Maybe you could work with templates, like:
          >
          > template <class T> class car
          > {
          > /*...*/
          > protected:
          > T M_;
          > };
          >
          > class diesel_car: public car<diesel_moto r>
          > {
          > };
          >
          > Then you can derive from car, and every derived class will contain the
          > motor that belongs to it.[/color]

          Yes, I think that should work. In fact, that was the solution I was looking
          for. Now that you have pointed it out to me, I recall having seen a
          solution using templates before, but obviously, I had forgotten it...
          Thanks for you help!

          Jan

          Comment

          Working...