java中默认访问说明符和受保护访问说明符之间的差异
我试图学习java,当我通过访问说明符时,我有一个疑问。如果没有指定默认的访问说明符,那么它与java中受保护的访问说明符有什么区别?受保护的java中默认访问说明符和受保护访问说明符之间的差异,java,access-specifier,Java,Access Specifier,我试图学习java,当我通过访问说明符时,我有一个疑问。如果没有指定默认的访问说明符,那么它与java中受保护的访问说明符有什么区别?受保护的说明符允许所讨论类的所有子类(无论它们驻留在哪个包中)以及同一包中的其他代码进行访问。默认说明符允许同一包中的其他代码访问,但不允许位于不同包中的子类中的代码访问。看 编辑:根据Michael Schmeißer的请求(这样其他人就不必通读评论或通过链接找到):接口的所有成员都是隐式公开的。事实上,为接口成员指定除public之外的任何访问说明符都是编译时
说明符允许所讨论类的所有子类(无论它们驻留在哪个包中)以及同一包中的其他代码进行访问。默认说明符允许同一包中的其他代码访问,但不允许位于不同包中的子类中的代码访问。看
编辑:根据Michael Schmeißer的请求(这样其他人就不必通读评论或通过链接找到):接口的所有成员都是隐式公开的。事实上,为接口成员指定除public
之外的任何访问说明符都是编译时错误(尽管没有任何访问说明符默认为public access)。以下是JLS针对类成员的完整规则集(有关包、顶级类和接口以及阵列的规则,请参见上面的链接):
引用(类、接口或数组)类型的成员(类、接口、字段或方法)或类类型的构造函数只有在类型可访问且该成员或构造函数声明允许访问时才可访问:
- 如果成员或构造函数声明为公共,则允许访问
- 接口的所有成员都是隐式公共的
- 否则,如果声明该成员或构造函数受保护,则仅当以下情况之一为真时才允许访问:
- 从包含声明受保护成员或构造函数的类的包中访问该成员或构造函数
- 如中所述,访问是正确的。(本条款涉及允许派生类访问超类的受保护成员的规则;§6.6.2开始:“对象的受保护成员或构造函数可以从包外部访问,在包中只能由负责实现该对象的代码声明。”然后详细说明。)
- 否则,如果该成员或构造函数被声明为私有的,则当且仅当访问发生在包含该成员或构造函数声明的顶级类()的主体内时,才允许访问
- 否则,我们说存在默认访问,只有在从声明类型的包中进行访问时才允许默认访问
这个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
受保护的访问说明符-有两种方法可以访问受保护的数据
如果一个类的受保护数据成员和受保护方法驻留在同一个包中,则它们对其他类是可见的
使用继承
意味着我们可以通过继承该类来使用该类的受保护数据
默认访问说明符-只有一种访问默认数据的方法
默认将访问权限限制在包级别,即使在扩展具有默认数据成员的类之后,我们也无法访问
例子
要检查providedProtected中int x的默认删除受保护关键字,将生成编译时错误
受保护的访问修饰符:-标记为受保护的任何内容在同一个包中可见,在子类中也可见
默认访问:-默认值不是关键字。当未指定访问修饰符时,它将应用。它基本上是一个包级修改器。具有这种访问权限的任何内容都可以在同一个包中看到
现在,通过一个例子可以更好地解释这种差异
套餐p1
public class A
{
protected void fn()
{
}
}
public class B
{
A a1 = new A();
a1.fn();// fn() is visible inside the same package
}
}
套餐p1
public class A
{
protected void fn()
{
}
}
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()
必须是非静态方法的一部分。长话短说:
默认
成员在同一软件包的所有其他类中可用
受保护的
成员可在同一包的所有其他类中使用和任何其他包的任何其他类中使用,只要该类扩展了包含受保护成员的类。
- 受保护-相同的包+扩展此类的其他包
- 默认-仅相同的包
例如:
package p1;
protected class Parent{
}
import p1.*;
class Child extends Parent{}
一个澄清:默认访问说明符允许访问所有子类,无论它们在哪个包中。与受保护的访问修饰符相比,默认修饰符拓宽了对同一包中所有类的访问。@david.dionis-这是不正确的。具有默认访问权限的字段、方法或其他成员无法从其他包中声明的子类访问。哇,这是真的。我只是尝试了一下,学到了一些新东西。谢谢你和+1@Ted Hopp您的答案是正确的,所以我投了赞成票,但是,我想请您添加一个事实,即默认可见性实际上在接口中是公共的。(在JLS部分中也提到:“接口的所有成员都是隐式公开的。”@MichaelSchmeißer-Done中清楚地显示了这种差异。