Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C#
  4. Abstract classes hierarchy

Abstract classes hierarchy

Scheduled Pinned Locked Moved C#
questioncsharpcsshardwarehelp
8 Posts 4 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Offline
    M Offline
    Metal76
    wrote on last edited by
    #1

    Hi, I am a longtime embedded C programmer who has recently begun struggling with OOP :confused: I'm writing code for a serial communication protocol; protocol messages can belong to 2 different types (commands and responses), which share several fields and methods that I decided to factor out in a common base class, more or less like the example below:

    public abstract class Message
    {
    // Several properties representing common fields ...
    private byte _FieldA;
    public byte FieldA
    {
    // Property getter and setter
    }

    private byte \_FieldB;
    public byte FieldB
    {
         // Property getter and setter
    }
    
    private byte \_FieldC;
    public byte FieldC
    {
         // Property getter and setter
         // NOTE: FieldC value is based on FieldA and Field B values!!!
    }
    
    // Common methods...
    public byte\[\] CompileHeader()
    {
         // Compiles packet header using all the fields above
    }
    

    }

    public abstract class Command : Message
    {
    // Additional specific command fields and methods
    // NOTE: commands must set FieldB to 1!
    }

    public abstract class Response : Message
    {
    // Additional specific response fields and methods
    // NOTE: commands must set FieldB to 2!
    }

    public class MyCommand : Command
    {
    // Concrete command class, adds more data etc.
    // By deriving from Command, I'd like FieldB to be
    // already set to 1 from the base classes
    }

    Message, Command and Response are abstract because they are not meant to be instantiated: it only makes sense to instantiate the concrete subclass (MyCommand). The problem is: as you see, if the actual message is a Command or a Response, FieldB must be set to a different value. However, FieldB is also used by the base Message class so I cannot move it down the hierarchy. I'd like FieldB to be set automatically to the appropriate value in my concrete classes, depending on the base class (e.g. if I inherit from Command I'd expect FieldB = 1). How can I implement this behaviour in C#? Thanks in advance to all of you gurus out there! Andrea

    L G 3 Replies Last reply
    0
    • M Metal76

      Hi, I am a longtime embedded C programmer who has recently begun struggling with OOP :confused: I'm writing code for a serial communication protocol; protocol messages can belong to 2 different types (commands and responses), which share several fields and methods that I decided to factor out in a common base class, more or less like the example below:

      public abstract class Message
      {
      // Several properties representing common fields ...
      private byte _FieldA;
      public byte FieldA
      {
      // Property getter and setter
      }

      private byte \_FieldB;
      public byte FieldB
      {
           // Property getter and setter
      }
      
      private byte \_FieldC;
      public byte FieldC
      {
           // Property getter and setter
           // NOTE: FieldC value is based on FieldA and Field B values!!!
      }
      
      // Common methods...
      public byte\[\] CompileHeader()
      {
           // Compiles packet header using all the fields above
      }
      

      }

      public abstract class Command : Message
      {
      // Additional specific command fields and methods
      // NOTE: commands must set FieldB to 1!
      }

      public abstract class Response : Message
      {
      // Additional specific response fields and methods
      // NOTE: commands must set FieldB to 2!
      }

      public class MyCommand : Command
      {
      // Concrete command class, adds more data etc.
      // By deriving from Command, I'd like FieldB to be
      // already set to 1 from the base classes
      }

      Message, Command and Response are abstract because they are not meant to be instantiated: it only makes sense to instantiate the concrete subclass (MyCommand). The problem is: as you see, if the actual message is a Command or a Response, FieldB must be set to a different value. However, FieldB is also used by the base Message class so I cannot move it down the hierarchy. I'd like FieldB to be set automatically to the appropriate value in my concrete classes, depending on the base class (e.g. if I inherit from Command I'd expect FieldB = 1). How can I implement this behaviour in C#? Thanks in advance to all of you gurus out there! Andrea

      L Offline
      L Offline
      Lost User
      wrote on last edited by
      #2

      In your abstract class Message class you can do this:

      public byte FieldB
      {
      get { return 1; }
      }

      And in your abstract class Response something like this:

      public new byte FieldB
      {
      get { return 2; }
      }

      regards

      M M 2 Replies Last reply
      0
      • L Lost User

        In your abstract class Message class you can do this:

        public byte FieldB
        {
        get { return 1; }
        }

        And in your abstract class Response something like this:

        public new byte FieldB
        {
        get { return 2; }
        }

        regards

        M Offline
        M Offline
        Metal76
        wrote on last edited by
        #3

        Thanks for your reply Greeeg. My doubt is: by doing this you are moving some of the Command-related logic to the base Message class (setting FieldB to 1 should only compete to a Command). Isn't there any other way to implement the desired behaviour without breaking the encapsulation?

        L 1 Reply Last reply
        0
        • M Metal76

          Thanks for your reply Greeeg. My doubt is: by doing this you are moving some of the Command-related logic to the base Message class (setting FieldB to 1 should only compete to a Command). Isn't there any other way to implement the desired behaviour without breaking the encapsulation?

          L Offline
          L Offline
          Lost User
          wrote on last edited by
          #4

          Metal76 wrote:

          My doubt is: by doing this you are moving some of the Command-related logic to the base Message class

          My bad. I actually meant to move

          public new byte FieldB
          {
          get { return 1; }
          }

          to the Command class. Is this what you actually wanted to achieve? regards

          1 Reply Last reply
          0
          • M Metal76

            Hi, I am a longtime embedded C programmer who has recently begun struggling with OOP :confused: I'm writing code for a serial communication protocol; protocol messages can belong to 2 different types (commands and responses), which share several fields and methods that I decided to factor out in a common base class, more or less like the example below:

            public abstract class Message
            {
            // Several properties representing common fields ...
            private byte _FieldA;
            public byte FieldA
            {
            // Property getter and setter
            }

            private byte \_FieldB;
            public byte FieldB
            {
                 // Property getter and setter
            }
            
            private byte \_FieldC;
            public byte FieldC
            {
                 // Property getter and setter
                 // NOTE: FieldC value is based on FieldA and Field B values!!!
            }
            
            // Common methods...
            public byte\[\] CompileHeader()
            {
                 // Compiles packet header using all the fields above
            }
            

            }

            public abstract class Command : Message
            {
            // Additional specific command fields and methods
            // NOTE: commands must set FieldB to 1!
            }

            public abstract class Response : Message
            {
            // Additional specific response fields and methods
            // NOTE: commands must set FieldB to 2!
            }

            public class MyCommand : Command
            {
            // Concrete command class, adds more data etc.
            // By deriving from Command, I'd like FieldB to be
            // already set to 1 from the base classes
            }

            Message, Command and Response are abstract because they are not meant to be instantiated: it only makes sense to instantiate the concrete subclass (MyCommand). The problem is: as you see, if the actual message is a Command or a Response, FieldB must be set to a different value. However, FieldB is also used by the base Message class so I cannot move it down the hierarchy. I'd like FieldB to be set automatically to the appropriate value in my concrete classes, depending on the base class (e.g. if I inherit from Command I'd expect FieldB = 1). How can I implement this behaviour in C#? Thanks in advance to all of you gurus out there! Andrea

            G Offline
            G Offline
            Guffa
            wrote on last edited by
            #5

            You can put (protected) constructors in the Command and Response class. The constructor in the MyCommand class will automatically call the constructor in the Command class if it's parameterless. Additionally, you can add a constructor to the Message class that takes a value for the FieldB property. That way a Message instance can not be created without specifying a value for the property. The constructors in the Command and Response classes can call the base constructor to specify the value:

            public abstract class Command : Message {

            // parameterless constructor that sets the FieldB value
            protected Command() : base(1) {}

            }

            Despite everything, the person most likely to be fooling you next is yourself.

            1 Reply Last reply
            0
            • M Metal76

              Hi, I am a longtime embedded C programmer who has recently begun struggling with OOP :confused: I'm writing code for a serial communication protocol; protocol messages can belong to 2 different types (commands and responses), which share several fields and methods that I decided to factor out in a common base class, more or less like the example below:

              public abstract class Message
              {
              // Several properties representing common fields ...
              private byte _FieldA;
              public byte FieldA
              {
              // Property getter and setter
              }

              private byte \_FieldB;
              public byte FieldB
              {
                   // Property getter and setter
              }
              
              private byte \_FieldC;
              public byte FieldC
              {
                   // Property getter and setter
                   // NOTE: FieldC value is based on FieldA and Field B values!!!
              }
              
              // Common methods...
              public byte\[\] CompileHeader()
              {
                   // Compiles packet header using all the fields above
              }
              

              }

              public abstract class Command : Message
              {
              // Additional specific command fields and methods
              // NOTE: commands must set FieldB to 1!
              }

              public abstract class Response : Message
              {
              // Additional specific response fields and methods
              // NOTE: commands must set FieldB to 2!
              }

              public class MyCommand : Command
              {
              // Concrete command class, adds more data etc.
              // By deriving from Command, I'd like FieldB to be
              // already set to 1 from the base classes
              }

              Message, Command and Response are abstract because they are not meant to be instantiated: it only makes sense to instantiate the concrete subclass (MyCommand). The problem is: as you see, if the actual message is a Command or a Response, FieldB must be set to a different value. However, FieldB is also used by the base Message class so I cannot move it down the hierarchy. I'd like FieldB to be set automatically to the appropriate value in my concrete classes, depending on the base class (e.g. if I inherit from Command I'd expect FieldB = 1). How can I implement this behaviour in C#? Thanks in advance to all of you gurus out there! Andrea

              L Offline
              L Offline
              Lost User
              wrote on last edited by
              #6

              Another way could also be to use an abstract property for FieldB in the Message class and override them in the Command and Response classes:

              public abstract class Message
              {
              	public abstract byte FieldB
              	{
              		get;
              	}
              }
              
              public abstract class Command : Message
              {
              	public override byte FieldB
              	{
              		get { return 1; }
              	}
              }
              
              public abstract class Response : Message
              {
              	public override byte FieldB
              	{
              		get { return 2; }
              	}
              }
              
              M 1 Reply Last reply
              0
              • L Lost User

                Another way could also be to use an abstract property for FieldB in the Message class and override them in the Command and Response classes:

                public abstract class Message
                {
                	public abstract byte FieldB
                	{
                		get;
                	}
                }
                
                public abstract class Command : Message
                {
                	public override byte FieldB
                	{
                		get { return 1; }
                	}
                }
                
                public abstract class Response : Message
                {
                	public override byte FieldB
                	{
                		get { return 2; }
                	}
                }
                
                M Offline
                M Offline
                Metal76
                wrote on last edited by
                #7

                Thank you very much for your replies, both approaches seem really promising. Regards, Andrea

                1 Reply Last reply
                0
                • L Lost User

                  In your abstract class Message class you can do this:

                  public byte FieldB
                  {
                  get { return 1; }
                  }

                  And in your abstract class Response something like this:

                  public new byte FieldB
                  {
                  get { return 2; }
                  }

                  regards

                  M Offline
                  M Offline
                  Mark Churchill
                  wrote on last edited by
                  #8

                  The new keyword would be inappropriate here. It would be better to use virtual properties and override. If you have: Message message = new Command(); then you would expect message.FieldB to return the override from command. If you use the new keyword, this won't happen.

                  Mark Churchill Director Dunn & Churchill Free Download:
                  Diamond Binding: The simple, powerful, reliable, and effective data layer toolkit for Visual Studio.

                  1 Reply Last reply
                  0
                  Reply
                  • Reply as topic
                  Log in to reply
                  • Oldest to Newest
                  • Newest to Oldest
                  • Most Votes


                  • Login

                  • Don't have an account? Register

                  • Login or register to search.
                  • First post
                    Last post
                  0
                  • Categories
                  • Recent
                  • Tags
                  • Popular
                  • World
                  • Users
                  • Groups