【问题标题】:Difference between the default access specifier and protected access specifier in java [duplicate]java中默认访问说明符和受保护访问说明符之间的区别[重复]
【发布时间】:2012-04-09 17:04:45
【问题描述】:

我正在尝试学习 java,但当我查看访问说明符时,我有一个疑问。如果没有指定默认值和java中受保护的访问说明符有什么区别?

【问题讨论】:

标签: java access-specifier


【解决方案1】:

这个 Java tutorial 可能对你有用。

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

【讨论】:

    【解决方案2】:

    protected 说明符允许相关类的所有子类(无论它们驻留在哪个包中)以及同一包中的其他代码访问。默认说明符允许同一包中的其他代码访问,但不允许位于不同包中的子类中的代码访问。见Java Language Specification Section 6.6

    编辑:根据 Michael Schmeißer 的要求(因此其他人不必通读 cmets 或点击链接即可找到此内容):接口的所有成员都是隐式公开的。实际上,为public 以外的接口成员指定任何访问说明符是编译时错误(尽管没有访问说明符默认为公共访问)。以下是 JLS 中针对类成员的完整规则集(有关包、顶级类和接口以及数组的规则,请参见上面的链接):

    只有当类型是可访问的并且成员或构造函数声明为允许访问:

    • 如果成员或构造函数声明为公共,则允许访问。

    • 接口的所有成员都是隐式公开的。

    • 否则,如果成员或构造函数被声明为受保护,则仅当满足以下条件之一时才允许访问:

    • 对成员或构造函数的访问发生在包含声明受保护成员或构造函数的类的包内。

    • 访问正确,如§6.6.2 中所述。 (此条款指的是允许派生类访问超类的受保护成员的规则;第 6.6.2 节开始:“对象的受保护成员或构造函数只能从声明它的包外部访问负责实现该对象的代码。” 然后详细说明。)

    • 否则,如果成员或构造函数声明为私有,则当且仅当它出现在包含成员或构造函数声明的顶级类 (§7.6) 的主体内时,才允许访问。

    • 否则,我们说有默认访问,只有当访问发生在声明类型的包内时才被允许。

    【讨论】:

    • 一个澄清:默认访问说明符允许访问所有子类,无论它们位于哪个包中。与受保护的访问修饰符相比,默认修饰符扩大了对同一包中所有类的访问。
    • @david.dionis - 这是不正确的。不能从不同包中声明的子类访问具有默认访问权限的字段、方法或其他成员。
    • 哇,这是真的。我只是尝试了一下并学到了一些新东西。谢谢你+1!
    • @Ted Hopp 您的回答是正确的,所以我投了赞成票,但是,我想请您添加一个事实,即默认可见性实际上在接口中是公开的。 (在 JLS 部分中也提到:“接口的所有成员都是隐式公共的。”)
    • @MichaelSchmeißer - 完成
    【解决方案3】:

    受保护的访问说明符 - 有两种方法可以访问受保护的数据

    1. 如果一个类的受保护数据成员、受保护方法位于同一个包中

    2. ,其他类将可以看到它们
    3. 使用继承

      意味着我们可以通过继承该类来使用该类的受保护数据。

    默认访问说明符 - 只有一种访问默认数据的方式

    默认将访问限制在包级别,即使扩展了具有默认数据成员的类,我们也无法访问。

    示例

    要检查它在 ProvideProtected 中 int x 的默认删除受保护关键字,将产生编译时错误。

            1. SuperClass
    
            package nee.superclass;
    
            public class ProvideProtected {
                protected int x=800;
    
            }
    
            2.Subclass
    
    
            package nee.subclass;
    
            import nee.superclass.*;
    
            public class AccessProtected extends ProvideProtected 
    
            {   
            public void accessProtected()
                {
                    System.out.println(x);
                }
    
                public static void main(String[] args) {
                    AccessProtected obj=new AccessProtected();
                    obj.accessProtected();
    
                }
    
            }
    

    【讨论】:

      【解决方案4】:

      受保护的访问修饰符:- 任何标记为受保护的东西在同一个包中可见,在子类中也可见。

      默认访问:- 默认不是关键字。它适用于未指定访问修饰符的情况。它基本上是一个包级别修饰符。任何具有这种访问权限的东西都可以在同一个包中看到。

      现在可以借助示例更好地解释差异

      包 p1

      public class A
      {
      
      protected void fn()
      {
      
      }
      
      } 
      

      包 p1

      public class B
      {
      
      A a1 = new A();
      
      a1.fn();// fn() is visible inside the same package
      
      }
      
      }
      

      现在我们来到不同包中的子类

      包 p2

      public class D extends A
      
      {
      
      void test()
      
      {
      
      A a1 = new new A();
      
          //a1.fn() -->  would give compilation error
      fn();
      
      super.fn();
      
      }
      
      }
      

      fn(), super.fn() 不会报错。

      所以,区别在于子类中的方法不能通过超类的引用来调用。要么你可以直接调用它,要么使用super。

      注意super.fn() 必须是非静态方法的一部分。

      【讨论】:

        【解决方案5】:

        长话短说:

        default 成员可用于同一包的所有其他类

        protected 成员在同一包的所有其他类任何其他包的任何其他类中都可用,只要该类扩展了包含受保护成员的类即可。

        【讨论】:

          【解决方案6】:
          • 受保护 - 相同的包+扩展此类的其他包。
          • 默认 - 仅同一个包。

          例子:

          package p1;
          protected class Parent{
          }
          
          import p1.*;
          class Child extends Parent{}
          

          【讨论】:

            猜你喜欢
            • 2013-12-25
            • 2018-06-22
            • 2011-06-15
            • 2016-01-15
            • 2014-11-03
            • 2011-01-31
            • 2011-03-30
            • 2011-01-15
            • 2014-09-09
            相关资源
            最近更新 更多