Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/309.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Java中,public、protected、package private和private之间有什么区别?_Java_Private_Public_Protected_Access Modifiers - Fatal编程技术网

在Java中,public、protected、package private和private之间有什么区别?

在Java中,public、protected、package private和private之间有什么区别?,java,private,public,protected,access-modifiers,Java,Private,Public,Protected,Access Modifiers,在Java中,在创建类和接口以及处理继承时,是否有关于何时使用每个访问修饰符(即默认包private、public、protected和private)的明确规则?可能对您有所帮助 班 包裹 子类相同包装 亚类差异包装 世界 平民的 + + + + + 受保护的 + + + + 无修饰语 + + + 私有的 + 简单规则。首先声明所有内容都是私有的。然后,随着需求的出现和设计的需要,向公众发展 在公开成员时,请自问是公开表示选择还是抽象选择。第一个问题是您希望避免的,因为它会引入太多对实际表示的

在Java中,在创建类和接口以及处理继承时,是否有关于何时使用每个访问修饰符(即默认包private、public、protected和private)的明确规则?

可能对您有所帮助

班 包裹 子类相同包装 亚类差异包装 世界 平民的 + + + + + 受保护的 + + + + 无修饰语 + + + 私有的 +
简单规则。首先声明所有内容都是私有的。然后,随着需求的出现和设计的需要,向公众发展

在公开成员时,请自问是公开表示选择还是抽象选择。第一个问题是您希望避免的,因为它会引入太多对实际表示的依赖,而不是对其可观察的行为的依赖

作为一般规则,我试图通过子类化来避免重写方法实现;把逻辑搞砸太容易了。如果要重写抽象受保护的方法,请声明该方法


另外,在重写时使用@Override注释,以防止重构时出现问题。

差异可以在已经提供的链接中找到,但使用哪一个链接通常归结为知识最少的原则。只允许所需的最少可见性。

警告:我不是Java程序员,我是Perl程序员。Perl没有正式的保护措施,这也许就是我如此理解这个问题的原因:

私有的 正如您所想,只有声明它的类才能看到它

包专用 它只能被声明它的包看到和使用。这是Java中的默认值,有些人认为这是一个错误

受保护的 包Private+可由子类或包成员查看

平民的 每个人都能看到

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

C++定义了一个称为friend的附加级别,您知道的越少越好

什么时候用什么?整个想法是封装以隐藏信息。您希望尽可能地对用户隐藏某些操作的细节。为什么?因为这样以后你就可以更改它们,而不会破坏任何人的代码。这使您可以优化、重构、重新设计和修复bug,而不用担心有人在使用您刚刚大修的代码

因此,经验法则是使事物只在必须的时候才可见。从private开始,只在需要时添加更多可见性。只公开用户必须知道的内容,你公开的每一个细节都会限制你重新设计系统的能力

如果您希望用户能够自定义行为,而不是公开内部构件,以便覆盖它们,那么最好将这些胆量塞进对象中,并公开该接口。这样他们就可以简单地插入一个新对象。例如,如果您正在编写一个CD播放机,并且希望有关此CD位的go-find信息可自定义,而不是将这些方法公开,那么您应该将所有这些功能放在它自己的对象中,并且只将您的对象getter/setter公开。通过这种方式,吝啬暴露自己的胆量会鼓励良好的组合和关注点的分离

就我个人而言,我坚持私人和公共的。许多面向对象语言都有这样的功能。保护可能很方便,但这真的是个骗局。一旦一个接口不仅仅是私有的,它就超出了你的控制范围,你必须去寻找其他人的代码来找到它的用途

这就是出版的理念。改变一个接口重构它需要你找到所有使用它的代码,并改变它。如果接口是私有的,那么没有问题。如果它受到保护,你必须找到你所有的子类。如果它是公共的,你必须找到所有使用你的代码的代码。有时这是可能的,例如,如果您正在编写仅供内部使用的公司代码,那么接口是否是公共的并不重要。您可以从公司存储库中获取所有代码。但是如果一个接口被发布,如果有代码在你的控制之外使用它,那么你就被套住了。您必须支持该接口,否则可能会破坏代码。即使是受保护的接口也可以被认为是已发布的,这就是为什么我不用担心受保护的接口


许多语言发现公共/受保护/私有的层级性质过于局限,不符合现实。为此,有了a的概念,但那是另一个节目。

大卫的回答提供了每个访问修饰符的含义。至于何时使用它们,我建议公开所有用于外部使用的类和每个类的方法,包括它们的API,其他的都是私有的

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

。。。。 受保护:受保护的访问修饰符有点复杂,可以说是默认访问修饰符的超集。就同一包中的访问权限而言,受保护成员与默认成员相同。区别在于,受保护的成员也可以被声明成员的类的子类访问,这些子类位于父类所在的包之外

但这些受保护的成员“只能通过继承在包外访问”“。也就是说,您可以直接访问其他包中存在的子类中某个类的受保护成员,就像该成员存在于子类本身一样。但是,通过使用父类的引用,该受保护成员将无法在包外的子类中访问。
..

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

也会调用缺少关键字指定的默认访问权限。例外:在接口中,没有修饰符表示公共访问;禁止使用public以外的修饰符。枚举常量始终是公共的

总结 是否允许使用此访问说明符访问成员

成员是私有的:仅当成员定义在与调用代码相同的类中时。 成员是包私有的:仅当调用代码位于成员的直接封闭包内时。 成员受保护:相同的包,或者如果成员是在包含调用代码的类的超类中定义的。 议员:是的。 什么访问说明符适用于 局部变量和形式参数不能接受访问说明符。因为根据作用域规则,它们本质上是外部无法访问的,所以它们实际上是私有的

对于顶级作用域中的类,只允许使用public和package private。这种设计选择可能是因为protected和private在包级别是冗余的,没有包的继承

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

相关的:

顺序 访问说明符可以严格排序

公共>受保护>包专用>专用

这意味着public提供了最多的访问权限,private提供的访问权限最少。对private成员的任何引用对包private成员也有效;对包private成员的任何引用对受保护成员都有效,依此类推。将受保护成员的访问权限授予同一包中的其他类被认为是错误的

笔记 更准确地说,C类的方法可以访问C类的任何子类的对象上的C类私有成员。Java不支持按实例限制访问,只支持按类限制访问。与Scala相比,Scala确实支持使用private[this]。 您需要访问构造函数才能构造对象。因此,如果所有构造函数都是私有的,则只能通过类内的代码(通常是静态工厂方法或静态变量初始值设定项)来构造该类。对于包私有或受保护的构造函数也是如此。 只有私有构造函数也意味着类不能在外部子类化,因为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();
    }
}
编译器输出:

Test.java:4: secretMethod() in Example.NestedClass is defined in an inaccessible class or interface
        Example.leakPrivateClass().secretMethod(); // error
                                  ^
1 error
一些相关问题:

简而言之

公共:可从任何地方访问。 受保护:可由同一包的类和驻留在任何包中的子类访问。 默认未指定修饰符:可由同一包的类访问。 私有:只能在同一类中访问。 根据经验:

私有:类范围。 默认或包专用:包作用域。 受保护:包范围+类似子包,但我们可以从不同的包中将其子类化。受保护修饰符始终保持父子关系。 公众:到处都是。 因此,如果我们将访问权分为三种权利:

从同一类内的方法直接调用,或通过此语法直接调用。 引用使用对类的引用或通过点语法调用方法。 在里面 通过亚类化遗传。 然后我们有一个简单的表格:

+—-———————————————+————————————+———————————+
|                 |    Same    | Different |
|                 |   Package  | Packages  |
+—————————————————+————————————+———————————+
| private         |   D        |           |
+—————————————————+————————————+———————————+
| package-private |            |           |
| (no modifier)   |   D R I    |           |
+—————————————————+————————————+———————————+
| protected       |   D R I    |       I   |
+—————————————————+————————————+———————————+
| public          |   D R I    |    R  I   |
+—————————————————+————————————+———————————+

Java中最容易被误解的访问修饰符是受保护的。我们知道它类似于默认修饰符,只有一个例外,子类可以看到它。但是怎么做呢?下面是一个例子,希望能澄清这一困惑:

假设我们有两个类;父亲和儿子,每个人都有自己的包裹:

package fatherpackage;

public class Father
{

}

-------------------------------------------

package sonpackage;

public class Son extends Father
{

}
让我们向父添加一个受保护的方法foo

方法foo可以在4种上下文中调用:

在一个类中,该类位于定义了foo的同一个包中父包:

在子类内部,通过this或super在当前实例上:

在类型为同一类的引用上:

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();
    }
}
在类型为父类的引用上,该引用位于定义了foo的包内fatherpackage[可包含在上下文1中]:

package fatherpackage;

public class Son extends Father
{
    public void sonMethod(Father f)
    {
        f.foo();
    }
}
以下情况无效

在类型为父类且位于定义了foo的包外部的引用上:

子类包中的非子类子类从其父类继承受保护的成员,并使其成为非子类的私有成员:

package sonpackage;

public class SomeClass
{
    public void someMethod(Son s) throws Exception
    {
        s.foo(); // compilation error
    }
}
私有的 方法、变量和构造函数 声明为私有的方法、变量和构造函数只能在声明的类本身内访问

类和接口 私有访问修饰符是限制最严格的访问级别。类和接口不能是私有的

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

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

方法、字段可以声明为受保护,但接口中的方法和字段不能声明为受保护

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

class Van{

    protected boolean speed(){

    }
}

class Car{
    boolean speed(){
    }

}
平民的 声明为公共的类、方法、构造函数、接口等可以从任何其他类访问

因此,公共类中声明的字段、方法和块可以从属于Java世界的任何类访问

不同的包装 但是,如果我们试图访问的公共类位于不同的包中,那么仍然需要导入公共类

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

默认-无关键字: 默认访问修饰符意味着我们不显式声明类、字段、方法等的访问修饰符

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

无法重写静态字段。如果尝试重写,则不会显示任何错误 但是,除了我们所做的以外,它不起作用

相关答案 参考链接

私人:仅限进入课堂

默认无修改器:对类和包的访问受限

受保护:对包内外的类、包和子类的访问受到限制


Public:可访问类、包all和子类。。。简而言之,无处不在。

受公共保护的默认和私有是访问修饰符

它们用于封装、隐藏和显示类的内容

类可以是public或default 类成员可以是public、protected、default或private。 在类外无法访问Private 默认值只能在包中访问。 在包以及扩展包的任何类中受保护。 公众对所有人开放


通常,成员变量定义为私有,但成员方法是公共的。

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

Public:它基本上很简单,因为您可以从任何类访问它,无论它是否在同一个包中

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

默认值:可以从包的任何类在同一包中访问它

要访问,可以创建类的对象。但是您不能在包之外访问此变量

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

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

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

在非静态方法中,您可以访问
直接由于构造函数中也存在此引用,但要在静态方法中访问,您需要创建类的对象。

对包可见。默认值。不需要修改器

仅对类可见私有

对世界公众可见

对包和所有受保护的子类可见

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

String name = "john";

public int age(){
    return age;
}
专用访问修饰符-专用:

声明为私有的方法、变量和构造函数只能在声明的类本身内访问。私有访问修饰符是限制最严格的访问级别。类和接口不能是私有的

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

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

示例:

Public class Details{

    private String name;

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

    public String getName(){
        return this.name;
    }
}
公共访问修饰符-公共:

声明为公共的类、方法、构造函数、接口等可以从任何其他类访问。因此,公共类中声明的字段、方法和块可以从属于Java世界的任何类访问

但是,如果我们试图访问的公共类位于不同的包中,那么仍然需要导入公共类

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

例如:

public void cal(){

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

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

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

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

class Van{

    protected boolean speed(){

    }
}

class Car{
    boolean speed(){
    }

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

默认-可从软件包访问

受保护-可从其他包中的包和子类访问。 也

私有-仅可从其类访问


下面是该表的一个更好的版本,它还包括一个模块列。

解释 私有成员i只能在声明的同一类中访问

没有访问修饰符j的成员只能在同一包中的类中访问

受保护的成员k可以在同一包中的所有类中以及在其他包中的子类中访问

公共成员l对所有类都是可访问的,除非它位于不导出其声明的包的中

要选择哪个修改器? Access modifiers是一种帮助您防止意外破坏封装的工具*。问问自己,您是否希望成员是类、包、类层次结构的内部成员,或者根本不是内部成员,并相应地选择访问级别

示例:

Public class Details{

    private String name;

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

    public String getName(){
        return this.name;
    }
}
字段长的internalCounter可能应该是私有的,因为它是可变的,并且是实现细节。 一个只应该在同一个包的工厂类中实例化的类应该有一个包限制的构造函数,因为它不可能直接从包外部调用它。 应该保护在呈现之前调用并用作子类中的钩子的内部void beforeRender方法。 从GUI代码调用的void saveGameFile dst方法应该是公共的。 *访问Java中的修饰符

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

一,。默认值:

仅对同一包中的类可访问

比如说,

// 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
  }
}
// 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();
  }
}
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
  }
}
// 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();
  }
}
这种访问比公共和受保护的访问受到更多的限制,但比私人访问受到更少的限制

二,。公开的

可以从任何地方访问。全球接入

比如说,

// 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
  }
}
// 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();
  }
}
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
  }
}
// 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();
  }
}
输出:您好

三,。私人的

只能在同一类中访问

如果您试图访问另一个类中某个类的私有成员,将抛出编译错误。比如说,

// 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
  }
}
// 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();
  }
}
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
  }
}
// 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();
  }
}
四,。保护

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

比如说,

// 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
  }
}
// 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();
  }
}
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
  }
}
// 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();
  }
}
输出:您好

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

这与Java有关

发件人:

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     ║
╚═════════════╩═══════╩═════════╩══════════╩═══════╝
第一个数据列指示类本身是否可以访问 由访问级别定义的成员。正如你所看到的,一个类总是 有权访问自己的成员。第二列指示是否 类位于与类相同的包中,而不考虑其 亲子关系可以访问该成员。第三列显示 在此包外部声明的类的子类是否具有 访问该成员。第四列指示是否所有类 有权访问该成员

访问级别在两个方面影响您。首先,当您使用类时 来自其他来源,例如Java平台中的类, 访问级别决定您自己的类的哪些成员 类可以使用。第二,当你写一个类时,你需要做出决定 类中的每个成员变量和每个方法的访问级别是什么 应该有


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

假设你是一所大学的学生,你有一个朋友周末要来看你。假设校园里有一个大学创始人的大雕像。

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

接下来,你想带你的朋友去你的宿舍,但为此你需要把他登记为访客。这意味着他可以获得一张通行证,这张通行证和你的通行证一样,可以进入校园内的各种建筑。这将使他的门禁卡受到保护

您的朋友想登录校园WiFi,但没有任何凭据。他能上网的唯一方法就是你和他分享你的登录信息。记住,每个上大学的学生都拥有这些登录凭证。这将使您的登录凭据成为无修改器

最后,你的朋友想看看你在网站上发布的这学期的进度报告。但是,每个学生都有自己的个人登录名来访问校园网站的这一部分。这将使这些凭据成为私有的


希望这有帮助

当您考虑访问修饰符时,请这样想,它适用于变量和方法:

公共->可从任何地方访问 private->只能在声明它的同一类中访问

现在,当涉及到默认和受保护时,就会出现混淆

默认->不存在访问修饰符关键字。这意味着它严格地在类的包中可用。在该软件包之外的任何地方都无法访问它

protected->略低于默认值,并且除了相同的包类之外,它可以被声明包之外的子类访问

这都是关于封装的,或者像乔·菲利普斯所说的,最少的知识

从最严格的private开始,看看以后是否需要限制较少的修饰符

我们都使用方法和成员修饰符,如private、public等。。。但有一件事很少有开发人员会做,那就是使用包逻辑地组织代码

例如: 您可以将敏感的安全方法放入“安全”包中。 然后放置一个公共类,该类访问此包中的一些安全相关代码,但将其他安全类保留为私有包。 因此,除非更改修改器,否则其他开发人员只能从这个包之外使用公开可用的类。 这不是安全功能,但将指导使用

另一件事是,相互依赖性很大的类最终可能会在同一个包中,如果依赖性太强,最终可能会被重构或合并

相反,如果您将所有内容都设置为public,则不清楚应该或不应该访问哪些内容,这可能会导致编写大量javadoc,而这些javadoc不会通过编译器强制执行任何内容

公开的

如果类成员是用public声明的,那么可以从任何地方访问它

保护

如果使用关键字protected声明类成员,则可以从相同的类成员、同一包内的外部类成员和继承的类成员访问该类成员。如果类成员受保护,则不能从包类外部访问它,除非外部包类被继承,即扩展其他包超类。但受保护的类成员始终可用于相同的包类—无论是否继承相同的包类

违约

在Java中,默认值不是访问修饰符关键字。如果声明的类成员没有任何访问修饰符关键字,那么在这种情况下,它将被视为默认成员。默认类成员始终可用于相同的包类成员。但即使外部类是不同于受保护成员的子类,外部包类成员也不能访问默认类成员

私人的

如果类成员是用关键字protected声明的,那么在这种情况下,它仅对相同的类成员可用

下面的框图解释了当派生类访问模式为私有时基类的数据成员是如何继承的

注意:使用私有访问说明符声明数据成员称为数据隐藏

来源:

我的两分钱:

私人:

类->顶级类不能是私有的。内部类可以是私有的,可以从同一个类访问

实例变量->只能在类中访问。无法在类之外访问

包专用:

类->顶级类可以是包私有的。它只能从同一个包访问。不来自子包,不来自外部包

实例变量->可从同一个包访问。不来自子包,不来自外部包

受保护:

类->顶级类不能被保护

实例变量->只能在同一包或子包中访问。扩展类时只能在包外部访问

公众:

类->可从包/子包/其他包访问

实例变量->可从包/子包/其他包访问

下面是详细的答案

Java访问修改

访问修饰符可以用于类、字段和方法。尝试访问、子类化或重写此

通过类访问字段或方法。 继承与开闭原则。 后续类子类访问修饰符可以是任何。 后续methodoverride访问修饰符应相同或展开 顶级类第一级作用域可以是公共的,也可以是默认的。嵌套类可以有任意一个

包未应用于包层次结构

Java中的访问说明符: java中有4个访问说明符,即private、package private default、protected和public,访问顺序递增

私人: 当您正在开发某个类,并且希望该类的成员不会暴露在该类之外时,您应该将其声明为private。只能在定义了私有成员的类(即封闭类)中访问私有成员。私有成员可以在“this”引用上访问,也可以在包含这些成员的类的其他实例上访问,但只能在此类的定义内访问

包私有默认值: 此访问说明符将提供由专用访问说明符指定的访问,以及下面描述的访问

当您正在开发某个包,从而开发其中的某个类(比如Class1)时,您可能会使用默认的无需明确提及的访问说明符,将类中的成员公开给同一包中的其他类。在同一个包中的这些其他类中,您可以访问Class1实例上的这些默认成员。您还可以访问Class1的子类中的这些默认成员,比如说在这个引用上的Class2,或者在Class1的实例上,或者在Class2的实例上

基本上,在同一个包中,您可以直接访问类实例上的默认成员,也可以访问子类中的“this”引用上的默认成员

受保护: 此访问说明符将提供由包专用访问说明符指定的访问,以及下面描述的访问

当您开发某个包以及其中的某个类(比如Class1)时,如果您不希望在包外部(比如包的消费者包中)访问该成员,那么您应该为Class1中的数据成员使用受保护的访问说明符,即通常使用API的客户机,但您想做一个例外,仅当客户端编写扩展Class1的类(比如Class2)时,才允许访问该成员。因此,一般来说,受保护的成员可以在派生类(即Class2)中的“this”引用上访问,也可以在Class2的显式实例上访问

请注意:

您将无法访问继承的Class1受保护成员 在里面 Class2,如果您试图在Class1的显式实例上访问它, 虽然它是遗传的。 当您在相同/不同的包中编写另一个类Class3时 这扩展了Class2,可以访问Class1中受保护的成员 在这个引用上,也在类3的显式实例上。这将 对于任何扩展的层次结构(即受保护的成员),都应为true 仍然可以在此引用或扩展的实例上访问 班注意,在类3中,如果创建类2的实例,则 但是,您将无法从Class1访问受保护的成员 它是遗传的。 所以,底线是,只有在扩展类定义内的“this”引用或扩展类的显式实例上访问来自此其他包、包含此受保护成员和受保护成员的扩展类的某些类时,才可以在其他包中访问受保护成员

公共:除了下面描述的访问之外,此访问说明符还将提供受保护的访问说明符指定的访问

当您开发某个包,因此某个类(比如其中的Class1)时,如果您希望在其他包的某个类中创建的Class1实例上的其他包中可以访问该成员,则应该为Class1中的数据成员使用公共访问说明符。基本上,当您打算无条件地向世界公开您的数据成员时,应该使用这个访问说明符


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

朋友->您对它了解的越少越好-->它提供了选择性可见性,这仍然优于包隐私。在C++中,它有它的用途,因为不是所有的函数都可以是成员函数,朋友比公开的要好。当然,有一个危险的错误使用邪恶的头脑。还应该注意到,保护在C++中有不同的含义-受保护的方法是有效的私人,但仍然可以从继承类调用。与java相反,在C++中,它可以由同一个包中的任何类调用。我觉得很奇怪,Java不允许声明子类可访问的成员,但不允许声明整个包可访问的成员。对我来说,这有点颠倒了——一个包比一个儿童类的范围更广@KonradMorawski IMHO包的作用域小于子类。如果您还没有声明类final,那么用户应该能够对它进行子类化——因此java protected是您发布的接口的一部分。OTOH,包是由单个组织隐式开发的:例如com.mycompany.mypackage。如果您的代码在我的包中声明了自己,那么您就隐式地声明自己是我的组织的一部分,因此我们应该进行通信。因此,与扩展我的对象的子类人员相比,包发布给我公司中较小/更容易接触的受众,因此可视性较低。friend用于定义类之间的特殊关系。在许多情况下,如果使用正确,它可以实现出色的封装。例如,特权工厂类可以使用它将内部依赖项注入到构造的类型中。它有一个坏名声,因为不关心如何正确维护设计良好的对象模型的人可能会滥用它来减轻他们的工作负载。只要在孩子访问父类的受保护成员时添加它,它变成私有的,或者更确切地说是一个特殊的私有成员,它可以被subclass的subclass成员的子类继承。private对包中的其他类隐藏。public暴露于包外的类。protected是public的一个版本,仅限于子类。@Tennenrishin-No;与C++相反,在java保护下,该方法也可以从整个包中访问。Java Visibly模型中的这种愚蠢行为打破了受保护的目标。@Nicolas无论是否受保护,都可以从整个包中访问它。作为一个访问修饰符,protected所做的就是暴露给包外的子类。@Tennerrishin-嗯,这就是Nicolas所说的。。。你现在只是在重复。你最初说的是受保护的——我引用一下——“是一个仅限于子类的public版本”,你自己承认这不是真的,因为受保护也允许通过整个包进行访问。因此,它不限制对子类的访问。我也同意Nicolas的观点,Java中受保护的访问模式是愚蠢的。结果是Java将水平晶格和垂直访问限制限定符混为一谈。默认范围是水平/晶格限制,晶格是包。公共是另一个水平限制,晶格是整个世界。私有和C++保护是垂直的。如果我们有一条横切的通道,比如说,p

为我们实际需要的罕见案例提供保护包,被保护的Objectclone相当于受保护成员的一个例子。做超级C++和第一个无效情况f.fo?@ cST1992之间的区别是什么?它很混乱,但是参见java语言规范。仅由负责实现该对象的代码声明的包。对于super.foo,参考super直接负责实现,而参考f则不是。为什么?因为你可以100%确定super是父亲类型,但不是f类型;在运行时,它可能是其他子类型的父亲。看到了吗?读到一个理解保护的人的回答会让人耳目一新。不幸的是,本页上所有其他定义受保护的答案都有一点错误。@RuchirBaronia,world=应用程序中的所有代码,不管它在哪里。值得一提的是,protected modifier使该对象在其他包中可用,而default/no修饰符限制了对同一对象的访问package@vanguard69,受保护修饰符使标记的对象类、方法或字段仅当所述其他类是声明该受保护标记对象的类的子类时,才可供其他包中的其他类使用?这个子类在另一个包中吗?呵呵。我想我知道Java。默认值不是访问修饰符,另外两个是拼错的。副刊到底是什么,为什么不是对现有帖子的编辑?副刊是访问修饰符。为什么不编辑?出于历史原因,保持接受的答案不变,并给出我的答案。受保护的成员只能从同一包的子类访问,而不能从不同包的子类访问。应该有一个更正在上面的表格世界是在您的项目。我应该进一步解释。库在您的项目中,如果您要创建库,它们也会公开这些公共类和方法。所以,只在你的项目中说有点不对劲。使用它的一切都是更好的描述。例如,如果我有MyClass,并且我正在执行另一个类扩展MyClass,那么我将可以从另一个类中访问所有受保护和公共的方法和属性。如果我做MyClass MyClass=新建MyClass;在某个地方的另一个类中(比如构造函数),只有在公共方法位于不同的包中时,我才能访问它。注意,如果I do=new MyClass{@Override protected void protectedMethod{//some logic};看起来我可以访问受保护的方法,但这和扩展它是一样的,而是内联的。现实是有点复杂,尤其是当你考虑保护,这实际上是一个非常困难的访问修饰符,以充分理解-大多数人认为他们知道什么保护真的不。此外,正如波希米亚人指出的,它没有回答这个问题——它没有说明何时使用每个访问修饰符。在我看来,这个答案还不至于糟糕到可以投反对票,但很接近。但是超过4000张选票?这是怎么发生的?@niks受保护的成员可以由不同包中的子类访问。这不是重点吗?否则,默认和受保护之间有什么区别?禁止使用公共以外的修饰符-从Java 9开始,情况就不再是这样了:接口也可以有私有方法。只是说:有很多人在区分红色/绿色方面有问题。使用红色/绿色或黄色/橙色/的表格。。。着色方案在任何方面都很难做得更好-@幽灵猫,我不同意。我认为红色/绿色在直觉上与许多人的工作/不工作一致,也就是说,它比许多替代品更好。。。8%的色盲男性可分为约1%的双翅目、1%的原翅目、1%的原翅目和5%的双翅目。因为我是这5%中的50%之一,所以请放心:红色/绿色很糟糕。@GhostCat Ok。。这比我想象的要多。我上传了这个图像,并测试了所有不同的模式。即使在单色/消色差模式下,色差也是合理的。你能看到区别吗?还是模拟器关闭了?我仍然认为红色/绿色对于能看见颜色的人来说是非常直观的。我能看到区别,但我也能通过我们在德国进行的驾驶执照色盲测试的一半;-。。。java java,C++,班诺特,但是我所发布的,特别的图片,Java和C++都不一样,这些规则也不适用于java吗?感谢C++中只有3个修饰符,而Java.中有4个。类比是好的,但是缺省访问说明符丢失了,OP问这个问题是什么区别?
在Java中介于public、protected、package private和private之间?为了更清楚,没有修饰符==package private | package protected这是一个很好的演示