访问标识符的真实示例[public,protected,private]



我是OOP的新手。

我知道有三个标识符,它们应该在不同的情况下使用。我也读过很多关于过度使用"公共"标识符是否危险的讨论。但我真的不明白为什么这很危险。

假设我有一个windows应用程序或web应用程序。在那些应用程序中,我声明了一些公共方法或变量,这有多危险?我的意思是,我的应用程序接受用户输入,然后产生输出,那么在哪些方面会有危险呢?其他程序或其他程序怎么会因为"公共"标识符而攻击或利用应用程序,或以某种方式对应用程序造成损害。

有人能描述一个现实生活中的例子吗?谢谢

Modifier    | Class | Package | Subclass | World
————————————+———————+—————————+——————————+———————
public      |  ✔    |    ✔    |    ✔     |   ✔
————————————+———————+—————————+——————————+———————
protected   |  ✔    |    ✔    |    ✔     |   ✘
————————————+———————+—————————+——————————+———————
no modifier |  ✔    |    ✔    |    ✘     |   ✘
————————————+———————+—————————+——————————+———————
private     |  ✔    |    ✘    |    ✘     |   ✘

私有:

方法、变量和构造函数

声明为私有的方法、变量和构造函数只能在声明的类本身中访问。

专用访问修饰符是限制性最强的访问级别。类和接口不能是私有的。

注意

如果类中存在公共getter方法,则可以在类外部访问声明为private的变量。在超类中声明为受保护的变量、方法和构造函数只能由其他包中的子类或受保护成员类的包中的任何类访问。

受保护

受保护的访问修饰符不能应用于类和接口。

方法、字段可以被声明为受保护,但是接口中的方法和字段不能被声明为保护。

注意

受保护的访问使子类有机会使用辅助方法或变量,同时防止非相关类尝试使用它

公共

声明为公共的类、方法、构造函数、接口等可以从任何其他类访问。

因此,在公共类中声明的字段、方法和块可以从属于Java宇宙的任何类访问。

http://javarevisited.blogspot.com/2012/10/difference-between-private-protected-public-package-access-java.html

以下是您的答案:https://softwareengineering.stackexchange.com/questions/143736/why-do-we-need-private-variables

简而言之,从长远来看,这是一个保持复杂性和可重用性的问题。通过确保变量对类是私有的,您可以阻止其他程序员(甚至您未来的自己)修改任何影响类内部的主要内容。

作为一个现实世界的例子,想象一下你未来的自己坐在你写的一些代码旁边,试图找到某个错误发生的地方。经过几天的搜寻,你确定了罪魁祸首:你的类的一个实例的成员变量被修改了。甚至不是你,而是你团队中一位依赖该变量的同事。

现在你有一个大问题。私有变量使您免于所有这些麻烦。

让我们将其提升到元级别,并假设我们是类Person的实例。

我们有一些关于我们的信息——nameagegenderweightheighthairColoreyeColor等等。大多数情况下,这是我们通过偶然的互动暴露给外界的信息,因此这可以被视为"公共"信息。我的意思是,隐藏你的eyeColor是没有意义的,除非你真的想…

现在,有一些事情我们不告诉外界,但愿意告诉我们的孩子。这些都是食谱、如何解决数学问题、如何纳税、如何处理令人讨厌的分手等。这些函数是通过继承传递的,因此,只能根据祖先的层次结构来引用。我们称之为"受保护的"信息,或解决这些问题的"受保护"方法。

还有一些我们只在家里保存的东西,比如你的小狗咬了你姐姐最喜欢的娃娃的次数,或者家族遗产在哪里。我们可以考虑,在我们家族的等级制度中,这是私人的。

最后,有些东西我们只是没有与其他人分享,但我们每天都需要这些信息来发挥作用。这就是我们所认为的"私人"。

现在,这个元示例的示例是Access Modifiers的一个经典示例。

  • public表示每个人都可以看到它,并对它为所欲为。也就是说,如果你有一个public可访问的名称,那么我可以随心所欲地将其更改为"Overflow Prime",你对此无能为力。

  • protected表示此字段或方法仅对那些直接从类继承的字段或方法可见。例如,Child extends Parent意味着我可以访问Parent的受保护方法和字段。

  • "package private",或者简称为"no修饰符",是一个只能在包的范围内访问和修改的字段或方法。这意味着,就包而言,字段是public,但包之外的任何字段都完全未知。

  • private是一个字段或方法,只有该类的实例才能直接使用和操作。即使有继承链,如果方法或字段是私有的,子类也无法访问它

现在,就你的现实世界例子而言,这意味着什么?

比方说,您的web应用程序处理敏感信息,如财务记录。如果我能够将持有我每周工资支票存根的班级的实例从微薄的600美元修改为相当大的79999美元,那么我既会损害你的应用程序的完整性,也会暴露出一个重大的财务漏洞(导致糟糕的事情发生),还会因为我的麻烦而被削减一张体面的每周支票。

这就是封装背后的理念。我只想向外界公开最起码的挂钩和信息,以确保我的应用程序的完整性,并确保有人不会给自己开出不应得的支票。

我试图在非常基本的代码和注释的帮助下回答这个问题。

package com.oops;
public class Modifiers {
public int a = 0;
private int b = 0;
protected int c = 0;
int d = 0;
public static void main(String[] args) {
new TestPublic().getAndPrintA();
new TestPrivate().cannotGetB();
new TestProtected().getProtected();
new TestDefault().getDefault();
}
}
class TestPublic {
public void getAndPrintA() {
Modifiers modifiers = new Modifiers();
modifiers.a = 10; // Public variables can be used from anywhere.
}
}
class TestPrivate {
public void cannotGetB() {
Modifiers modifiers = new Modifiers();
// modifiers.b; //Compile time error: The field Modifiers.b is not
// visible
}
}
class TestProtected {
public void getProtected() {
Modifiers modifiers = new Modifiers();
modifiers.c = 10; // Visible here, but will not be visible to the
// outside world.
// Protected means package and subclass
}
}
class TestDefault {
public void getDefault() {
Modifiers modifiers = new Modifiers();
modifiers.d = 10; // Visible here, but will not be visible to the
// outside world and subclass.
// Default means only within package.
}
}

虽然其他人已经很好地解释了这些概念,但我认为这个问题需要一个真实的例子。以下是关于概念的解释。请注意包裹名称:myarea

package myarea;
public class MyHome{
private int frontDoorLock;
public int myAddress;
int defaultWifiPaswd;
}

现在,注释(有效/无效)将其解释清楚在另一个文件中,但相同的包:myarea

package myarea;
public class MyBedroom{
public static void main(String[] args) {
MyHome a = new MyHome();
int v1 = a.myAddress; // works
int v2 = a.defaultWifiPaswd; // works
int v3 = a.frontDoorLock; // doesn’t work
}
}

另一个文件不同的包:neighborArea

package neighbourArea;
import myarea.MyHome;
public class NeighbourHome{
public static void main(String[] args) {
MyHome a = new MyHome();
int v1 = a.myAddress; // works
int v2 = a.defaultWifiPwd; // doesn’t work
int v3 = a.privateVar; // doesn’t work
}

最初,我分享这篇文章是为了向Java代码爱好者解释其中一篇文章。

最新更新