Java中的public,protected,package-private和private有什么区别?

int*_*ion 3004 java private protected public access-modifiers

在Java中,有没有关于何时使用每个访问修饰符,即默认明确的规则(包私有)public,protected并且private,同时使classinterface和处理继承?

Dav*_*nds 5417

官方教程可能对你有用.

______________________________________________________________
|           ? Class ? Package ? Subclass ? Subclass ? World  |
|           ?       ?         ?(same pkg)?(diff pkg)?        |
|????????????????????????????????????????????????????????????|
|public     ?   +   ?    +    ?    +     ?     +    ?   +    | 
|????????????????????????????????????????????????????????????|
|protected  ?   +   ?    +    ?    +     ?     +    ?        | 
|????????????????????????????????????????????????????????????|
|no modifier?   +   ?    +    ?    +     ?          ?        | 
|????????????????????????????????????????????????????????????|
|private    ?   +   ?         ?          ?          ?        |
|___________|_______|_________|__________|__________|________|
 + : accessible         blank : not accessible

  • 对于一个没有回答问题的答案来说,这是很多选票,*当*我们应该使用每个可见性时(不是效果是什么). (118认同)
  • @Bohemian - 答案假设您知道您应尽可能使用最不宽容的访问说明符(或假设您通过遵循也提供该建议的链接阅读完整答案). (28认同)
  • 在 Java 和 JDK 1.0.1 之前的版本中,您可以同时使用 private 和 protected 来创建另一种保护形式,将方法或变量的访问限制为仅允许给定类的子类。 (16认同)
  • 如果你试图在同一个类中访问受保护的方法或实例变量,但是在一个不是你的对象上,就像.equals(Klass var)一样,它会起作用吗? (11认同)
  • 如果子类与其父类位于同一个包中,则默认字段在子类中可见. (7认同)
  • _世界在您的项目中_。我应该进一步解释。库位于您的项目中,如果您正在创建库,它们也会公开这些公共类和方法。所以,仅仅在你的项目中说有点不对。“使用它的一切”是更好的描述。 (7认同)
  • @niks 受保护的成员可以由不同包中的子类访问。这不是重点吗?否则默认和受保护之间有什么区别? (7认同)
  • @Jack 是的,尼克斯的评论是错误的,尽管许多人表示反对。答案中的 Java 教程链接清楚地表明,也可以在不同包的子类中访问受保护的成员。看来他/她的意思是“包级”而不是“受保护”,或者指的是不同的编辑。 (5认同)
  • @DawoodsaysreinstateMonica 这是一个很好的答案,这正是大多数找到此页面的人正在寻找的答案。另外,该表来自官方 Oracle 教程。但是,您给我们一个链接,以便我们了解“受保护”的真正含义如何? (4认同)
  • 这张桌子不是超级教学法.有一个更好的[在此页面上更进一步](http://stackoverflow.com/a/33627846/276052). (3认同)
  • 哇iheanyi,我希望所有的答案可以"假设你知道"实际答案,这对每个人来说都会容易得多.3000+票的链接是愚蠢的.但是,让我们继续假装,好像这实际意味着什么,因为原因. (3认同)
  • 子类(同一包)字段具有误导性,最好删除该列。因为是否是子类并不重要。 (3认同)
  • @niks:我能够从不同包的子类访问受保护的成员 (3认同)
  • 受保护的成员只能从相同包的子类访问,而不能从不同的包中访问子类.上表中应该有一个更正 (2认同)
  • 我仍然无法区分“公共”和“受保护”。这个答案中的“世界”是什么。这是否意味着访问不同项目和包中的项目文件夹?但这并没有发生。在这方面需要帮助。 (2认同)
  • @Deepak,世界在您的项目中。如果您有一个公共类,则任何其他类都可以实例化该类。方法一样。如果它是公共的,任何使用该类的人都可以使用该方法。包是指您所在的“文件夹”。因此,`ca.my.package.controllers` 与`ca.my.package.models` 不同。公共项目可以在这些包之外访问,但其余的则不能。package-private 本质上在包中被认为是公共的。受保护意味着任何继承它,或在同一个包内。Private 删除所有外部访问,包括包。 (2认同)
  • 例如,如果我有`MyClass`并且我正在执行`AnotherClass扩展MyClass`,我将可以访问`AnotherClass`中的所有受保护和公共方法和属性.如果我在某个地方执行`MyClass myClass = new MyClass();`在`AnotherClass`中 - 让我们说构造函数 - 如果它位于不同的包中,我将只能访问公共方法.请注意,如果我执行`= new MyClass(){@Override protected void protectedMethod(){// some logic}};`看来我可以访问受保护的方法,但这类似于扩展它,但是内联而不是内联. (2认同)
  • 不幸的是,这个答案是一个粗略的过度简化.现实有点复杂,特别是当你考虑`protected`(这实际上是一个非常难以完全理解的访问修饰符 - 大多数认为他们知道`protected`意味着什么的人).此外,正如波希米亚人指出的那样,它没有回答这个问题 - 它说_nothing_关于何时使用每个访问修饰符.在我看来,这个答案并不足以让人失望,而是接近尾声.但超过4000票?这怎么发生的? (2认同)
  • protected 只能在同一个包中访问。在该包之外无法访问它。java中的protected说明符称为包级说明符。 (2认同)
  • @DawoodsaysreinstateMonica我认为这里的问题是标题和正文提出了两个不同的问题:“访问修饰符之间有什么区别”和“何时应该使用不同的访问修饰符”。这个答案回答了标题中的问题,但没有回答正文中的问题。 (2认同)
  • @MarcoSulla 不幸的是,本页前 8 个答案(当前)中有 7 个实际上是错误的。我只是对这 7 个投了反对票,因为我认为这是一件大事。看看 Eng.Fouad 的答案,它目前是本页的第 9 个答案。这是第一个真正好的。 (2认同)

Sch*_*ern 453

(警告:我不是Java程序员,我是Perl程序员.Perl没有正式的保护,这也许是我理解这个问题的原因:))

私人的

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

包私人

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

受保护

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

上市

每个人都可以看到它.

发布时间

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

C++定义了一个名为"friend"的附加级别,你知道的越少越好.

你什么时候应该用什么?整个想法是隐藏信息的封装.您希望尽可能隐藏用户完成某些操作的详细信息.为什么?因为那样你可以在以后更改它们而不会破坏任何人的代码.这使您可以优化,重构,重新设计和修复错误,而无需担心有人正在使用您刚刚彻底检查过的代码.

因此,经验法则是使事物只能像它们必须一样可见.从私有开始,只根据需要添加更多可见性.只有公开对用户来说绝对必要的内容,你公开的每一个细节都会让你重新设计系统.

如果您希望用户能够自定义行为,而不是将内部公开,以便他们可以覆盖它们,那么将这些内容推入对象并使该接口公开通常是一个更好的主意.这样他们就可以简单地插入一个新对象.例如,如果您正在编写CD播放器并希望"查找有关此CD的信息"位可自定义,而不是将这些方法公开,您可以将所有功能放入其自己的对象中,并使公共getter/setter成为公共对象.通过这种方式吝啬暴露你的胆量可以促进良好的成分和关注点的分离

就个人而言,我只坚持"私人"和"公开".许多OO语言就是这样."受保护"可以派上用场,但这真的是一种骗局.一旦界面不仅仅是私人的,它就在你的控制之外,你必须去寻找其他人的代码才能找到用途.

这就是"已发布"的概念所在.更改界面(重构它)需要您找到使用它的所有代码并进行更改.如果界面是私有的,那么没问题.如果它受到保护,你必须找到你所有的子类.如果它是公开的,你必须找到使用你的代码的所有代码.有时这是可能的,例如,如果您正在处理仅供内部使用的公司代码,那么如果接口是公共的则无关紧要.您可以从公司存储库中获取所有代码.但是如果一个界面被"发布",如果有代码在你的控制范围之外使用它,那么你就被软管了.您必须支持该接口或冒险破坏代码.即使是受保护的界面也可以被认为是已发布的(这就是我不喜欢

许多语言发现公共/受保护/私有的等级性质太过限制而不符合现实.为此,有一个特质类的概念,但这是另一个节目.

  • 还应该注意,C++中的"protected"具有不同的含义 - 受保护的方法实际上是私有的,但仍然可以从继承类中调用.(与Java相反,它可以被同一个包中的任何类调用.) (29认同)
  • 朋友 - >"你知道的越少越好"--->它提供了选择性的可见性,这仍然优于包隐私.在C++中,它有其用途,因为并非所有函数都可以是成员函数,而且朋友比公共更好.当然,有邪恶思想滥用的危险. (24认同)
  • @KonradMorawski IMHO包的范围小于子类.如果您尚未将类声明为final,则用户应该能够将其子类化 - 因此java protected是已发布接口的一部分.OTOH,软件包由一个组织隐式开发:例如com.mycompany.mypackage.如果您的代码在我的包中声明了自己,那么您隐含地声明自己是我的组织的一部分,所以我们应该进行沟通.因此,包发布给更小/更容易接触的受众(我公司的人)而不是子类(扩展我的对象的人),因此被视为较低的可见性. (15认同)
  • @RhysvanderWaerden C#在这方面与C++相同.我发现很奇怪Java不允许声明子类可访问的成员而不是整个包.这对我来说有点颠倒 - 包装的范围比儿童类更宽! (9认同)
  • “朋友”非常适合定义类之间的特殊关系。在正确使用的情况下,它可以在许多情况下提供出色的封装效果。例如,特权工厂类可以使用它将内部依赖项注入到构造的类型中。它的名称很不好,因为不关心正确维护设计良好的对象模型的人可能会滥用它来减轻工作量。 (2认同)

aio*_*obe 392

这是表格的更好版本.(模块专栏的未来证明.)

Java Access Modifiers

说明

  • 一个私有成员(i)是唯一的,因为它宣布同一个类中访问.

  • 没有访问修饰符(j)的成员只能在同一个包中的类中访问.

  • 一个受保护的成员(k)是在同一个包中的所有类中访问其他包中的子类中.

  • 一个公共成员(l)是所有类都可以访问(除非它驻留在一个模块不出口,现声明在包).


选择哪种修饰符?

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

例子:

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

(*)什么是封装?

  • 只是说:很多人在区分红色/绿色方面有问题。使用红色/绿色(或黄色/橙色/ ...)着色方案的表在任何情况下都很少“更好” ;-) (8认同)
  • http://www.colourblindawareness.org/colour-blindness/types-of-colour-blindness/ ... * 8%的色盲男性大致可分为1%氘代鸦片,1%百变蛋白,1%百变蛋白和** 5%氘异常**。*而且我是那5%的那50%之一,请放心:红色/绿色很烂。 (6认同)
  • @GhostCat,我不同意。我认为红色/绿色对许多人来说直观地与“有效”/“无效”一致,即它_is_比许多替代品更好。 (5认同)
  • @GhostCat好..那是我所期望的人口比例更大的部分。我在此[色盲模拟器](https://www.color-blindness.com/coblis-color-blindness-simulator/)中上传了图片,并测试了所有不同的模式。即使在单色/无色症模式下,色差也是合理的。您能看到区别还是模拟器关闭了?(我仍然认为红色/绿色对于有色人种非常直观。) (5认同)
  • 我可以看到其中的区别,但是我也可以通过一半的色盲测试,而这是我们在德国必须取得的驾驶执照;-) ...但是我认为这样的模拟器“足够好”。 (2认同)
  • 我对颜色感到困惑 (2认同)

Abd*_*ull 190

                | 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         |       ?       |     ?    |       ?       |   ?    
____________________________________________________________________
Run Code Online (Sandbox Code Playgroud)

  • 值得一提的是-“受保护的修饰符使对象可以跨其他包使用,而默认/无修饰符限制对同一包的访问” (2认同)
  • @vanguard69,`protected` 修饰符使标记的*事物*(类、方法或字段)可用于其他包中的其他类**仅当**表示其他类是该类的子类,其中`protected `- 已声明标记为 *thing*。 (2认同)

Joh*_*son 155

容易统治.首先声明一切都是私密的.然后随着需求的出现向公众发展,设计需要保证.

当暴露成员时,问问自己是否暴露了表示选择或抽象选择.第一个是你想要避免的东西,因为它会在实际表示中引入太多依赖,而不是它的可观察行为.

作为一般规则,我尝试通过子类化来避免覆盖方法实现; 搞砸逻辑太容易了.如果要覆盖它,则声明抽象受保护的方法.

此外,重写对让事情当你打破重构时使用@Override注释.

  • @RuchirBaronia,"world"=应用程序中的所有代码,无论它在哪里. (3认同)

Mec*_*ail 108

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

"默认"访问(由缺少关键字指定)也称为package-private.例外:在界面中,没有修饰符意味着公共访问; 禁止公开以外的修饰语.枚举常量总是公开的.

摘要

是否允许访问具有此访问说明符的成员?

  • 成员是private:仅当成员与调用代码在同一类中定义时.
  • 成员是包私有:仅当调用代码在成员的立即封装包内时.
  • 成员是protected:相同的包,或者如果成员是在包含调用代码的类的超类中定义的.
  • 成员是public:是的.

什么访问说明符适用于

局部变量和形式参数不能使用访问说明符.由于根据范围规则它们本身就无法进入外部,因此它们实际上是私密的.

对于顶级作用域中的类,仅public允许使用package-private.这种设计选择大概是因为protected并且private在包级别上是多余的(没有包的继承).

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

相关:Java类可访问性

订购

访问说明符可以严格排序

public> protected> package-private> private

意味着public提供最多的访问,private至少.私有成员可能的任何引用也对包私有成员有效; 对包私有成员的任何引用在受保护的成员上都是有效的,依此类推.(允许访问受保护的成员到同一个包中的其他类被认为是一个错误.)

笔记

  • 类的方法允许访问同一类的其他对象的私有成员.更准确地说,C类的方法只能通过类来访问的C私有成员C.爪哇任子类的对象不支持通过实例限制访问.(与Scala相比,它确实支持它private[this].)
  • 您需要访问构造函数才能构造对象.因此,如果所有构造函数都是私有的,则该类只能由生活在类中的代码构造(通常是静态工厂方法或静态变量初始化器).类似地,对于包私有或受保护的构造函数.
    • 只有私有构造函数也意味着该类不能在外部进行子类化,因为Java要求子类的构造函数隐式或显式地调用超类构造函数.(但是,它可以包含一个嵌套类,它将其子类化.)

内课

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

但是,这非常复杂,有关详细信息,请参阅Java语言规范.(是的,过去有过编译器错误.)

要了解这些如何相互作用,请考虑此示例.有可能"泄漏"私人内部阶级; 这通常是一个警告:

class Test {
    public static void main(final String ... args) {
        System.out.println(Example.leakPrivateClass()); // OK
        Example.leakPrivateClass().secretMethod(); // error
    }
}

class Example {
    private static class NestedClass {
        public void secretMethod() {
            System.out.println("Hello");
        }
    }
    public static NestedClass leakPrivateClass() {
        return new NestedClass();
    }
}
Run Code Online (Sandbox Code Playgroud)

编译器输出:

Test.java:4: secretMethod() in Example.NestedClass is defined in an inaccessible class or interface
        Example.leakPrivateClass().secretMethod(); // error
                                  ^
1 error
Run Code Online (Sandbox Code Playgroud)

一些相关问题:

  • *“禁止使用 public 以外的修饰符”* — 从 Java 9 开始,情况不再如此:接口也可以具有私有方法。 (2认同)

nxh*_*oaf 87

根据经验:

  • private:类范围.
  • default(或package-private):包范围.
  • protected:包范围+子(如包,但我们可以从不同的包中继承它).protected修饰符始终保持"父子关系".
  • 公众:无处不在.

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

  • (D)irect(从同一个类中的方法调用).
  • (R)eference(使用对类的引用或通过"dot"语法调用方法).
  • (I)nheritance(通过子类化).

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

+—-———————————————+————————————+———————————+
|                 |    Same    | Different |
|                 |   Package  | Packages  |
+—————————————————+————————————+———————————+
| private         |   D        |           |
+—————————————————+————————————+———————————+
| package-private |            |           |
| (no modifier)   |   D R I    |           |
+—————————————————+————————————+———————————+
| protected       |   D R I    |       I   |
+—————————————————+————————————+———————————+
| public          |   D R I    |    R  I   |
+—————————————————+————————————+———————————+
Run Code Online (Sandbox Code Playgroud)


Rav*_*avi 50

很短的

  • public:无处不在.
  • protected:可以通过相同包的类和驻留在任何包中的子类访问.
  • default(未指定修饰符):可由同一包的类访问.
  • private:只能在同一个类中访问.


Eng*_*uad 43

Java中最容易被误解的访问修饰符是protected.我们知道它与默认修饰符类似,但有一个例外,即子类可以看到它.但是怎么样?这是一个有希望澄清混淆的例子:

  • 假设我们有2个班级; Father并且Son,每个都在自己的包装中:

    package fatherpackage;
    
    public class Father
    {
    
    }
    
    -------------------------------------------
    
    package sonpackage;
    
    public class Son extends Father
    {
    
    }
    
    Run Code Online (Sandbox Code Playgroud)
  • 让我们添加一个受保护的方法foo()Father.

    package fatherpackage;
    
    public class Father
    {
        protected void foo(){}
    }
    
    Run Code Online (Sandbox Code Playgroud)
  • 该方法foo()可以在4个上下文中调用:

    1. 在一个类中,它位于foo()定义的相同包中(fatherpackage):

      package fatherpackage;
      
      public class SomeClass
      {
          public void someMethod(Father f, Son s)
          {
              f.foo();
              s.foo();
          }
      }
      
      Run Code Online (Sandbox Code Playgroud)
    2. 在子类内部,在当前实例上通过thissuper:

      package sonpackage;
      
      public class Son extends Father
      {
          public void sonMethod()
          {
              this.foo();
              super.foo();
          }
      }
      
      Run Code Online (Sandbox Code Playgroud)
    3. 在类型相同的引用上:

      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();
          }
      }
      
      Run Code Online (Sandbox Code Playgroud)
    4. 在类型为父类的引用上,它foo()定义(fatherpackage)[这可以包含在上下文中.1]:

      package fatherpackage;
      
      public class Son extends Father
      {
          public void sonMethod(Father f)
          {
              f.foo();
          }
      }
      
      Run Code Online (Sandbox Code Playgroud)
  • 以下情况无效.

    1. 在类型为父类的引用上,它在包定义()的包之外:foo()fatherpackage

      package sonpackage;
      
      public class Son extends Father
      {
          public void sonMethod(Father f)
          {
              f.foo(); // compilation error
          }
      }
      
      Run Code Online (Sandbox Code Playgroud)
    2. 子类包内的非子类(子类从其父类继承受保护的成员,并使它们对非子类是私有的):

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

  • @cst1992 这很令人困惑,但请参阅 Java 语言规范 6.6.2:“可以从包外部访问对象的受保护成员或构造函数,在该包中只能由负责实现该对象的代码声明它”。对于 super.foo(),引用“super”是“直接负责实现”,但引用“f”不是。为什么?因为你可以100%确定“super”是Father类型,但“f”则不然;在运行时它可能是父亲的其他子类型。请参阅https://docs.oracle.com/javase/specs/jls/se9/html/jls-6.html#jls-6.6.2.1 (5认同)

Nam*_*mbi 28

私人的

  • 方法,变量和构造函数

声明为private的方法,变量和构造函数只能在声明的类本身中访问.

  • 类和接口

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

注意

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


受保护

  • 类和接口

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

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

注意

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


上市

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

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

  • 不同的包

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

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


默认-No关键字:

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

  • 在同一个包中

声明没有任何访问控制修饰符的变量或方法可用于同一包中的任何其他类.接口中的字段隐式为public static final,接口中的方法默认为public.

注意

我们不能覆盖静态字段.如果你试图覆盖它,它不显示任何错误,但它不起作用我们除外.

相关答案

参考链接

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


Joe*_*ips 18

的差异可以在链接中找到已经提供,但使用哪一个通常归结为"至少意味着知识的原则".仅允许所需的最低可见性.


sam*_*hah 18

私人:仅限课程访问

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

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

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


Pra*_*ant 15

访问修饰符用于限制多个级别的访问.

Public:它基本上就像你可以从任何类访问一样简单,无论是否在同一个包中.

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

默认值:可以从任何类包中访问相同的包.

要访问,您可以创建该类的对象.但是您无法在包外部访问此变量.

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

要访问基类中定义的受保护字段,可以创建子类的对象.

私有: 它可以在同一个类中访问.

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


Vir*_*ual 14

Java中的访问修饰符.

Java访问修饰符用于在Java中提供访问控制.

1.默认:

只能访问同一个包中的类.

例如,

// Saved in file A.java
package pack;

class A{
  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(); // Compile Time Error
   obj.msg(); // Compile Time Error
  }
}
Run Code Online (Sandbox Code Playgroud)

此访问比公共访问受到更多限制并受到保护,但受限于私有.

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();
  }
}
Run Code Online (Sandbox Code Playgroud)

输出:你好

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 Error
    obj.msg(); // Compile Time Error
  }
}
Run Code Online (Sandbox Code Playgroud)

4.受保护

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

例如,

// Saved in file A.java
package pack;
public class A{
  protected void msg(){System.out.println("Hello");}
}

// Saved in file B.java
package mypack;
import pack.*;

class B extends A{
  public static void main(String args[]){
    B obj = new B();
    obj.msg();
  }
}
Run Code Online (Sandbox Code Playgroud)

输出:你好

在此输入图像描述


ami*_*ura 12

包装可见.默认.不需要修饰符.

仅对班级可见(私人).

对世界可见(公众).

对包和所有子类(受保护)可见.

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

String name = "john";

public int age(){
    return age;
}
Run Code Online (Sandbox Code Playgroud)

私人访问修饰符 - 私人:

声明为private的方法,变量和构造函数只能在声明的类本身中访问.私有访问修饰符是限制性最强的访问级别.类和接口不能是私有的.

如果类中存在公共getter方法,则可以在类外部访问声明为private的变量.

使用private修饰符是对象封装自身并隐藏来自外部世界的数据的主要方式.

例子:

Public class Details{

    private String name;

    public void setName(String n){
        this.name = n;
    }

    public String getName(){
        return this.name;
    }
}
Run Code Online (Sandbox Code Playgroud)

公共访问修饰符 - 公共:

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

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

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

例:

public void cal(){

}
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

class Van{

    protected boolean speed(){

    }
}

class Car{
    boolean speed(){
    }

}
Run Code Online (Sandbox Code Playgroud)


Sha*_*ngh 12

  • 公共 - 可从应用程序的任何位置访问.

  • 默认 - 可从包中访问.

  • protected - 可从其他包中的包和子类访问.同样

  • 私人 - 仅限同类课程.


Boa*_*ann 12

我只是想解决一个极其普遍错误的细节,包括本页面上的大部分答案."默认"访问(当不存在访问修饰符时)并不总是与package-private相同.这取决于事物是什么.

  • 非成员类型(即,未在另一种类型中声明的类,枚举,接口和注释类型)默认为package-private.(JLS§6.6.1)

  • 默认情况下,类成员和构造函数是包私有的.(JLS§6.6.1)

  • 枚举构造函数默认私有的.(实际上,枚举结构必须是私有的,尝试将它们公开或保护是错误的).枚举常量是公共的,不允许任何访问说明符.枚举的其他成员默认为package-private.(JLS§8.9)

  • 默认情况下,接口和注释类型的所有成员都是公共的.(实际上,接口和注释类型的成员必须是公共的,并且尝试将它们设为私有或受保护是错误的.)(JLS§9.3至9.5)

  • 然后,只是为了混淆新手,在Java 8中将界面方法添加了很棒的新修饰符`default` :) (4认同)

dam*_*eng 11

此页面很好地描述了受保护和默认访问修饰符

....受保护:受保护的访问修饰符有点棘手,你可以说是默认访问修饰符的超集.受保护的成员与默认成员相同,只要涉及相同包中的访问.不同之处在于,受保护成员也可以被声明成员的类的子类访问,这些成员位于父类所在的包之外.

但是这些受保护的成员"只能通过继承才能在程序包外部访问".即,您可以直接访问其他包中存在的子类中受保护的成员,就好像该成员存在于子类本身中一样.但是,通过使用父类的引用,无法在包外部的子类中访问该受保护的成员.....


Dov*_*man 9

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

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


yoA*_*ex5 9

Java访问修改

在此处输入图片说明

访问修饰符可适用于class, field[About] , method. 尝试访问、子类化或覆盖它。

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

顶级类(一级作用域)可以是publicand defaultNested class[关于]可以有任何一个

package 未申请包层次结构

[Swift 访问修饰符]


ישו*_*ותך 6

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

这与Java Access Modifiers有关.

Java Access修饰符:

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

  • 项目清单
  • 私人的
  • 默认(包)
  • 保护
  • 上市

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

访问级别修饰符确定其他类是否可以使用特定字段或调用特定方法.访问控制有两个级别:

  • 在顶层 - public或package-private(没有显式修饰符).
  • 在成员级别 - public,private,protected或package-private(无显式修饰符).

可以使用修饰符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     ?
????????????????????????????????????????????????????
Run Code Online (Sandbox Code Playgroud)

第一个数据列指示类本身是否可以访问由访问级别定义的成员.如您所见,类始终可以访问自己的成员.第二列指示与该类相同的包中的类(无论其父级是否有)可以访问该成员.第三列指示在此包外声明的类的子类是否可以访问该成员.第四列指示是否所有类都可以访问该成员.

访问级别以两种方式影响您.首先,当您使用来自其他源的类(例如Java平台中的类)时,访问级别将确定您自己的类可以使用的这些类的哪些成员.其次,当您编写一个类时,您需要确定每个成员变量和类中的每个方法应具有的访问级别.


小智 5

Public Protected Default和private是访问修饰符.

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

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

在类外部无法访问私有默认值只能在包中访问.受保护的包以及任何扩展它的类.公众对所有人开放.

通常,成员变量是私有的,但成员方法是公共的.


小智 5

我经常意识到,通过创造现实世界的类比,记住任何语言的基本概念都是可能的.以下是我在Java中理解访问修饰符的类比:

我们假设您是一所大学的学生,并且您有一位朋友将在周末来访您.假设校园中间有一座大学创始人的大型雕像.

  • 当你把他带到校园时,你和你朋友看到的第一件事就是这座雕像.这意味着任何走进校园的人都可以在未经大学许可的情况下观看雕像.这使雕像成为PUBLIC.

  • 接下来,你想把你的朋友带到你的宿舍,但为此你需要将他注册为访客.这意味着他可以获得进入通行证(与您的通行证相同)进入校园内的各种建筑物.这将使他的访问卡成为PROTECTED.

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

  • 最后,您的朋友想要阅读您在网站上发布的学期的进度报告.但是,每个学生都有自己的个人登录信息,可以访问校园网站的这一部分.这将使这些凭据成为PRIVATE.

希望这可以帮助!


Mus*_*bir 5

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

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

  • 为了更清楚起见,“无修饰符”==“包私有” | `包受保护` (2认同)

归档时间:

查看次数:

2012589 次

最近记录:

6 年 前