title: Inheritance and 2 interface types
body: <p>I have a question regarding inheritance and designing a user interface.</p>
  
  <p>I have a <code>class KeyboardKey</code> which represents an individual keyboard key, such as Q, W, E, R, ... etc.</p>
  
  <p>I have a <code>class Keyboard</code> which contains a <strong>vector of</strong> <code>class Keyboardkey</code>. [Important!]</p>
  
  <p>I am using SFML, and so each time an event is generated from an event loop, it is sent to the keyboard class. This class then farms that event out to the corresponding key.</p>
  
  <p>In addition, I have a <code>class SynthesizerKey</code> which inherits from <code>KeyboardKey</code>. In addition to the regular key stuff, such as "is the key enabled", "is the key pressed", this class contains data and functions to handle generating a sin wave tone. Variables include the amplitude and current phase of the sin wave.</p>
  
  <p>I am now about to create a <code>class SynthesizerKeyboard</code>. I was about to copy and paste all the code from <code>class Keyboard</code> into this class, however this is not good programming practice, as code is duplicated!</p>
  
  <p>The main issue I have is that <code>SynthesizerKeyboard</code> contains a function to generate a sequence of samples to be stored in a buffer. In order to generate the samples, a loop iterates over each <code>KeyboardKey</code> and checks if it is pressed. If it is, then we must generate a sample corresponding to that keys note/frequency.</p>
  
  <p>However, since the vector contains <code>class KeyboardKey</code> and <strong>not</strong> <code>class SynthesizerKey</code> I do not have the variables for the phase and amplitude of the sin waves as member data of the elements of the vector.</p>
  
  <p>I think I may have to do what is known as "refactoring" [?], and separate the "sin wave" parts of <code>SynthesizerKey</code> from the <code>KeyboardKey</code> parts. In other words, I ditch the <code>SynthesizerKey</code> class and have an <code>Synthesizer</code> class and a <code>KeyboardKey</code> class, separately. I then have a vector of <code>Synthesizer</code> in <code>class SynthesizerKeyboard</code> in addition to the vector of <code>KeyboardKey</code> in <code>class Keyboard</code> which I have access to in <code>SynthesizerKeyboard</code> through inheritance.</p>
  
  <p>However this is less elegant. Is there another way?</p>
  
  <p>Below is some code which might help the reader understand the quesiton in more detail.</p>
  
  <p><strong>SynthesizerKeyboard</strong></p>
  
  <pre><code>class SynthesizerKeyboard : public Keyboard
  {
  
  public:
  
      SynthesizerKeyboard(const sf::Font&amp; sf_font)
          : Keyboard(sf_font)
      {
      }
  
      double Sample() const
      {
          for(std::vector&lt;KeyboardKey&gt;::iterator it = m_keyboardkey.begin()
              it != m_keyboardkey.end(); ++ it)
          {
              if(it-&gt;IsKeyPressed())
              {
                  it-&gt;Sample();
              }
          }
      }
  
      void GenerateBufferSamples(std::vector&lt;sf::Int16&gt; buffer)
      {
          for(std::size_t i = 0; i &lt; buffer.size(); ++ i)
          {
              buffer[i] = Sample();
          }
      }
  
  };
  </code></pre>
  
  <p><strong>SynthesizerKey</strong></p>
  
  <pre><code>class SynthesizerKey : public KeyboardKey
  {
  
  protected:
  
      AbstractOscillator *m_abstractoscillator;
  
  public:
  
      double Sample() const
      {
          return m_abstractoscillator-&gt;Sample();
      }
  
  };
  </code></pre>
  
  <p><strong>Keyboard</strong></p>
  
  <pre><code>class Keyboard
  {
  
  protected:
  
      std::vector&lt;KeyboardKey&gt; m_keyboardkey;
  
  public:
  
      Keyboard(const sf::Font&amp; sf_font)
  
      void Draw(sf::RenderWindow&amp; window)
  
      void Event(const sf::Event&amp; event)
      {
          for(std::vector&lt;KeyboardKey&gt;::iterator it = m_keyboardkey.begin();
              it != m_keyboardkey.end(); ++ it)
          {
              (*it).Event(event);
          }
      }
  
      bool IsKeyPressed(const sf::Keyboard::Key&amp; sf_key)
      {
          for(std::vector&lt;KeyboardKey&gt;::iterator it = m_keyboardkey.begin();
              it != m_keyboardkey.end(); ++ it)
          {
              if((*it).Key() == sf_key)
              {
                  return (*it).IsKeyPressed();
              }
          }
      }
  
  };
  </code></pre>
  
  <p><strong>KeyboardKey</strong></p>
  
  <pre><code>class KeyboardKey
  {
  
  protected:
  
      KeyState m_keystate;
      sf::Color m_pressed_color;
      sf::Color m_release_color;
      sf::Text m_sf_text;
      sf::Keyboard::Key m_sf_keyboard_key;
      sf::RectangleShape m_sf_rectangle;
  
  public:
  
      KeyboardKey(const sf::Keyboard::Key&amp; sf_keyboard_key, const std::string&amp; text, const sf::Font&amp; sf_font,
                  const double position_x, const double position_y)
  
      void Draw(sf::RenderWindow&amp; window)
  
      void Event(const sf::Event&amp; event)
  
      bool IsKeyPressed()
  
  };
  </code></pre>