java中的默认访问说明符和受保护的访问说明符之间的区别

我试图学习java,当我通过访问说明符时,我有一个疑问,如果没有指定默认值和受保护的访问说明符,有什么区别?

protected说明符允许所讨论的类的所有子类访问它们所包含的任何包,以及同一包中的其他代码。 默认说明符允许同一包中的其他代码进行访问,但不允许通过驻留在不同包中的子类中的代码进行访问。 请参阅Java语言规范第6.6节 。

编辑:MichaelSchmeißer的请求(因此其他人不必阅读评论或按照链接查找):所有接口成员都是隐式公开的。 事实上,为public接口成员指定任何访问说明符是一个编译时错误(尽管没有访问说明符默认为公共访问)。 以下是来自JLS的类成员规则的完整规则(请参阅上面的包,规则,顶级类和接口以及数组的链接):

只有在类型可访问且声明成员或构造函数允许访问时,才能访问引用(类,接口或数组)类型的成员(类,接口,字段或方法)或类类型的构造函数:

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

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

  • 否则,如果成员或构造函数被声明为protected,则只有在满足以下条件之一时才允许访问:

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

  • 访问是正确的,如§6.6.2中所述 。 (此子句引用允许派生类访问超类的受保护成员的规则;§6.6.2开始: “对象的受保护成员或构造函数可以从包外部访问,只能通过代码来声明它。负责该对象的实现。“然后详细阐述了这一点。”

  • 否则,如果成员或构造函数被声明为private,则当且仅当它发生在包含成员或构造函数声明的顶级类(第7.6节 )的主体内时才允许访问。

  • 否则,我们说存在默认访问权限,只有在声明类型的包中发生访问时才允许访问。

这个Java 教程可能对你有用。

 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 

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

  1. 受保护的数据成员,类的受保护方法,如果它们位于同一个包中 ,则对其他类可见

  2. 使用inheritance

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

默认访问说明符 – 只有一种方法可以访问默认数据

默认情况下,仅限访问包级别,即使在扩展具有默认数据成员的类之后,我们也无法访问。

要检查它是否默认删除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(); } } 

受保护的访问修饰符: – 标记为受保护的任何内容在同一个包中可见,并且在子类中也可见。

默认访问权限: – 默认不是关键字。 它在未指定访问修饰符时适用。 它基本上是一个包级修饰符。 在同一个包中可以看到任何具有此类访问权限的内容。

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

包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()必须是非静态方法的一部分。