在Java中,在创建类和接口以及处理继承时,是否有明确的规则来确定何时使用每个访问修饰符,即默认的(包私有)、公共的、受保护的和私有的?


当前回答

这一切都是关于封装的(或者正如乔·菲利普斯所说的,最起码的知识)。

从限制性最大的(私有)开始,看看以后是否需要限制性较小的修饰符。

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

例如:您可以将敏感的安全方法放在“安全”包中。然后放一个公共类,它访问这个包中的一些安全相关代码,但保持其他安全类包的私有性。因此,其他开发人员只能在这个包之外使用公开可用的类(除非他们更改了修饰符)。这不是安全功能,但将指导使用。

Outside world -> Package (SecurityEntryClass ---> Package private classes)

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

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

其他回答

Public Protected Default和private是访问修饰符。

它们用于封装,或隐藏和显示类的内容。

类可以是公共的或默认的类成员可以是公共的、受保护的、默认的或私有的。

课堂外无法访问私人课程默认值只能在包中访问。在包以及扩展它的任何类中受到保护。公众对所有人开放。

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

公共-可从应用程序中的任何位置访问。默认-可从包访问。protected-可从其他包中的包和子类访问。也private-只能从其类访问。

当你想到访问修饰符时,你可以这样想(适用于变量和方法):

public-->可从任何位置访问private-->只能在声明它的同一类中访问

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

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

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

对于初学者来说,考虑这个例子可能会有所帮助;

考虑到我在foo包中开发了MyClass,它有一个很棒的方法,名为print,您有兴趣调用它(它可能是一个方法或属性)

package foo;  // I am in foo 
public class MyClass {
     private void print() { //This is private
        System.out.println("I can print!");
    }
}

您已经开发了YourClass的bar包,您有兴趣使用MyClass#print

package bar; \\You are not in same package as me 
import foo.MyClass;    
public class YourClass {
    void test() {
        MyClass myClass = new MyClass();
        myClass.print();
    }
}

您的代码未编译,并且出现错误。方法print()对于类型MyClass未定义

你来找我:

你:我想用你的方法,但它是私人的。你能公开吗?我:不,我不想让别人使用你:我是你的朋友,至少让我不要让别人使用它。我:好的,我将删除私有关键字。我的访问修饰符将是默认的或私有的包。因为你们是我的朋友,你们必须和我在同一个包裹里。所以你们必须来到我的包裹里。我的意思是确切的包,甚至不是子包。

然后MyClass将

package foo;    
public class MyClass {    
    void print() { //No access modifier means default or package-private 
        System.out.println("I can print!");
    }   
}

YourClass将是:

package foo;//You come to my package
public class YourClass {
    void test() {
        MyClass myClass = new MyClass();
        myClass.print();
    }
}

不考虑这个:你又来找我了

你:我的老板告诉我我不能改变我的包(在实际世界中,你不能改变你的包以使用其他类方法)我:还有另一种方法,如果你扩展我,我使print()受到保护,那么无论你是否更改包,你都可以使用它。(因此,子类将始终允许您访问我的方法)。

这是我的班级

package foo;
protected class MyClass { // it is now protected
     protected void print() {
        System.out.println("I can print!");
    }   
}

这是YourClass

package bar; // You are on your own package
import foo.MyClass;
public class YourClass extends MyClass {
    void  test() {
        //You initiate yourself! But as you extend me you can call my print()
        YourClass yourClass = new YourClass(); 
        yourClass.print();
    }
}

您可能已经注意到,通过使一个方法受到保护,所有其他类都可以通过扩展它来使用它,您无法轻松控制如何使用它。这在java17中通过引入密封和许可词来解决。因此,您可以定义哪些类可以扩展您。类似于公共密封类MyClass允许YourClass参见Java17中的密封类是什么?有关详细信息

此图将使您轻松了解public、private、protected和default访问修饰符之间的基本区别。当您没有在代码中声明ant访问修饰符时,默认修饰符会自动发生。