我已对问题进行了更清晰的编辑。老问题在下面。
我有两个具有自己的数据库客户端实现的子类,但仍在相同的父数据库接口(例如存储库模式)下。
class Child1
{
protected IDB_Child1 DB;
public void Disconnect()
{
DB.disconnect();
}
}
class Child2
{
protected IDB_Child2 DB;
public void Disconnect()
{
DB.Disconnect();
}
}
interface IDB_Child1 : IDB {}
interface IDB_Child2 : IDB {}
interface IDB { void Disconnect() }
这有效:
Child1 c1 = new Child1();
c1.Disconnect(); //OK
很显然,我想将上面的通用功能移至父级,这是非常基本的重构步骤。我愿意:
abstract class Parent
{
protected IDB DB;
public void Disconnect()
{
DB.Disconnect();
}
}
class Child1 : Parent
{
protected IDB_Child1 DB;
}
class Child2 : Parent
{
protected IDB_Child2 DB;
}
由于某种原因,C#对于此类变量具有自己的作用域,而我无法从父类访问数据库:
Child1 c1 = new Child1();
c1.Disconnect(); // ERROR: DB is null in the parent even though in the c1 it is initialized and visible from child1 class methods.
我如何实现这种基本的OOP功能?
答案 0 :(得分:1)
您无需在子级中声明DB(您可以通过继承从父级访问一个)。提示您必须使用new关键字,因为它与父DB字段冲突(通常非常糟糕)。
只需删除
新的受保护的IDB_Child数据库;
这是一个完整的实现:
public interface IDB
{
void Bar();
}
abstract class Parent
{
protected IDB DB;
public Parent(IDB database) {
DB = database;
}
public void Foo()
{
DB.Bar();
}
}
class Child : Parent
{
public Child(IDBImplem database) : base(database) {}
public void ChildFoo()
{
DB.Bar();
}
}
public class IDBImplem : IDB
{
public void Bar()
{
}
}
答案 1 :(得分:1)
听起来仿制药可以满足您的需求(假设IDB_Child
扩展或实现IDB
):
abstract class Parent<T>
{
protected T DB;
public void Disconnect()
{
DB.Disconnect();
}
}
class Child1 : Parent<IDB_Child1>
{
}
class Child2 : Parent<IDB_Child2>
{
}
您也可以使用访问器代替继承字段:
abstract class Parent
{
protected IDB DB() {get;}
public void Disconnect()
{
getDB().Disconnect();
}
}
class Child1 : Parent
{
protected IDB_Child1 _DB;
override IDB DB()
{
get
{
return DB;
}
}
}
class Child2 : Parent
{
protected IDB_Child2 _DB;
override IDB DB()
{
get
{
return DB;
}
}
}
//错误:即使在c1中已初始化DB,并且在child1类方法中可见,它在父目录中也为空
这是因为您在子类中声明了(但未初始化,但没有显示)新的 DB
字段。由于父级DB
实例对子级可见,因此您无需声明其他实例。