Как вызвать отвержение метода в потомке, не имея абстрактного базового класса?

Заголовок вопроса, кажется, мало сбивает с толку, Но я Попытаюсь очистить свой вопрос здесь.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    public abstract class Employee
    {
        private string name;
        private int empid;
        BenefitPackage _BenefitPackage = new BenefitPackage();
        public string Name
         {
             get { return this.name; }
             set { this.name = value; }
            }
        public int EmpId
        {
            get { return this.empid; }
            set
            {
                if (value == 1)
                    return;
                this.empid = value; }
        }
        public Employee(string Name, int EmpId)
        {
            this.Name = Name;
            this.EmpId = EmpId;
        }
        public Employee()
        { }

        public abstract void GiveBonus();

    }

    public class Manager : Employee
    {
        private int noofstockoptions;
        public override void GiveBonus()
        {
            Console.WriteLine("Manger GiveBonus Override");
        }
        public int NoOfStockOptions
        {
            get { return this.noofstockoptions; }
            set { this.noofstockoptions = value; }
        }

        public Manager(string Name,int EmpId, int NoOfStockOptions):base(Name,EmpId)
        {
            this.NoOfStockOptions=NoOfStockOptions;
        }

    }
    public class SalesPerson:Employee
    {
        private int noofsales;
        public int NoOfSales
        {
            get { return this.noofsales; }
            set { this.noofsales = value; }
        }

        public SalesPerson(string Name, int EmpId, int NoOfSales):base(Name,EmpId)
        {
            this.NoOfSales = NoOfSales;
        }
        public override void GiveBonus()
        {
            Console.WriteLine("Hi from salesperson");
        }
    }
    public sealed class PTSalesPerson : SalesPerson
    {
        private int noofhrworked;
        public int NoOfHrWorked
        {
            get { return this.noofhrworked; }
            set { this.noofhrworked = value; }

        }
        public PTSalesPerson(string Name, int EmpId, int NoOfSales,int NoOfHrWorked):base(Name,EmpId,NoOfSales)
        {
            this.NoOfHrWorked = NoOfHrWorked;

        }
        //public new void GiveBonus()
        //{
        //    Console.WriteLine("hi from ptsalesperson");
        //} 
    }

    class BenefitPackage
    {
        public int Bonus;
        public int GiveBonus()
        {
            int i = 200;
            return i;
        }

        private class innerPublic
        {
            public int innerBonus;

        }


    }

    class MainClass
    {
        public static void Main()
        { 
        Manager _Manager=new Manager("Vaibhav",1,50);
        PTSalesPerson _PTSalesPerson = new PTSalesPerson("Shantanu", 1, 4, 6);
        _Manager.GiveBonus();

        Employee _emp;
        //_emp = new Employee("new emp",4);
        //_emp.GiveBonus();
        _PTSalesPerson.GiveBonus();
        ((SalesPerson)_PTSalesPerson).GiveBonus();
        Console.ReadLine();    
        }

    }
}

Пожалуйста, не пытайтесь понять целый кодекс. Я суммирую его.

  1. Сотрудник - Абстрактный класс, у которых есть абстрактный метод GiveBonus
  2. SalesPerson - получение от Сотрудника. SalesPerson должен дать определение абстрактному Методу GiveBonus. (SalesPerson не может быть Абстрактным),
  3. PTSalesPerson происходит из SalesPerson.

Теперь мой вопрос, Как я могу вынудить PTSalesPerson иметь свое собственное внедрение GiveBonus.

43
задан angry person 22 January 2010 в 15:07
поделиться

8 ответов

Я думаю, что вы думаете об этом неправильно. Языковые дизайнеры не сказали себе «то, что нам действительно нужно, это способ отметить метод как должен быть переопределен , давайте изобрем эту вещь под названием Аннотация ». Они сказали: «Виртуальный метод позволяет нам представлять эту идею, что каждый полученный тип этого базового типа должен иметь возможность сделать этот метод . Но что, если есть , не имеется разумного кода , который может Идите в базовый класс версии метода? Я знаю, давайте изобрем эту вещь, называемую абстрактным методом для этого обстоятельства ».

Это проблема, что абстрактные методы предназначались для решения: у вас есть метод, общий для всех полученных классов, но никаких разумных реализаций базового класса, а не «Мне нужен способ заставить моих полученных типов, чтобы обеспечить реализацию». Это производные типы вынуждены обеспечить реализацию, является следствием раствора , но не проблема , предназначенная для решавления в первую очередь.

Язык C # не имеет механизма для проблемы «я должен заставить мой подтип предоставить свою собственную реализацию этого метода», потому что это не проблема, которую языковые дизайнеры, к своим знаниям, когда-либо считались проблемой для Большинство наших клиентов.

Итак, мой вопрос: почему вы хотите сделать это? Конечно, это зависит от разработчика полученного класса, чтобы определить, правильно ли реализация базового класса для полученного класса или нет. Это не до тебя. И даже если у вас есть какой-то способ сделать это, то, что остановит разработчику от простого слова

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

?

Можете ли вы объяснить, какую цель вы должны попытаться заставить эту работу над разработчиками ваших полученных классов? Возможно, есть лучший способ добиться того, что вы хотите.

Но в целом: я не уверен, что ваша иерархия разумно спроектирована в первую очередь. Когда я вижу метод, посвященный на сотруднику, я предполагаю, что это означает, что «сотрудник может дать бонус», а не «сотрудник может получить бонус». Несомненно, руководитель дает бонус и сотрудник бонус. Я думаю, что вы можете сделать иерархию сотрудника слишком много.

95
ответ дан 26 November 2019 в 22:29
поделиться

Единственный способ увидеть эту работу, если вы не можете Сделайте Salesperson Cable, это:

1) в Salesperson.GiveBonus (...) использовать отражение, чтобы определить, «этот» является продавцом, или полученный класс а) если не полученный класс, выполняйте текущий код в Salesperson.GiveBonus б) в противном случае вызов сдачи. (Объявите это как виртуально, и сделайте вспомогательное представление в продавцом, бросьте исключение.)

Вершинные спины здесь, отражение медленное. Нет ошибки времени компиляции, если сдачи не заявлены, и т. Д.

1
ответ дан 26 November 2019 в 22:29
поделиться

Объявление о сотруднике [11224448] в виде абстрактных, но предоставляют и осуществляют , которые адапбоны () , которые бросают исключение времени выполнения с сообщением быть реализованы подклассами ". Это старая практика Smalltalk ... не уверен, что это полезно для C #. Я использовал его в коде Java.

7
ответ дан 26 November 2019 в 22:29
поделиться

Агрегат обычно содержит ссылки на другие совокупные корни. Эти ссылки должны быть удалены, когда содержащий совокупность удаляется, но агрегаты они указывают на останусь.

Чтобы использовать вашу аналогию. Доклад, который мы предполагаем, является частью только одного падающего падающего агрегата и удаляется вместе с совокупностью. Ни один другой агрегат не будет напрямую доступа к этим отчетам.

Однако падающий совокупность будет совокупность агрегатов, представляющих офицеров и подозреваемых, а также записи журналов CCTV.

-121--3279176-

Если вы не собираетесь создавать экземпляр продавца напрямую, то самая простая вещь, чтобы сделать, чтобы сделать спасение абстрактным, и это принудило бы какие-либо детские классы, чтобы внести его вместо этого (или быть абстрактными сами себя).

Если в этом методе есть какая-то логика, общая для всех продавцов, вы могли бы реализовать датбонус на продавцом в качестве метода шаблона . Которые вызывают некоторый абстрактный метод, необходимый в любых подклассах:

, которые когда-либо вы принимаете решение, единственный способ заставить внедрение в детском классе - сделать базовый класс абстрактным.

1
ответ дан 26 November 2019 в 22:29
поделиться

Вы не можете использовать описанную вами настройку. PTSALesperSon уже будет внедрение датчика, потому что он наследует от продавца.

1
ответ дан 26 November 2019 в 22:29
поделиться

Используйте инъекцию зависимости. Создать BonusCalculator Класс:

public abstract class BonusCalculator
{
   public abstract decimal CalculateBonus(Employee e)
}

В вашем базовом классе:

private BonusCalculator Calculator { get; set; }

public void GiveBonus()
{
   Bonus = Calculator.CalculateBonus(this)
}

в конструкторе вашей реализации:

public SomeKindOfEmployee()
{
    Calculator = new SomeKindOfEmployeeBonusCalculator();
}

Кто-то, реализующий подкласс , который теперь должен явно предоставить ему экземпляр Из BONUSCALCUTLCUTLCUTUL (или получить NullReferenceException в , метод ).

Как добавленная, бонус, этот подход позволяет различным подклассам человека , чтобы поделиться методом бонус-расчета, если это уместно.

Редактировать

Конечно, если PTSALesperson происходит из Salesperson и его конструктор вызывает базовый конструктор, это тоже не будет работать.

7
ответ дан 26 November 2019 в 22:29
поделиться

Вы не можете, если вы не сделаете продавцом абстрактным или изменить иерархию.

Как насчет:

                       Employee*
                           ^
                           |
                       SalesPersonBase* (have all the code except GiveBonus)
                        ^           ^
                        |           |
                 SalesPerson      PTSalesPerson

как работника, так и продавца, и продавца теперь отмечены как абстрактные.

Однако, если вам нужен PTSAleSperson, чтобы не только наследовать поведение, но и наследующую это отношения (PTSALesperson также является продавцом), то у вас нет способа заставить это.

Примечание. Приведенный выше текст действителен только в том случае, если вы считаете только проверки компиляции. Другими словами, если вы хотите, чтобы компилятор пожаловаться, если вы не добавили переопределение в класс PTSALesperson, вы не можете сделать это, если вы не сделаете то, что я изложил выше.

Тем не менее, нет ничего останавливать вас от использования отражения для изучения методов во время выполнения, и выбросить исключение, если метод в PTSAleSperson не явно переопределен там, однако я бы считал, что это взломать.

10
ответ дан 26 November 2019 в 22:29
поделиться

Вы всегда можете сделать реализацию Salesperson, бросил нотамлементомException. : V Но по контракте нет, вы не можете этого сделать.

0
ответ дан 26 November 2019 в 22:29
поделиться
Другие вопросы по тегам:

Похожие вопросы: