Подтвердить что ты не робот

Как заставить подклассы реализовать метод

Я создаю структуру объекта, и я хочу, чтобы все подклассы базы были вынуждены реализовать метод.

Единственное, что я мог подумать, это:

  • Абстрактный класс - будет работать, но базовый класс имеет некоторые полезные вспомогательные функции, которые будут использоваться некоторыми подклассами.

  • Интерфейс - если применяется только к базовому классу, то подкласс не должен реализовывать функцию, которую выполняет только базовый класс.

Возможно ли это?

N.B. Это приложение .NET 2.

4b9b3361

Ответ 1

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

public abstract class YourClass
{
    // Your class implementation

    public abstract void DoSomething(int x, int y);

    public void DoSomethingElse(int a, string b)
    {
        // You can implement this here
    }
}

Ответ 2

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

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

Это приводит к тому, что вы не упомянули: использовать оба. У вас есть интерфейс IFoo, а абстрактный базовый класс FooBase реализует его или его часть. Это предоставляет подклассам "реализацию по умолчанию" интерфейса (или его части), а также позволяет наследовать от чего-то еще и по-прежнему реализовывать интерфейс, или если вы хотите реализовать интерфейс, но не наследовать реализацию базового класса. Пример может помочь:

// Your interface
interface IFoo { void A(); void B; }

// A "default" implementation of that interface
abstract class FooBase : IFoo
{
    public abstract void A();

    public void B()
    {
        Console.WriteLine("B");
    }
}

// A class that implements IFoo by reusing FooBase partial implementation
class Foo : FooBase
{
    public override void A()
    {
        Console.WriteLine("A");
    }
}

// This is a different class you may want to inherit from
class Bar
{
    public void C()
    {
        Console.WriteLine("C");
    }
}

// A class that inherits from Bar and implements IFoo
class FooBar : Bar, IFoo
{
    public void A()
    {
        Console.WriteLine("Foobar.A");
    }
    public void B()
    {
        Console.WriteLine("Foobar.B");
    }
}

Ответ 3

Абстрактный класс - будет работать, но базовый класс имеет полезный помощник функции, которые используются некоторыми sub classe

Абстрактный класс не требует всех функций, которые он предоставляет для абстрактного.

abstract class Base {
    public void Foo() {} // Ordinary method
    public virtual void Bar() {} // Can be overridden
    public abstract void Xyz(); // This one *must* be overridden
}

Обратите внимание, что если вы замените public на protected, отмеченный метод будет выглядеть только для базовых классов и подклассов.

Ответ 4

Да, и если все классы, которые вам нужно сделать для этого, являются логически подклассами существующего абстрактного базового класса, добавьте абстрактный метод в базовый класс... Это лучше, чем интерфейс, потому что он позволяет добавлять (путем изменения метода абстрактного базового класса на виртуальный метод с реализацией по умолчанию), если/когда выяснится, что, скажем, восемь из десяти производных классов будут иметь одну и ту же реализацию, и говорят, что только два из них отличаются друг от друга...

EDIT: (на основе потока в комментариях ниже) Базовый класс должен быть объявлен как абстрактный для этого... Вы не можете иметь абстрактный метод в не-абстрактном классе, потому что не абстрактный тип может быть создан, и если экземпляр его был создан, для этого метода не было бы никакой реализации. Так что это незаконно. Объявляя базу абстрактной, вы запрещаете создание экземпляра класса. Затем могут быть созданы только не абстрактные производные классы, где (поскольку базовый метод является абстрактным), вы ДОЛЖНЫ добавить реализацию для этого метода.

Ответ 5

И полный рабочий образец с параметрами (.netcore 2.2):

class User{
    public string Name = "Fen";
}

class Message{
    public string Text = "Ho";
}

// Interface
interface IWorkerLoop
{
    // Working with client message
    string MessageWorker(string msg);
}

// AbstractWorkerLoop partial implementation
public abstract class AbstractWorkerLoop : IWorkerLoop
{
    public User user;
    public Message msg;

    // Append session object to loop
    public abstract AbstractWorkerLoop(ref User user, ref Message msg){
        this.user = user;
        this.msg = msg;
    }

    public abstract string MessageWorker(string msg);
}

// Worker class
public class TestWorkerLoop : AbstractWorkerLoop
{
    public TestWorkerLoop(ref User user, ref Message msg) : base(user, msg){
        this.user = user;
        this.msg = msg;
    }

    public override string MessageWorker(string msg){
        // Do something with client message    
        return "Works";
    }
}