29

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

4

6 回答 6

47

本 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
于 2012-05-02T09:32:16.560 回答
38

说明protected符允许相关类的所有子类访问,无论它们驻留在哪个包中,以及同一包中的其他代码。默认说明符允许同一包中的其他代码访问,但不允许位于不同包中的子类中的代码访问。请参阅Java 语言规范第 6.6 节

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

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

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

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

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

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

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

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

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

于 2012-03-26T07:09:55.287 回答
4

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

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

  2. 使用继承

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

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

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

例子

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

        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();

            }

        }
于 2015-04-24T07:36:57.470 回答
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()必须是非静态方法的一部分。

于 2017-04-06T13:54:24.153 回答
4

长话短说:

default成员在同一包的所有其他类中都可用;

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

于 2019-12-14T10:58:27.520 回答
1
  • protected - 扩展此类的相同包+其他包。
  • 默认 - 仅相同的包。

例子:

package p1;
protected class Parent{
}

import p1.*;
class Child extends Parent{}
于 2020-10-30T08:08:29.327 回答