Overriding Virtual Members
-
The Grand Negus wrote:
Perfectly reasonable presuming that one has accepted the notion that derived classes of any sort are reasonable.
Derived classes are perfectly reasonable just like it’s reasonable to use the term “vehicle” to refer to all manner of vehicles (cars, trucks, bikes, etc) or to class, say, a car as a vehicle. In the same way that much can be said about vehicles in general, a lot of the common aspects in a simulation of vehicles can be factored into a base class; the specifics of a particular vehicle are factored into derived classes.
Steve
-
I don't agree that it’s necessarily bad design. It’s perfectly reasonable for a derived class to add functionality rather than replace it.
Steve
Stephen Hewitt wrote:
I don't agree that it’s necessarily bad design. It’s perfectly reasonable for a derived class to add functionality rather than replace it.
I guess what bothers me is the ambiguity involved. As a matter of practice should an overriden method call the base class method? If so, should it call it at the beginning of the overriden method or at the end? Should we rely on documentation to specify if calling the base class method is necessary?
-
Stephen Hewitt wrote:
I don't agree that it’s necessarily bad design. It’s perfectly reasonable for a derived class to add functionality rather than replace it.
I guess what bothers me is the ambiguity involved. As a matter of practice should an overriden method call the base class method? If so, should it call it at the beginning of the overriden method or at the end? Should we rely on documentation to specify if calling the base class method is necessary?
That's where, in a perfect world, documentation would come into the picture. It might be valid to do things both before and after. One pattern you may be interesting in is the following: NOTE: This is in C++. I'm no C# expert so I'm not sure how much of this will cleanly translate.
class CMyClass
{
public:
bool DoSomething() // NOTE: I'm not virtual!
{
// Do something.
int size = DoSomething_GetSize();
// Do other stuff.
std::string str = DoSomething_GetString();
// Do even more stuff.....
}
private:
virtual int DoSomething_GetSize()
{
return 1; // Default.
}
virtual std::string DoSomething_GetString()
{
return std::string("Hello"); // Default.
}
};In this pattern all the methods that users call are implemented by non-virtual public functions. Any customization needed is implemented by virtual function “hooks” that customize specific aspects of the public functions. In this pattern you don’t call the base class version (you can't as they're private) and customization is limited to specific preplanned areas.
Steve
-
The Grand Negus wrote:
Perfectly reasonable presuming that one has accepted the notion that derived classes of any sort are reasonable.
No. the above is NOT a pre-requisite. :)
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler. -- Alfonso the Wise, 13th Century King of Castile.
-
That's where, in a perfect world, documentation would come into the picture. It might be valid to do things both before and after. One pattern you may be interesting in is the following: NOTE: This is in C++. I'm no C# expert so I'm not sure how much of this will cleanly translate.
class CMyClass
{
public:
bool DoSomething() // NOTE: I'm not virtual!
{
// Do something.
int size = DoSomething_GetSize();
// Do other stuff.
std::string str = DoSomething_GetString();
// Do even more stuff.....
}
private:
virtual int DoSomething_GetSize()
{
return 1; // Default.
}
virtual std::string DoSomething_GetString()
{
return std::string("Hello"); // Default.
}
};In this pattern all the methods that users call are implemented by non-virtual public functions. Any customization needed is implemented by virtual function “hooks” that customize specific aspects of the public functions. In this pattern you don’t call the base class version (you can't as they're private) and customization is limited to specific preplanned areas.
Steve
Stephen Hewitt wrote:
This is in C++. I'm no C# expert so I'm not sure how much of this will cleanly translate.
It's the same in C# :) Also the non-virtual method usualy does all the parameter checking etc, so you don't need to duplicate it in derived classes.
"Throughout human history, we have been dependent on machines to survive. Fate, it seems, is not without a sense of irony. " - Morpheus "Real men use mspaint for writing code and notepad for designing graphics." - Anna-Jayne Metcalfe
-
That's where, in a perfect world, documentation would come into the picture. It might be valid to do things both before and after. One pattern you may be interesting in is the following: NOTE: This is in C++. I'm no C# expert so I'm not sure how much of this will cleanly translate.
class CMyClass
{
public:
bool DoSomething() // NOTE: I'm not virtual!
{
// Do something.
int size = DoSomething_GetSize();
// Do other stuff.
std::string str = DoSomething_GetString();
// Do even more stuff.....
}
private:
virtual int DoSomething_GetSize()
{
return 1; // Default.
}
virtual std::string DoSomething_GetString()
{
return std::string("Hello"); // Default.
}
};In this pattern all the methods that users call are implemented by non-virtual public functions. Any customization needed is implemented by virtual function “hooks” that customize specific aspects of the public functions. In this pattern you don’t call the base class version (you can't as they're private) and customization is limited to specific preplanned areas.
Steve
Stephen Hewitt wrote:
One pattern you may be interesting in is the following:
This looks like the Template[^] design pattern. I'm glad you brought this up as I think it's a superior way of approaching the problem I described. Thanks. (My C++ is rusty, but I think the virtual methods should have protected access rather than private, no?)
-
Just a thought, If you override a virtual function in class inherited from a standard control, does that not by default inclde a call to the base function??
pprice wrote:
If you override a virtual function in class inherited from a standard control, does that not by default inclde a call to the base function??
It depends. If you write the code by hand, it's entirely up to you to add the code that calls the base class method. If you rely on intellisense, it creates the overriden method that includes a call to the base class method.
-
He is asking for help with his work. He doesn't have the choice of foregoing object oriented design. C# is all objects. At least have some sense of the reality of the situation. Sheeesh. This isn't english. Its C#.
This statement was never false.
-
Say you have a class with a virtual method (using C#):
public class BaseClass
{
public virtual void DoSomething()
{
// Stuff...
}
}A class that derives from the base class:
public class DerivedClass : BaseClass
{
public override void DoSomething()
{
// More stuff...base.DoSomething(); }
}
Questions: What is your opinion of the derived class calling the base class's implementation of
DoSomething
? Suppose the base class is designed in such a way that any derived class must call the base class method/property when overriding it in order for the class's invariants to be maintained. Is this bad design?I think its perfectly reasonable, but would caution against this design if its mandatory. It should be elective to call a base's virtual member that you've overridden. Personally if you have a dependency, I'd wrap that in a private member function that calls the virtual one. This way you control through the base class what gets called.
public class BaseClass
{
private void DoMyThing()
{
//Required stuff//either do your code before calling DoSomething or //after depending on the logic requirements DoSomething(); } public virtual void DoSomething() { //Only optional stuff }
}
public class DerivedClass : BaseClass
{
public override void DoSomething()
{
// More stuff...//the base will do its thing either before this or after //if required, else if its optional then call the base here }
}
This statement was never false.
-
Stephen Hewitt wrote:
I don't agree that it’s necessarily bad design. It’s perfectly reasonable for a derived class to add functionality rather than replace it.
I guess what bothers me is the ambiguity involved. As a matter of practice should an overriden method call the base class method? If so, should it call it at the beginning of the overriden method or at the end? Should we rely on documentation to specify if calling the base class method is necessary?
A good example of this is in MFC where you can override some of the message functions, but might still call the base to get its bits. But again, I'd say this would be better for optional cases.
This statement was never false.
-
Stephen Hewitt wrote:
One pattern you may be interesting in is the following:
This looks like the Template[^] design pattern. I'm glad you brought this up as I think it's a superior way of approaching the problem I described. Thanks. (My C++ is rusty, but I think the virtual methods should have protected access rather than private, no?)
If you don't want the derived class to be able to call the base class implementation
private
is best as any attempt to call it will result in a compiler error.private
doesn’t mean you can’t override the method in a derived class, you just can’t call the method in the base class from the derived class. Again, this is in C++, but I think it will be the same in C#.Steve
-
pprice wrote:
If you override a virtual function in class inherited from a standard control, does that not by default inclde a call to the base function??
It depends. If you write the code by hand, it's entirely up to you to add the code that calls the base class method. If you rely on intellisense, it creates the overriden method that includes a call to the base class method.
-
Say you have a class with a virtual method (using C#):
public class BaseClass
{
public virtual void DoSomething()
{
// Stuff...
}
}A class that derives from the base class:
public class DerivedClass : BaseClass
{
public override void DoSomething()
{
// More stuff...base.DoSomething(); }
}
Questions: What is your opinion of the derived class calling the base class's implementation of
DoSomething
? Suppose the base class is designed in such a way that any derived class must call the base class method/property when overriding it in order for the class's invariants to be maintained. Is this bad design?oops - did not see all messages before writing my comment (page break) but anyway: It's perfectly reasonably to do it or not to do it. Depends on what you want to do: replace or add functionality. And that's the problem with deriving classes: the "internal interface" is very weak. This could leaad to wrong use of your base class, i.e. your base class requires the base.DoSomething but the programmer of the derived class forgets it :-( Therefore some people do advise to use aggregation in difficult situations. Happy programming Urs -- modified at 5:39 Monday 25th June, 2007
-^-^-^-^-^- no risk no funk