封装 VS 继承 - 如何使用受保护的函数?

发布于 2024-07-08 17:25:59 字数 172 浏览 8 评论 0原文

在 C# 或 VB.NET 等 OOP 语言中,如果我将超类中的属性或方法设置为受保护的,我将无法在表单中访问它们 - 它们只能在继承自的类中访问那个超级班。

要访问这些属性或方法,我需要将它们设为公共,这会破坏封装性,或者将它们重新写入我的类中,这会破坏继承性。

这样做的正确方法是什么?

In OOP languages like C# or VB.NET, if I make the properties or methods in a super class protected I can't access them in my Form - they can only be accessed in my class that inherits from that super class.

To access those properties or methods I need to make them public, which defeats encapsulation, or re-write them into my class, which defeats inheritance.

What is the right way to do this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

生生漫 2024-07-15 17:25:59

如果您的代码需要要求类执行特定操作,但该类没有为您的代码提供执行此操作的方法,则该类无法满足您的代码要求。

这有点像说我有一辆汽车,它有一个受保护的方向盘,所以我无法访问它。 车子对我来说没什么用。

要么将这些成员设为公共(或至少是内部)并使用它们,要么放弃该类并使用一个为您的消费代码提供所需功能的类。

也许您真正需要的是一个界面。 该接口包含您的代码所需的成员,并且您可以在您的类上实现该接口。 这里的优点是您的类可以确定正在通过此接口而不是继承子类访问成员。

If you have code which needs to ask an Class to perform a specific operation but the class does not present your code with a means to do that then the Class doesn't fulfill you codes requirements.

Its bit like saying I've got a Car (Automobile) that has a protected steering wheel so I can't access it. The car is no use to me.

Either make those members Public (or at least internal) and use them or ditch the class and use one that gives your consuming code the features it needs.

Perhaps what you are really looking for is an interface. The interface contains the members your code needs and you implement that interface on your class. The advantage here is that your class can determine that the members are being accessed via this Interface rather than an inheriting subclass.

违心° 2024-07-15 17:25:59

“需要将它们公开,这会破坏封装性”

不要将良好的设计与令人讨厌的可见性规则混为一谈。 可见性规则令人困惑。 实际上有两种正交的可见性——子类和客户端。 目前尚不完全清楚为什么我们要向子类隐藏任何内容。 但我们可以,通过private

这就是重要的事情。 封装并不意味着隐藏。 受保护和私有并不是良好封装的重要组成部分。 您可以通过公开所有内容来进行良好的设计(例如,Python 就是这样工作的)。

受保护/私有的内容主要是关于知识产权管理:您是否愿意(以具有法律约束力的“如果不起作用,法庭见”的方式)承诺界面? 如果您的软件开发涉及律师,那么您会关心为您不承诺的事情添加保护和隐私。

如果您不必与律师打交道,请考虑正确进行封装,但将所有内容公开。

"need to make them public which defeats encapsulation"

Don't conflate good design with the icky visibility rules. The visibility rules are confusing. There are really two orthogonal kinds of visibility -- subclass and client. It's not perfectly clear why we'd ever conceal anything from our subclasses. But we can, with private.

Here's what's important. Encapsulation does not mean hiding. Protected and private are not an essential part of good encapsulation. You can do good design with everything being public (that's the way Python works, for example).

The protected/private stuff is -- mostly -- about intellectual property management: are you willing to commit (in a legally binding, "see-you-in-court-if-it-doesn't-work" way) to an interface? If your software development involves lawyers, then you care about adding protect and private to the things you're not committed to.

If you don't have to cope with lawyers, consider doing encapsulation right but leave everything public.

晨曦÷微暖 2024-07-15 17:25:59

抱歉,不清楚您所说的“在我的表格中”是什么意思 - 您的表格和两个班级之间的关系是什么? 如果您的类是同一项目中的控件,并且您想要从表单访问属性,则应使用“internal”关键字。

Sorry, it's not clear what you mean by "in my Form" - what is the relationship between your Form and your two classes? If your classes are controls in the same project, and you want to access properties from the form, you should use the 'internal' keyword.

静若繁花 2024-07-15 17:25:59

至少可以通过三种方法来限制谁可以使用特定类实例的某些特定实例方法:

  1. 将方法定义为“protected”、“internal”或“private”。 在第一种情况下,实例方法只能在同一实例的派生类方法中使用; 在第二种情况下,程序集中的所有类都可以访问这些方法,但外部的类则不能; 在第三种情况下,任何外部类(甚至同一程序集中的派生类)都无法访问,除非它们的代码嵌套在声明类中。
  2. 将方法定义为“public”,但让创建实例的类将它们保持为私有,并且永远不会将它们暴露给外界。 任何想要调用对象上的实例方法的人都必须有一个实例来调用它。 如果一个类持有实例但从不公开对它们的直接引用,则可以在这些实例上使用的唯一实例方法将是持有类本身使用的实例方法。
  3. 将方法定义为“public”,但有一个构造函数,该构造函数接受一个位置,可以在该位置存储一个或多个私有方法的委托。 有权访问这些委托的代码将能够调用由此引用的方法,但其他代码则不能(除非以我认为仅在完全信任场景中可用的方式使用反射)。

如果非完全信任场景中的反射允许未绑定的委托绑定到任意对象实例,则可以使用嵌套类来强化#3,这样就必须访问 private 字段才能获得非法访问到 private 函数; 在完全信任的场景之外,这肯定是被禁止的。

There are at least three ways you can limit who can use some particular instance method of particular class instances:

  1. Define the method as `protected`, `internal`, or `private`. In the first case, an instance method will only be usable from within derived-class methods of the same instance; in the second case, all classes within the assembly will have access to those methods, but classes outside won't; in the third case, no outside classes, even derived ones in the same assembly, will have access, unless their code is nested within the declaring class.
  2. Define the method as `public`, but have the classes that create instances keep them private and never expose them to the outside world. Anyone wanting to invoke an instance method on an object has to have an instance to invoke it on. If a class holds instances but never exposes direct references to them, the only instance methods that can ever be used on those instances will be those which the holding classes uses itself.
  3. Define the method as `public`, but have a constructor which accepts a location into which one or more delegates to private methods may be stored. Code with access to those delegates will be able to call the methods referred to thereby, but other code will not (except by using Reflection in ways which I think are only usable in full-trust scenarios).

If Reflection in non-full-trust scenarios would allow unbound delegates to be bound to arbitrary object instances, one could use nested classes to reinforce #3 so that one would have to access private fields to gain illegitimate access to the private functions; that would definitely be forbidden outside full-trust scenarios.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文