考虑这种情况: (请注意,为简洁起见,省略了类型和方法体)
当我需要这样做时,这会让我与数据联系起来。
public abstract class DatabaseAccessor {
protected static object GetDataFromDatabase(...) {...}
protected static object UpdateSomething(...) {...}
}
这管理缓存 - 如果我向ServerCache询问资源但它没有,那么ServerCache可以使用DatabaseAccessor来获取它所需的内容。我无法直接访问缓存的资源。
public abstract class ServerCache : DatabaseAccessor {
private static object CachedResources;
protected static object GetFromCacheOrGetFresh(...) {...}
protected static void InvalidateCache(...) {...}
}
这是一种服务,它提供了一种访问缓存数据或新数据,发送更新,使缓存资源无效/过期的方法。
public class DepartmentsService : ServerCache {
public static object Read() {
...
return ServerCache.GetFromCacheOrGetFresh();
}
public static object Update(string id) {
...
DatabaseAccessor.UpdateSomething(...);
ServerCache.InvalidateCache(...);
return DepartmentsService.Read().Where(record => record.Id == id);
}
public static object Create(...){...}
}
在我需要创建其他服务之前,这一直很有效,就像上面的那样。它是这样的:
public class EmployeeService : ServerCache {
...
public static object Create(object creation) {
//check first service to see if creation is valid
//by checking that the DepartmentsService contains creation.Department.
DepartmentsService.Read().Where(..... problem
}
}
在非派生类中调用DepartmentsService的DepartmentsService OUTSIDE时,我能够看到ServerCache的所有受保护方法。
在设计中,Web Api控制器同时使用DepartmentsService和EmployeeService。控制器不从ServerCache继承,并且方法按预期隐藏。
因为DepartmentsService和EmployeesService都来自ServerCache,这不应该意味着EmployeesService应该能够调用DepartmentsService的本质私有方法。
我在这里想到的保护修饰符是什么?
当保护与静态一起使用时,我是否会遗漏一些细微差别?
这是"方法隐藏"会发生什么?
答案 0 :(得分:3)
DepartmentsService
和EmployeeService
僵尸程序继承自ServerCache
,其自身继承自DatabaseAccessor
。
EmployeeService
可以看到什么?首先,它可以看到所有其他类的所有公共成员,包括DepartmentsService
。此外,它可以看到DatabaseAccessor
和ServerCache
的所有受保护方法,因为它在继承层次结构中位于它们之下。
这是它可以看到的列表:
protected static DatabaseAccessor.GetDataFromDatabase(...)
protected static DatabaseAccessor.UpdateSomething(...)
protected static ServerCache.GetFromCacheOrGetFresh(...)
protected static ServerCache.InvalidateCache(...)
public static DepartmentsService.Read()
public static DepartmentsService.Update(string id)
public static DepartmentsService.Create(...)
protected
成员继承后会发生什么? 它仍然是它的基础:基类的protected
成员。它在基类上下文中执行,除非它被new
- 关键字(或virtual
和override
覆盖,这在您的情况下是不允许的,因为它全部被声明为{{ 1}})。因此它对父类的所有子类都是可见的。
这是需要注意的基本点和liskov substitution principle的驱动程序之一,它基本上说应该能够将子类的实例分配给引用它的基类,然后调用基类成员,它的行为应该像人们期望基类实例的行为,而不是知道它实际上是一个子类实例。
让我告诉你这个给出的例子意味着什么,假设方法 不是static
:
static
的行为应完全相同:
DatabaseAcccessor accessor = new ServerCache();
var data = accessor.GetDataFromDatabase(...);
因为如果变量或参数引用派生类型实例,你永远不会知道。
因此,在使用ServerCache accessor = new ServerCache();
var data = accessor.GetDataFromDatabase(...);
和new
时务必小心,并且通常偏好合成而不是继承。
您如何阻止override
DatabaseAccessor
上DepartmentService
调用EmployeeService
的受保护方法?
这需要一点点重组。我建议制作ServerCache Singleton或Monostate。让我们选择Singleton:
public class ServerCache : DatabaseAccessor {
private object CachedResources;
private static readonly ServerCache instance;
private ServerCache(){ /* private ctor to prevent instances from beeing createt anywhere but in this class */ }
private static ServerCache Instance
{
get
{
if(instance==null)
instance = new ServerCache();
return instance;
}
}
public object GetFromCacheOrGetFresh(...) {...}
public void InvalidateCache(...) {...}
}
您现在可以在ServerCache
和DepartmentsService
中创建EmployeeService
个变量,而不是从ServerCache
继承。这样,ServerCache
方法将无法用作DepartementsService的protected
方法。