今天看Delphi的e-book,看到在delphi中以一种违反访问权限规则的“欺骗”方式访问其父类。此时我想到一个问题,就是当protected对对象进行封装保护时,是有很明显的后门的。在C#中,我们很容易将protected暴露为public。例如:
通过这种方法,我们就可以在另外的类中毫无顾忌地访问Base的Print()方法了。
换句话说,如果我们想暴露某个类的受保护方法或字段,OK,我们只需要生成一个wrapper类(对使用者,就好比是包装了该类,实质上是采用继承的方法),派生这个类,然后new这个受保护方法,并将其定义为public就可以了。如此一种“欺骗”的方式,轻而易举就窃取了类的受保护方法。
也就是说,通过继承的方法,我们可以提升父类设置的访问级别。当然对于父类的private是无能为力的。
所以,对于派生类而言,是应该直接派生其受保护方法呢?还是应该new一个新的,需要我们根据实际情况来选择。
posted on 2004-11-17 16:26 张逸 阅读(2935) 评论(21) 编辑 收藏 所属分类: C# Programming
呵呵,老兄 protected声明的方法本来就是为了让其子类可以使用 不让外部使用的方法你直接用private多简单 回复 引用 查看
呵呵。我已经意识到这点,其实我想说的是派生类可以提升其父类的访问级别。 所以我已经改了,没想到你回复得这么快,呵呵^_^ 回复 引用 查看
还有一个问题是,这个父类并非你实现的。如果你需要将父类的某些方法暴露出来,那就需要这样动动手脚了。 因此你在设计类库时,为了保证重用的灵活性时,还是应多考虑使用protected,而不是private,即使你的目的是不想让外部调用。一旦声明为private,可就被封装死了,想改就只有该父类的代码了。可惜的是,你不是父类的设计者,你是无权更改父类的代码的。 因此,选择protected还是private,这个选择还是很重要的。 回复 引用 查看
派生类可以提升其父类的访问级别 ----------------------- 这话说的真晦涩 回复 引用
public ^ internal ^ protected ^ private 这就是所谓的"提升访问级别"罗,呵呵:) 回复 引用 查看
這叫cracker class,這種技巧早就再用了。 主要是用在不同的程序單元的地方。 兩個類在同一個單元就不用這麼累的。 回复 引用 查看
internal是没法和protected比较的,如果非要比较,那么我认为internal无法穿透程序集的边界,所以internal不如protected。 public > protected internal > protected > internal > private 回复 引用
在.Net Framework,确实提供了五种访问级别。不过我觉得Ninputer写的顺序似乎有误,应该是: public > protected > internal > protected internal> private。 但是在C#中,只提供了四种,不包括protected internal。 不过对于internal和protected,没有完全的访问级别的高低界限。因为对于internal而言,只要是在同一程序集中,即使不是该类的派生类,也可以访问。而对于protected来说,另外一个程序集的类也可以访问它,但前提是必须继承该类。 所以,internal和protected两者的访问级别,以集合的概念来看,似乎是两个相交的集合。而其交集就是protected internal修饰符。它只能被同一程序集的派生类访问。 回复 引用 查看
不,protected internal是protected的范围 加上 internal的范围,是并集不是交集。 你好像没有用过的样子,回去试试。C#当然支持它了。VB也支持,叫Protected Friend 回复 引用
记得设计模式中曾提到,少用继承,多用引用,即使在对象关系上是继承的。 回复 引用
internal与protected 不好比较 但protected internal 确实比他门两个的范围大,这个可以比较 回复 引用 查看
敬请留意我的一篇新Blog,将对这一问题做出我个人的回答。今天太晚了,不放出来了,明天中午吧。 回复 引用 查看
声明的可访问性 意义 public 访问不受限制。 protected 访问仅限于包含类或从包含类派生的类型。 internal 访问仅限于当前程序集。 protected internal 访问仅限于从包含类派生的当前程序集或类型。 private 访问仅限于包含类型。 以上是MSDN对这几种访问限制的说明。Ninputer的观点是正确的,我将“当前程序集或类型”看作是“当前程序集的类型”了。protected internal 应该是internal和protected的并集,是我失误了。 不过我记得Applied .Net Framework里似乎还介绍了一种访问限制,是protected和internal的交集。这个修饰符在C#里并没有提供,但在IL里是有的,不知道是否正确,手边没有这本书,无法查阅了。 回复 引用 查看
protected internal 应该是internal和protected的并集 回复 引用
考虑一个成员的访问域(Accessibility domains),应该同时考虑包含这个成员的类的访问域,一个成员实际的访问域是两者的交集 回复 引用
C#不支持internal protected??? 事实上protected更大的作用是避免我们敲一个"."后出现一大堆我们根本就不想看到的东西。 回复 引用
wayfarer 还…… internal protected是internal和protected的交集。 不要老是咬文嚼字,自己试一下就全明白了。 尤其是VS2005的中文帮助,翻译错误多如牛毛…… 回复 引用
并集! FamilyOrAssembly -> protected internal http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=193386&SiteID=1 回复 引用
public > protected internal > protected > internal > private 这个顺序应该是对的 protected:只能被自身和继承的子类来访问 internal:只能被程序集内部访问,如果子类不和父类在一个程序集的话,那么子类是没有办法访问的。 protected internal:是两个的并集,无论是不是在一个程序集,子类都能访问,而且自己所在的程序集内的都能访问,说得有点乱,不过,我是理解了 ^_^ 回复 引用
不过,protected和internal,应该不能简单的说谁的范围大,谁的范围小的 如果都在同一个程序集那么,自然是internal的范围大 如果子类和父类不在一个程序集的话,可能就另说了吧?应该 回复 引用
《软件设计精要与模式》
《WCF服务编程》