无法在接口方法中创建抽象类的实例

本文关键字:创建 抽象类 实例 方法 接口 | 更新日期: 2023-09-27 18:27:50

我已经根据提供给我的文档创建了这个接口。(我需要使用第三方API进行数据库日志记录)。我应该为getLogger()方法返回对象类型"Logger",为getDatabaseMgr方法返回对象类别"DatabaseMgr"。然而,这些都是抽象类。文档没有具体说明该方法的作用,他们只是写了{…}。

如果我不能创建这些类的实例,那么我如何返回它们?

using System;
using System.Data.Common;
namespace com.XXXXXXXXXX.api
{
    public class ApiFactory
    {
        public static ApiFactory getInstance() {
            return new ApiFactory();
        }

        public Logger getLogger(String Id, Type type)
        {
        }
        public DatabaseMgr getDatabaseMgr(String Id)
        {
        }
    }
    public abstract class Logger
    {
        public String Id { get; set; }
        public abstract void trace(String message);
        public abstract void debug(String message);
        public abstract void info(String message);
        public abstract void warn(String message);
        public abstract void error(String message);
        public abstract void alert(String message);
        public abstract bool isTraceEnabled { get; }
        public abstract bool isDebugEnabled { get; }
        public abstract bool isInfoEnabled { get; }
        public abstract bool isWarnEnabled { get; }
        public abstract bool isErrorEnabled { get; }
    }
    public abstract class DatabaseMgr
    {
        public String Id { get; set; }
        protected DatabaseMgr(String Id)
        {
        }
    }
}

无法在接口方法中创建抽象类的实例

单词"abstract"表示不能创建此类的实例。您可以创建另一个从抽象类继承的类,并从子(非抽象)类创建实例。

您的抽象类必须在派生类中实现:

public abstract class Logger
{
    public abstract void debug(String message);
    //Other properties and methods
}

MyLoggerImpl是抽象Logger的派生类,可以选择使用带有sealed修饰符的MyLoggerImpl来防止其他类继承:

public sealed class MyLoggerImpl : Logger
{
    public override void debug(string message) 
    {
        //Write log
        //Trace.WriteLine(message);
    }
}

现在在另一个类MyLogger中创建MyLoggerImpl的实例:我更愿意将debug()创建为static,这样无论创建了多少个类实例,static成员都只存在一个副本,也避免了从不同的代码模块多次创建MyLogger的实例,相反,MyLogger.debug("Some message.")可以被调用:

public class MyLogger
{
    public static void debug(string message)
    {
        var log = new MyLoggerImpl();
        log.debug(message);
    }
}

MSDN参考资料如下:

控制台应用程序的示例用法:

static void Main(string[] args)
{
    MyLogger.debug("Some message.");
}

对于.NET Core 3.1和.NET 5,您可以使用System.Reflection

将构造函数添加到Logger:

public abstract class Logger
{
    public Logger() { }
    public String Id { get; set; }
    public abstract void trace(String message);
    ...
    ...
    public abstract bool isWarnEnabled { get; }
    public abstract bool isErrorEnabled { get; }
}

使用反射获取实例:

Type typeLogger = typeof(Logger);
ConstructorInfo magicConstructor = typeLogger.GetConstructor(Type.EmptyTypes);//get Constructor
Type TypeRuntimeMethodHandle = typeof(RuntimeMethodHandle);
MethodInfo magicMethod = TypeRuntimeMethodHandle.GetMethod("InvokeMethod", BindingFlags.Static | BindingFlags.NonPublic);//get InvokeMethod from RunTimeMethodHandle
PropertyInfo sigInfo = magicConstructor.GetType().GetProperty("Signature", BindingFlags.Public | BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Instance);//get signature
Logger abstrObj = (Logger)magicMethod.Invoke(null, new object[] { null, null, sigInfo.GetValue(magicConstructor), true , null});
abstrObj.Id = "2366";
Console.WriteLine(abstrObj.Id);
Console.WriteLine(abstrObj.GetType().ToString());

来源:https://github.com/FORzzMOK/Creating-an-abstract-class

抽象类旨在充当默认的行为提供程序,而不是用于实例化。因此,你需要从抽象类继承,获得氏族的最糟糕的行为,然后用特定的行为和状态扩展你继承的类。

在您的情况下,您需要创建父抽象类的引用,并实例化您自己继承的类,并将其分配给上面创建的引用。现在您可以返回这个抽象类引用了。