How to force overriding a method in a descendant, without having an abstract base class?

前端 未结 14 902
孤城傲影
孤城傲影 2020-12-09 07:24

Question Heading seems to be little confusing, But I will Try to clear my question here.

using System;
using System.Collections.Generic;
usi         


        
相关标签:
14条回答
  • 2020-12-09 07:41

    A WA may be using an "Interface" so you define one like IBonusGiver { void GiveBonus(); } An then, instead of the abstract method and the overrides, you implement in all your classes this new interface. e.g. PTSalesPerson : SalesPerson, IBonusGiver forcing a new implementation in each class.

    0 讨论(0)
  • Okay, I know this post is old, however, I have recently needed to look this answer up, so for anyone else looking for this: (I am using VS 2012 .net 4.5, so not sure about older versions)

    I created an abstract class, and used override on both child classes:

    public abstract class Person
    {
        public string Name { get; protected set; }
        public abstract void GiveName(string inName);
    }
    
    public class Employee : Person
    {
        public override void GiveName(string inName)
        {
            Name = inName;
        }
    }
    
    public class SalesPerson:Employee
    {
        public override void GiveName(string inName)
        {
            Name = "Sales: "+inName;
        }
    }
    

    Testing:

    SalesPerson x = new SalesPerson();
    x.GiveName("Mark"); //Name="Sales: Mark"
    Employee e = x;
    e.GiveName("Mark"); //Name="Sales: Mark"
    Employee m = new Employee();
    m.GiveName("Mark"); //Name="Mark"
    
    0 讨论(0)
  • 2020-12-09 07:52

    I very much hope my answer will help some people confused by this issue.

    Bear with me, but I'll try to re-summarise what is being asked, just to ensure that I am answering the right question. Then I'll give the answer!

    I think the essence of the question is: How do I declare a method in an abstract class so that is has an implementation but still requires a derived class to override the method?

    C# doesn't appear to support this. If you declare the method 'abstract', it is not permitted to have an implementation (body). But if you declare it 'virtual', a derived class is not forced to override it. C# deosn't allow a method to be marked as both abstract and virtual.

    I believe there are many situations where you wish to do this (what is being asked).

    The way to solve this riddle is as follows: Declare two methods! One of them is marked 'abstract'; the other is marked 'virtual' and calls the first one somewhere in its body.

    This way, the derived class is forced to override the abstract method, but the (partial) implementation in the virtual method can be safely inherited.

    So, for example, the Employee method GiveBonus might be declared thus:

    public abstract decimal ComputeBonus();
    public virtual void GiveBonus() { 
        decimal amount = ComputeBonus();
        if (amount > 0.0) PostBonus(amount);
    }
    

    I'll leave the details of PostBonus to the imagination, but the beauty of this approach is that derived classes are forced to override ComputeBonus, yet GiveBonus benefits from the partial implementation provided in the base class. HTH

    0 讨论(0)
  • 2020-12-09 07:54

    You can't using the setup you described. PTSalesPerson will already have an implementation of GiveBonus because it inherits from SalesPerson.

    0 讨论(0)
  • 2020-12-09 07:56

    I think you're thinking about this the wrong way. The language designers did not say to themselves "what we really need is a way to mark a method as must be overridden, let's invent this thing called abstract". They said "A virtual method lets us represent the idea that every derived type of this base type should be able to do this method. But what if there is no sensible code that can possibly go in the base class version of the method? I know, let's invent this thing called an abstract method for that circumstance."

    That's the problem that abstract methods were intended to solve: you have a method common to all derived classes but no sensible base class implementation, NOT "I need a way to force my derived types to provide an implementation". That derived types are forced to provide an implementation is a consequence of the solution, but not the problem intended to be solved in the first place.

    The C# language does not have a mechanism for the problem "I must force my subtype to provide their own implementation of this method" because that's not a problem that the language designers, to my knowledge, ever considered would be a problem for the majority of our customers.

    So my question to you is: why do you want to do this? Surely it is up to the developer of the derived class to determine whether or not the base class implementation is correct for the derived class or not. That's not up to you. And even if you did have some way to do that, what would stop the developer from simply saying

    override void M() { base.M(); }
    

    ?

    Can you explain what purpose you have for attempting to force this work upon the developers of your derived classes? Perhaps there is a better way to achieve what you want.

    But more generally: I am not sure that your hierarchy is sensibly designed in the first place. When I see a method GiveBonus on an Employee, I assume that this means that "an employee can give a bonus", not "an employee can receive a bonus". Surely a manager gives a bonus and an employee receives a bonus. I think you might be making the employee hierarchy do too much.

    0 讨论(0)
  • 2020-12-09 07:58

    Declare the class Employee as abstract but provide and implementation of GiveBonus() that throws a runtime exception with a message like "Must be implemented by subclasses". It's an old Smalltalk practice... Not sure if it is useful to C#. I have used it in Java code.

    0 讨论(0)
提交回复
热议问题