Java中的public、protected、包私有和私有有什么区别?

Java,是否有明确的规则来规定何时使用每个访问修饰符,即默认(包私有)、publicprotectedprivate,同时制作classinterface并处理继承?

2463440 次浏览

官方教程可能对你有用。


子类
(相同的pkg)
子类
(diff pkg)
世界
public+++++
protected++++
没有修饰语+++
private+

+:可访问
空白:无法访问

简单的规则。从宣布一切都是私有的开始。然后随着需求的出现和设计的保证,向公众发展。

当公开成员时,问问自己是公开表示选择还是抽象选择。第一个是你想要避免的,因为它会引入太多对实际表示的依赖,而不是对其可观察行为的依赖。

作为一般规则,我尽量避免通过子类化来覆盖方法实现;搞砸逻辑太容易了。如果您打算覆盖它,请声明抽象保护方法。

此外,在重写时使用@Overides注释,以防止重构时发生故障。

差异可以在已经提供的链接中找到,但使用哪一个通常归结为“最少知识原则”。只允许所需的最小可见性。

(警告:我不是一个Java程序员,我是一个Perl程序员。Perl没有正式的保护,这也许就是为什么我这么了解这个问题:))

私人

就像你想的那样,只有声明它的才能看到它。

包私有

它只能被声明它的看到和使用。这是Java中的默认值(有些人认为这是一个错误)。

保护

Package Private+可以通过子类或包成员看到。

公共

每个人都可以看到它。

已发布

在我控制的代码之外可见(虽然不是Java语法,但它对本讨论很重要)。

C++定义了一个叫做“朋友”的额外级别,你知道的越少越好。

什么时候应该使用What?整个想法就是隐藏信息的封装。你想尽可能地向用户隐藏某些事情是如何完成的细节。为什么?因为这样你就可以稍后更改它们,而不会破坏任何人的代码。这让你可以优化、重构、重新设计和修复错误,而不用担心有人在使用你刚刚大修的代码。

所以,经验法则是让事情只在必要的时候可见。从私有开始,只在需要的时候增加更多的可见性。只公开用户需要知道的东西,你公开的每个细节都会限制你重新设计系统的能力。

如果你希望用户能够自定义行为,而不是将内部内容公开以便他们可以覆盖它们,那么将这些内容推送到对象中并使该接口公开通常是一个更好的主意。这样他们就可以简单地插入一个新对象。例如,如果你正在编写一个CD播放器并且希望“去查找有关这张CD的信息”位可自定义,而不是将这些方法公开,那么你应该将所有这些功能放入其对象中,并仅公开你的对象getter/setter。这样,吝啬地暴露你的胆量会鼓励良好的组合和关注点分离

我坚持只使用“私有”和“公共”。许多OO语言就是这样。“受保护”可能很方便,但它是一种欺骗。一旦界面不仅仅是私有的,它就超出了你的控制范围,你必须去寻找其他人的代码来找到用途。

这就是“已发布”的想法的用武之地。更改一个接口(重构它)需要你找到所有使用它的代码,并也要更改它。如果接口是私有的,没问题。如果它受保护,你必须找到你所有的子类。如果它是公共的,你必须找到所有使用你代码的代码。有时这是可能的,例如,如果你使用的是仅供内部使用的公司代码,接口是否公开并不重要。你可以从公司存储库中获取所有代码。但是如果一个接口被“发布”了,如果有代码在你的控制之外使用它,那么你就完了。你必须支持那个接口,否则就有破坏代码的风险。即使是受保护的接口也可以被认为是发布的(这就是为什么我不打扰受保护的接口)。

许多语言发现public/protected/Private的分层性质过于局限,不符合现实。为此,有性状类的概念,但这是另一种表现。

David的回答提供了每个访问修饰符的含义。至于何时使用每个,我建议公开所有供外部使用的类和每个类的方法(其API),其他一切都是私有的。

随着时间的推移,您将了解何时将某些类设为包私有,以及何时声明某些方法受保护以在子类中使用。

这个页面写的很好关于protected&default访问修饰符

受保护的:受保护的访问修饰符有点棘手,你可以说是默认访问修饰符的超集。就同一包中的访问而言,受保护的成员与默认成员相同。不同的是,受保护的成员也可以访问声明成员的类的子类,这些子类位于父类所在的包中。

但是这些受保护的成员“只能通过继承在包外访问”。也就是说,你可以直接访问一个类的子类中存在于其他包中的受保护成员,就好像该成员存在于子类本身一样。但是,通过使用父类的引用,该受保护成员将无法在包外的子类中访问。……

它实际上比简单的网格显示的要复杂一点。网格告诉你是否允许访问,但访问到底是什么构成的?此外,访问级别与嵌套类和继承以复杂的方式交互。

“默认”访问(由缺少关键字指定)也称为包-私有。例外:在接口中,没有修饰符意味着公共访问;禁止使用公共以外的修饰符。枚举常量始终是公共的。

总结

是否允许使用此访问说明符访问成员?

  • 成员为private:仅当成员与调用代码在同一类中定义时。
  • 成员是包私有的:只有当调用代码在成员的直接封闭包中时。
  • 成员是protected:相同的包,或者成员是在包含调用代码的类的超类中定义的。
  • 成员public:是的。

什么访问说明符适用于

局部变量和形式参数不能接受访问说明符。根据作用域规则,它们本质上是不可访问的,因此它们实际上是私有的。

对于顶部作用域中的类,只允许public和包私有。这种设计选择大概是因为protectedprivate在包级别是多余的(包没有继承)。

所有访问说明符都可以在类成员(构造函数、方法和静态成员函数、嵌套类)上使用。

相关:Java无障碍

订单

访问说明符可以严格排序

公共>受保护>包私有>私有

这意味着public提供了最多的访问权限,private提供了最少的访问权限。对私有成员的任何引用对包私有成员也有效;对包私有成员的任何引用对受保护成员都有效,依此类推。(将受保护成员的访问权限授予同一包中的其他类被认为是错误的。)

备注

  • 类的方法允许访问同一类的其他对象的私有成员。更准确地说,类C的方法可以访问C的任何子类的对象上的C的私有成员Java不支持通过实例限制访问,只能通过类。(
  • 你需要访问构造函数来构造一个对象。因此,如果所有构造函数都是私有的,则该类只能由类中的代码构造(通常是静态工厂方法或静态变量初始化器)。包私有或受保护的构造函数也是如此。
    • 只有私有构造函数也意味着类不能在外部被子类化,因为Java需要子类的构造函数隐式或显式调用超类构造函数。(但是,它可以包含一个嵌套类来子类化它。)

内部类

你还必须考虑嵌套范围,例如内部类。复杂性的一个例子是内部类有成员,这些成员本身可以接受访问修饰符。所以你可以有一个带有公共成员的私有内部类;该成员可以被访问吗?(见下文。)一般规则是查看范围并递归思考,看看你是否可以访问每个级别。

然而,这是相当复杂的,完整的细节,查看Java语言规范。(是的,过去有编译器错误。)

要了解这些类是如何交互的,请考虑这个例子。有可能“泄漏”私有内部类;这通常是一个警告:

class Test {public static void main(final String ... args) {System.out.println(Example.leakPrivateClass()); // OKExample.leakPrivateClass().secretMethod(); // error}}
class Example {private static class NestedClass {public void secretMethod() {System.out.println("Hello");}}public static NestedClass leakPrivateClass() {return new NestedClass();}}

编译器输出:

Test.java:4: secretMethod() in Example.NestedClass is defined in an inaccessible class or interfaceExample.leakPrivateClass().secretMethod(); // error^1 error

一些相关的问题:

在很短

  • public:从任何地方访问。
  • protected:同一包中的类和驻留在任何包中的子类都可以访问。
  • 默认(未指定修饰符):同一包的类可访问。
  • private:只能在同一个类中访问。

作为一个经验法则:

  • private:类范围。
  • default(或package-private):包范围。
  • protectedpackage scope + child(类似包,但我们可以从不同的包中对其进行子类化)。protected修饰符始终保持“父子”关系。
  • 0:到处都是。

因此,如果我们将访问权分为三个权利:

  • (D)直接(从同一类内的方法调用,或通过“this”语法调用)。
  • (R)参考(使用对类的引用或通过“点”语法调用方法)。
  • (一)继承(通过子类化)。

然后我们有这个简单的表:

+—-———————————————+————————————+———————————+|                 |    Same    | Different ||                 |   Package  | Packages  |+—————————————————+————————————+———————————+| private         |   D        |           |+—————————————————+————————————+———————————+| package-private |            |           || (no modifier)   |   D R I    |           |+—————————————————+————————————+———————————+| protected       |   D R I    |       I   |+—————————————————+————————————+———————————+| public          |   D R I    |    R  I   |+—————————————————+————————————+———————————+
____________________________________________________________________| highest precedence <---------> lowest precedence*———————————————+———————————————+———————————+———————————————+———————\ xCanBeSeenBy | this          | any class | this subclass | any\__________   | class         | in same   | in another    | class\  | nonsubbed     | package   | package       |Modifier of x \ |               |           |               |————————————————*———————————————+———————————+———————————————+———————public          |       ✔       |     ✔     |       ✔       |   ✔————————————————+———————————————+———————————+———————————————+———————protected       |       ✔       |     ✔     |       ✔       |   ✘————————————————+———————————————+———————————+———————————————+———————package-private |               |           |               |(no modifier)   |       ✔       |     ✔     |       ✘       |   ✘————————————————+———————————————+———————————+———————————————+———————private         |       ✔       |     ✘     |       ✘       |   ✘____________________________________________________________________

Java中最容易被误解的访问修饰符是protected。我们知道它类似于默认修饰符,只有一个例外,子类可以看到它。但是怎么做呢?下面是一个例子,希望能澄清混淆:

  • 假设我们有2个类;FatherSon,每个都在自己的包中:

    package fatherpackage;
    public class Father{
    }
    -------------------------------------------
    package sonpackage;
    public class Son extends Father{
    }
  • Let's add a protected method foo() to Father.

    package fatherpackage;
    public class Father{protected void foo(){}}
  • The method foo() can be called in 4 contexts:

    1. Inside a class that is located in the same package where foo() is defined (fatherpackage):

      package fatherpackage;
      public class SomeClass{public void someMethod(Father f, Son s){f.foo();s.foo();}}
    2. Inside a subclass, on the current instance via this or super:

      package sonpackage;
      public class Son extends Father{public void sonMethod(){this.foo();super.foo();}}
    3. On an reference whose type is the same class:

      package fatherpackage;
      public class Father{public void fatherMethod(Father f){f.foo(); // valid even if foo() is private}}
      -------------------------------------------
      package sonpackage;
      public class Son extends Father{public void sonMethod(Son s){s.foo();}}
    4. On an reference whose type is the parent class and it is inside the package where foo() is defined (fatherpackage) [This can be included inside context no. 1]:

      package fatherpackage;
      public class Son extends Father{public void sonMethod(Father f){f.foo();}}
  • The following situations are not valid.

    1. On an reference whose type is the parent class and it is outside the package where foo() is defined (fatherpackage):

      package sonpackage;
      public class Son extends Father{public void sonMethod(Father f){f.foo(); // compilation error}}
    2. A non-subclass inside a package of a subclass (A subclass inherits the protected members from its parent, and it makes them private to non-subclasses):

      package sonpackage;
      public class SomeClass{public void someMethod(Son s) throws Exception{s.foo(); // compilation error}}

私人

  • 方法、变量和构造函数

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

  • 类和接口

私有访问修饰符是最严格的访问级别。类和接口不能是私有的。

注意

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


保护

  • 类和接口

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

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

注意

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


公共

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

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

  • 不同的包

但是,如果我们尝试访问的公共类位于不同的包中,则仍然需要导入公共类。

由于类继承,类的所有公共方法和变量都由其子类继承。


默认-关键字:

默认访问修饰符意味着我们没有显式声明类、字段、方法等的访问修饰符。

  • 在相同的包

声明时不带任何权限改造的变量或方法可用于同一包中的任何其他类。接口中的字段是隐式公共静态Final,接口中的方法默认是公共的。

注意

我们无法覆盖静态fields.if您尝试覆盖它没有显示任何错误但它不工作,我们除了什么。

相关答案

参考资料链接

http://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.htmlhttp://www.tutorialspoint.com/java/java_access_modifiers.htm

私人:仅限访问类

默认值(无修饰符):对类和包的访问受限

保护:对类、包和子类的访问受限(包内外)

公共:可访问类、包(所有)和子类……简而言之,无处不在。

公共保护默认值和私有是访问修饰符。

它们用于封装,或隐藏和显示类的内容。

  1. 类可以是公共的或默认的
  2. 类成员可以是公共的、受保护的、默认的或私有的。

私有不能在类之外访问默认值只能在包中访问。在包以及任何扩展它的类中受到保护。对所有人开放

通常,成员变量被定义为私有的,但成员方法是公共的。

访问修饰符用于在多个级别上限制访问。

公众:它基本上和你可以从任何类访问一样简单,无论它是否在同一个包中。

如果您在同一个包中,则可以直接访问,但如果您在另一个包中,则可以创建该类的对象。

默认值:它可以在同一包中从任何类包中访问。

要访问,您可以创建该类的对象。但您不能在包之外访问此变量。

保护:您可以访问同一包中的变量以及任何其他包中的子类。所以基本上是默认+继承行为。

要访问基类中定义的protected字段,您可以创建子类的对象。

私人:它可以在同一个类中访问。

在非静态方法中,由于这个引用(也在构造函数中),您可以直接访问,但要在静态方法中访问,您需要创建类的对象。

包可见。默认值。不需要修饰符。

仅对类可见(私人)。

对世界可见(公共)。

包和所有子类可见(保护)。

变量和方法可以在没有调用任何修饰符的情况下声明。默认示例:

String name = "john";
public int age(){return age;}

私有访问修饰符-私有:

声明为私有的方法、变量和构造函数只能在声明的类本身内访问。私有访问修饰符是最受限制的访问级别。类和接口不能是私有的。

如果类中存在公共getter方法,则可以在类之外访问声明为私有的变量。

使用私有修饰符是对象封装自身并向外部世界隐藏数据的主要方式。

示例:

Public class Details{
private String name;
public void setName(String n){this.name = n;}
public String getName(){return this.name;}}

公共访问修饰符-公共:

声明为public的类、方法、构造函数、接口等可以从任何其他类访问。因此,在公共类中声明的字段、方法、块可以从属于Java宇宙的任何类访问。

但是,如果我们尝试访问的公共类位于不同的包中,则仍然需要导入公共类。

由于类继承,类的所有公共方法和变量都由其子类继承。

示例:

public void cal(){
}

受保护的访问修饰符-protected:

在超类中声明受保护的变量、方法和构造函数只能由另一个包中的子类或受保护成员类的包中的任何类访问。

受保护的访问修饰符不能应用于类和接口。方法、字段可以声明为受保护,但接口中的方法和字段不能声明为受保护。

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

class Van{
protected boolean speed(){
}}
class Car{boolean speed(){}
}
  • public-可以从应用程序中的任何位置访问。

  • default-可从包访问。

  • 保护-可从其他包中的包和子类访问。还有

  • 私有-只能从它的类访问。

这是一个更好的表版本,它还包括一个模块列。

在此处输入图片描述


解释

  • 私人成员(i)在声明的同一个类中可以只有访问。

  • 无访问修饰符j)的成员只能在同一包中的类中访问。

  • 保护成员(k)可以在同一包中的所有类中访问,也可以在其他包的子类中访问。

  • 所有类都可以访问公共成员(l)(除非它驻留在不导出声明它的包的模块中)。


选择哪个修饰符?

访问修饰符是一种帮助您防止意外破坏封装(*)的工具。问问自己,您是否希望成员是类、包、类层次结构的内部成员,还是根本不是内部成员,并相应地选择访问级别。

示例:

  • 字段long internalCounter可能应该是私有的,因为它是可变的并且是实现细节。
  • 一个只应该在工厂类(在同一个包中)中实例化的类应该有一个包限制构造函数,因为它不可能直接从包外调用它。
  • 在渲染之前调用并用作子类中的钩子的内部void beforeRender()方法应该受到保护。
  • 从GUI代码调用的void saveGame(File dst)方法应该是公共的。

(*)什么是封装?

Java中的访问修饰符。

Java访问修饰符用于在Java中提供权限改造。

1.默认:

只能访问同一包中的类。

例如,

// Saved in file A.javapackage pack;
class A{void msg(){System.out.println("Hello");}}
// Saved in file B.javapackage mypack;import pack.*;
class B{public static void main(String args[]){A obj = new A(); // Compile Time Errorobj.msg(); // Compile Time Error}}

这种访问比公共和受保护的访问更受限制,但比私有访问更受限制。

2.公共

可以从任何地方访问。(全球访问)

例如,

// Saved in file A.java
package pack;public class A{public void msg(){System.out.println("Hello");}}
// Saved in file B.java
package mypack;import pack.*;
class B{public static void main(String args[]){A obj = new A();obj.msg();}}

输出:你好

3.私营

只能在同一个类中访问。

如果您尝试访问另一个类中一个类的私有成员,将引发编译错误。例如,

class A{private int data = 40;private void msg(){System.out.println("Hello java");}}
public class Simple{public static void main(String args[]){A obj = new A();System.out.println(obj.data); // Compile Time Errorobj.msg(); // Compile Time Error}}

4.受保护

只能访问同一包中的类和子类

例如,

// Saved in file A.javapackage pack;public class A{protected void msg(){System.out.println("Hello");}}
// Saved in file B.javapackage mypack;import pack.*;
class B extends A{public static void main(String args[]){B obj = new B();obj.msg();}}

输出:你好

在此处输入图片描述

注:这只是对已接受的答案的补充。

这与Java访问修饰符有关。

Java访问修饰符

Java访问修饰符指定哪些类可以访问给定的类及其字段、构造函数和方法。访问修饰符可以为类、其构造函数、字段和方法Java访问修饰符有时也在日常Java访问说明符,但正确的名称是Java访问修饰符。类、字段、构造函数和方法可以具有以下之一四个不同的Java访问修饰符:

  • 列表项
  • 私人
  • 默认(包)
  • 保护
  • 公共

控制对类成员的访问教程:

访问级别修饰符确定其他类是否可以使用特定字段或调用特定方法。有两个级别权限改造:

  • 在顶层-公共或包私有(没有显式修饰符)。
  • 在成员级别-公共、私有、受保护或包私有(没有显式修饰符)。

一个类可以用修饰符public声明,在这种情况下类对任何地方的所有类都是可见的。如果一个类没有修饰符(默认值,也称为包私有),它只是可见的在自己的包中

下表显示了每个成员允许的访问权限修饰符。

╔═════════════╦═══════╦═════════╦══════════╦═══════╗║ Modifier    ║ Class ║ Package ║ Subclass ║ World ║╠═════════════╬═══════╬═════════╬══════════╬═══════╣║ public      ║ Y     ║ Y       ║ Y        ║ Y     ║║ protected   ║ Y     ║ Y       ║ Y        ║ N     ║║ no modifier ║ Y     ║ Y       ║ N        ║ N     ║║ private     ║ Y     ║ N       ║ N        ║ N     ║╚═════════════╩═══════╩═════════╩══════════╩═══════╝

第一个数据列表示类本身是否可以访问由访问级别定义的成员。正如您所看到的,类总是可以访问它自己的成员。第二列指示是否类与类在同一个包中(无论它们亲子关系)有权访问该成员。第三列表示在此包外声明的类的子类是否具有第四列指出是否所有的类#36825;的成员

访问级别以两种方式影响您。首先,当您使用来自其他来源,例如Java平台中的类,访问级别决定你自己的类的哪些成员第二,当你写一个类的时候,你需要决定您类中的每个成员变量和每个方法的访问级别应该有。

很多时候,我意识到通过创建真实世界的类比可以记住任何语言的基本概念。这是我理解Java中访问修饰符的类比:

假设你是一所大学的学生,你有一个朋友周末来看你,假设在校园中央有一座大学创始人的大雕像。

  • 当你把他带到校园时,你和你的朋友看到的第一件事就是这座雕像。这意味着任何走进校园的人都可以在没有大学许可的情况下看到这座雕像。这使得这座雕像具有公共意义。

  • 接下来,你想带你的朋友去你的宿舍,但为此你需要将他登记为访客。这意味着他有通行证(和你的一样)进入校园的各种建筑。这将使他的门禁卡成为受保护的。

  • 您的朋友想要登录校园WiFi,但没有任何登录凭据。他上网的唯一方法是您与他共享您的登录名。(记住,每个去大学的学生也拥有这些登录凭据)。这将使您的登录凭据为NO MODIFIER

  • 最后,你的朋友想看看你在网站上发布的学期进度报告。然而,每个学生都有自己的个人登录来访问校园网站的这一部分。这将使这些凭据成为私人的。

希望这有帮助!

当您考虑访问修饰符时,请以这种方式考虑它(适用于变量方法):

public-->从任何地方访问
private-->只能在声明它的同一个类中访问

现在,当涉及到defaultprotected时,出现了混淆

default-->没有访问修饰符关键字存在。这意味着它严格在类的包中可用。无处可去在该包之外可以访问它。

protected-->比default稍微不那么严格,除了相同的包类之外,它可以被声明它的之外的子类访问。

这一切都是关于封装(或者正如Joe Phillips所说,最少的知识)。

从最严格的(私有)开始,看看以后是否需要限制较少的修饰符。

我们都使用方法和成员修饰符,如私有、公共……但很少有开发人员会做的一件事是使用包来逻辑地组织编码。

例如:您可以将敏感的安全方法放在“安全”包中。然后放置一个公共类,该类访问此包中的一些安全相关代码,但保留其他安全类包私有。因此,其他开发人员只能在此包外使用公开可用的类(除非他们更改修饰符)。这不是一个安全功能,但将指南使用。

Outside world -> Package (SecurityEntryClass ---> Package private classes)

另一件事是,相互依赖很多的类可能最终会在同一个包中,如果依赖关系太强,最终可能会被重构或合并。

相反,如果您将所有内容设置为公共,则不清楚应该或不应该访问什么,这可能会导致编写大量javadoc(它不会通过编译器强制执行任何内容…)。

  • 公共

    如果一个类成员声明为public,那么它可以从任何地方访问

  • 保护

    如果一个类成员被声明了关键字protected,那么它可以从相同的类成员,同一包中的外部类成员和继承的类成员访问。如果一个类成员受到保护,那么它不能从外部包类访问,除非外部包类被继承,即扩展其他包超类。但受保护的类成员总是可用于相同的包类,无论是否继承相同的包类都没关系

  • 默认

    在Java默认不是访问修饰符关键字。如果一个类成员被声明没有任何访问修饰符关键字,那么在这种情况下,它被认为是默认成员。默认类成员始终可用于相同的包类成员。但是外部包类成员不能访问默认类成员,即使外部类是子类,也不像受保护的成员。

  • 私密

    如果一个类成员声明了关键字protected,那么在这种情况下,它只对相同的类成员可用

我的两分钱:)

私人:

类->顶级类不能是私有的。内部类可以是私有的,可以从同一个类访问。

实例变量->只能在类中访问。不能在类外访问。

包私有:

类->顶级类可以是包私有的。它只能从同一个包访问。不能从子包访问,也不能从外部包访问。

实例变量->可从同一个包访问。不是从子包,不是从外部包。

保护:

类->不能保护顶级类。

实例变量->仅可在同一包或子包中访问。扩展类时只能在包外访问。

公众:

类->从包/子包/另一个包访问

实例变量->从包/子包/另一个包访问

这里有详细的答案

https://github.com/junto06/java-4-beginners/blob/master/basics/access-modifier.md

Java访问权限

在此处输入图片描述

访问修饰符可以适用于classfield关于我们method。尝试访问、子类化或覆盖它。

  • 访问fieldmethod是通过class
  • 继承和开闭原理[关于]
    • 后继者class(子类)访问修饰符可以是任何
    • 后继者method(覆盖)访问修饰符应该是相同或扩展它

顶级类(第一级作用域)可以是publicdefaultNested class关于我们可以有它们中的任何一个

package不应用包层次结构

[Swift访问修饰符]

Java中的访问说明符:java中有4个访问说明符,即私有、包私有(默认)、受保护和公共,以增加访问顺序。

私人:当您正在开发某个类并且您希望该类的成员不暴露在该类之外时,您应该将其声明为私有。私有成员只能在定义它们的类中访问,即封闭类。私有成员可以在'this'引用上访问,也可以在包含这些成员的类的其他实例上访问,但只能在这个类的定义内。

包私有(默认):除了下面描述的访问之外,此访问说明符还将提供私有访问说明符指定的访问。

当你开发一个包,因此在其中开发一个类(比如Class1)时,你可以使用默认(无需明确提及)访问说明符,将类中的成员暴露给你(同一)包中的其他类。在这些其他类(同一包中)中,你可以在Class1的实例上访问这些默认成员。你也可以在Class1的子类中访问这些默认成员,比如Class2(在这个引用上或Class1的实例上或Class2的实例上)。

基本上,在同一个包中,您可以直接访问类实例的默认成员,也可以访问子类中的'this'引用。

保护:除了下面描述的访问之外,此访问说明符还将提供包私有访问说明符指定的访问。

当你在开发某个包以及其中的某个类(比如Class1)时,如果你不希望这个成员在你的包之外被访问(比如在你的包的消费者包中,即使用你的API的客户端),那么你应该为Class1中的数据成员使用protected访问说明符,但是你想做一个例外,只有当客户端写入扩展Class1的类(比如Class2)时才允许访问这个成员。因此,一般来说,受保护的成员将在派生类中的'this'引用上可访问,即Class2以及Class2的显式实例。

请注意:

  1. 您将无法访问继承的受保护的Class1成员Class2,如果您尝试在Class1的显式实例上访问它,虽然它在其中是继承的。
  2. 当您在相同/不同的包中编写另一个类Class3时扩展Class2,来自Class1的受保护成员将可访问在这个引用和Class3的显式实例上。这将适用于任何被扩展的层次结构,即受保护的成员将仍然可以在此引用或扩展实例上访问类。请注意,在Class3中,如果您创建Class2的实例,则您将无法从Class1访问受保护的成员它是继承的。

所以底线是,受保护的成员可以在其他包中访问,只有当这个其他包中的某个类,包含这个受保护成员的扩展类和受保护成员在扩展类的定义内的“this”引用或扩展类的显式实例上被访问时。

公共:除了下面描述的访问之外,此访问说明符还将提供受保护的访问说明符指定的访问。

当你开发一些包,因此一些类(比如Class1)在它里面,那么你应该使用公共访问说明为数据成员在Class1如果你希望这个成员可以在其他包的实例上访问Class1创建在其他包的某个类。

公共,私有,默认和受保护的访问修饰符之间的差异

此图像将使您轻松了解公共、私有、受保护和默认访问修饰符之间的基本区别。当您在代码中未声明ant访问修饰符时,默认修饰符会自动发生。

当您不希望您的变量/方法/类在该类之外可见时,请使用私有。当您希望只有此类的子级可以使用该变量时,请使用protected。当您希望变量/类/方法可以从任何地方访问时,请使用public。当您希望您的变量/类/方法仅在该包中使用时,请使用包私有。

当谈到访问修饰符时,我们可以很容易理解,非常简单的规则包括它们。

私有访问修饰符在:只有一个类

默认访问修饰符在:-只有相同的类/相同的包子类

保护访问修饰符在:-相同类/相同包子类/相同包非-子类/不同包子类

中使用的公共访问修饰符:-我们可以在任何地方使用(相同的类/相同的包子类/相同的包非-子类/不同的包子类/不同的包非-子类)