从基本定义初始化子类

时间:2014-05-06 11:00:16

标签: c# inheritance abstract-class

道歉,如果这是一个常见问题,但我花了很长时间谷歌搜索答案,无法找到明确的答案。

我有一个抽象类,其中包含其他抽象类的(定义)字段。然后将它们用于属性的具体实现。但是,当我想初始化该抽象类的实现时,我希望这些字段可以填充字段的特定实现。这实际上对我自己来说听起来很混乱,所以这是一个例子。

// My main abstract class
public abstract class Log
{
    public virtual bool AppendLog
    {
        set { _logWriter.Append = value; }
    }

    internal LogWriter _logWriter; //LogWriter is another abstract class

    public abstract void AddEntry(string input);
}

// Implementation of abstract class
public class SyncLog : Log
{
    public SyncLog
    {
        // Now I want to initialize LogWriter abstract class in parent with
        // It's actual implementation SyncLogWriter : LogWriter
        _logWriter = new SyncLogWriter(); 
    }

    public override void AddEntry(string input)
    {
        content.AddEntry(input);
        _logWriter.Write("Hello");
    }
}

虽然这在技术上符合甚至有效,但存在问题。使用_logWriter时,我只能访问在抽象类LogWriter中声明的方法和属性,而不能访问在它的子节点(SyncLogWriter)中另外实现的方法和属性。虽然技术上有意义但我想知道是否有任何方法可以采用类似的方法,但是可以使用SyncLogWriter中的所有其他内容吗?

3 个答案:

答案 0 :(得分:1)

在继承的班级_syncLogWriter上使用其他成员SyncLog。 另外,通过构造函数初始化基类的_logWriter成员并将其设置为私有更好。

// My main abstract class
public abstract class Log
{
    protected Log(LogWriter logWriter)
    {
        _logWriter = logWriter;
    }

    public virtual bool AppendLog
    {
        set { _logWriter.Append = value; }
    }

    private LogWriter _logWriter; //LogWriter is another abstract class

    public abstract void AddEntry(string input);
}

// Implementation of abstract class
public class SyncLog : Log
{
    private SyncLogWriter _syncLogWriter

    public SyncLog() : this(new SyncLogWriter()) { }

    private SyncLog(SyncLogWriter logWriter) : base(logWriter)
    {
        _syncLogWriter = logWriter; 
    }

    public override void AddEntry(string input)
    {
        content.AddEntry(input);
        _syncLogWriter.Write("Hello");
    }
}

答案 1 :(得分:1)

您可以创建SyncLogWriter类型的私有只读属性,该属性实际指向_logWriter

public class SyncLog : Log
{
    public SyncLog
    {
        _logWriter = new SyncLogWriter(); 
    }

    private SyncLogWriter LogWriter
    {
        get { return (SyncLogWriter)_logWriter; }
    }

    public override void AddEntry(string input)
    {
        content.AddEntry(input);
        _logWriter.Write("Hello");
    }

    private void DoSomething()
    {
         LogWriter.SomeSyncLogWriterMethod();
    }
}

答案 2 :(得分:1)

在我看来,比其他两个答案更清晰的解决方案是使用泛型,如下:

public abstract class Log<TLogWriter> where TLogWriter : LogWriter
{
    public virtual bool AppendLog
    {
        set { _logWriter.Append = value; }
    }

    internal TLogWriter _logWriter;

    public abstract void AddEntry(string input);
}

public class SyncLog : Log<SyncLogWriter>
{
    public SyncLog
    {
        _logWriter = new SyncLogWriter(); 
    }

    public override void AddEntry(string input)
    {
        content.AddEntry(input);
        _logWriter.Write("Hello");
    }
}

这消除了复制字段或强制转换

的需要