Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/380.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中,是否有关于何时使用每个访问修饰符的明确规则,即默认的(包私有)、公共的、受保护的和私有的,同时使类和接口处理继承问题?可能对您有所帮助 等级 包裹 子类(相同包装) 子类(不同包装) 世界 public + + + + + 受保护 + + + + 无修饰语 + + + private + 简单规则。首先声明所有内容都是私有的。然后,随着需求的出现和设计的需要,向公众发展 在公开成员时,请自问是公开表示选择还是抽象选择。第一个问题是您希望避免的,因为它会引入太多对实际表示的依赖,而

在Java中,是否有关于何时使用每个访问修饰符的明确规则,即默认的(包私有)、
公共的
受保护的
私有的
,同时使
接口
处理继承问题?

可能对您有所帮助


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

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

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


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

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

(注意:我不是Java程序员,我是Perl程序员。Perl没有正式的保护措施,这也许就是为什么我对这个问题如此了解的原因:)

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

包专用 它只能由声明它的包查看和使用。这是Java中的默认设置(有些人认为这是一个错误)

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

公开的 每个人都能看到

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

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

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

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

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

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

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


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

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

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

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

但这些受保护的成员“只能通过继承在包外访问”“。也就是说,您可以直接访问其他包中存在的子类中某个类的受保护成员,就像该成员存在于子类本身一样。但是,该受保护成员将无法通过使用父类在包外的子类中访问。”
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   |
+—————————————————+————————————+———————————+
____________________________________________________________________
                | highest precedence <---------> lowest precedence
*———————————————+———————————————+———————————+———————————————+———————
 \ xCanBeSeenBy | this          | any class | this subclass | any
  \__________   | class         | in same   | in another    | class
             \  | nonsubbed     | package   | package       |    
Modifier of x \ |               |           |               |       
————————————————*———————————————+———————————+———————————————+———————
public          |       ✔       |     ✔     |       ✔       |   ✔  
————————————————+———————————————+———————————+———————————————+———————
protected       |       ✔       |     ✔     |       ✔       |   ✘   
————————————————+———————————————+———————————+———————————————+———————
package-private |               |           |               |
(no modifier)   |       ✔       |     ✔     |       ✘       |   ✘   
————————————————+———————————————+———————————+———————————————+———————
private         |       ✔       |     ✘     |       ✘       |   ✘    
____________________________________________________________________
package fatherpackage;

public class Father
{

}

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

package sonpackage;

public class Son extends Father
{

}
package fatherpackage;

public class Father
{
    protected void foo(){}
}
package fatherpackage;

public class SomeClass
{
    public void someMethod(Father f, Son s)
    {
        f.foo();
        s.foo();
    }
}
package sonpackage;

public class Son extends Father
{
    public void sonMethod()
    {
        this.foo();
        super.foo();
    }
}
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();
    }
}
package fatherpackage;

public class Son extends Father
{
    public void sonMethod(Father f)
    {
        f.foo();
    }
}
package sonpackage;

public class Son extends Father
{
    public void sonMethod(Father f)
    {
        f.foo(); // compilation error
    }
}
package sonpackage;

public class SomeClass
{
    public void someMethod(Son s) throws Exception
    {
        s.foo(); // compilation error
    }
}
String name = "john";

public int age(){
    return age;
}
Public class Details{

    private String name;

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

    public String getName(){
        return this.name;
    }
}
public void cal(){

}
class Van{

    protected boolean speed(){

    }
}

class Car{
    boolean speed(){
    }

}
// 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();
  }
}
╔═════════════╦═══════╦═════════╦══════════╦═══════╗
║ 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     ║
╚═════════════╩═══════╩═════════╩══════════╩═══════╝
Outside world -> Package (SecurityEntryClass ---> Package private classes)