Abstract classes hierarchy
-
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
-
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
-
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
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?
-
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?
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 -
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
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.
-
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
Another way could also be to use an
abstract
property forFieldB
in theMessage
class andoverride
them in theCommand
andResponse
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; } } }
-
Another way could also be to use an
abstract
property forFieldB
in theMessage
class andoverride
them in theCommand
andResponse
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; } } }
-
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
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.