Java 中公共抽象类中方法的默认访问级别是什么?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17232312/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-01 01:24:12  来源:igfitidea点击:

What is the default access level for methods in a public abstract class in Java?

java

提问by ceving

Normally the default access level of methods is package local. But it seems to me that it is different for public abstract classes. In those classes the default seems to be public. Is this correct?

通常方法的默认访问级别是包本地。但在我看来,公共抽象类是不同的。在这些类中,默认值似乎是公开的。这个对吗?

Update

更新

@EJP

@EJP

It was a bug in my code. It is possible to shadow the package local method with a public method, which confuses me. This makes me think that a public abstract could be similar to an interface where the methods are public. See the example:

这是我代码中的一个错误。可以使用公共方法隐藏包本地方法,这让我感到困惑。这让我认为公共抽象可能类似于方法是公共的接口。看例子:

a/A.java:

一个/A.java:

package a;

public abstract class A
{
    String a () { return "a"; }
}

test_a.java:

test_a.java:

class test_a
{
    static class NewA extends a.A
    {
        public String a () { return "new a"; }
    }

    public static void main (String[] args)
    {
        NewA a = new NewA();
        System.out.println(a.a());
    }
}

回答by Arnaud Denoyelle

False, let's see with a quick example:

False,让我们看一个简单的例子:

package apackage;

public abstract class AbstractFoo {

  //A method with default visibility
  abstract void bar();

}

A quick implementation :

快速实施:

public class Foo extends AbstractFoo {

  @Override
  void bar() {}
}

Now, in another package :

现在,在另一个包中:

public static void main(String[] args) throws Exception{

  AbstractFoo something=new Foo();
  something.bar();//Compiler complains here

Compiler complains about visibility. So the default visibility for methods is package protected, even if the class is public abstract.

编译器抱怨可见性。因此,方法的默认可见性是包保护的,即使类是public abstract.

回答by Mark Rotteveel

The Java Language Specification for Java 7does not mention separate rules for abstract methods, as such an abstract method without a qualified access level is default aka package private, just like a normal method would have been.

Java 7Java 语言规范没有提到抽象方法的单独规则,因为这种没有限定访问级别的抽象方法是默认的,也就是包私有的,就像普通方法一样。

See also 6.6.1. Determining Accessibility:

另见6.6.1。确定可访问性

  • A member (class, interface, field, or method) of a reference (class, interface, or array) type or a constructor of a class type is accessible only if the type is accessible and the member or constructor is declared to permit access:

    • If the member or constructor is declared public, then access is permitted.
      All members of interfaces are implicitly public.
    • Otherwise, if the member or constructor is declared protected, then access is permitted only when one of the following is true:
      • Access to the member or constructor occurs from within the package containing the class in which the protected member or constructor is declared.
      • Access is correct as described in §6.6.2.
    • Otherwise, if the member or constructor is declared private, then access is permitted if and only if it occurs within the body of the top level class (§7.6) that encloses the declaration of the member or constructor.
    • Otherwise, we say there is default access, which is permitted only when the access occurs from within the package in which the type is declared.
  • 引用(类、接口或数组)类型的成员(类、接口、字段或方法)或类类型的构造函数仅在该类型可访问且成员或构造函数声明为允许访问时才可访问:

    • 如果成员或构造函数被声明为 public,则允许访问。
      接口的所有成员都是隐式公开的。
    • 否则,如果成员或构造函数被声明为受保护的,则只有在以下情况之一为真时才允许访问:
      • 对成员或构造函数的访问发生在包含声明受保护成员或构造函数的类的包中。
      • 访问正确,如 §6.6.2 所述。
    • 否则,如果成员或构造函数被声明为私有,则当且仅当它发生在包含成员或构造函数声明的顶级类(第 7.6 节)的主体内时,才允许访问。
    • 否则,我们说存在默认访问,仅当访问发生在声明类型的包内时才被允许。

(emphasis mine)

(强调我的)

Also note that the term 'default access' is equivalent to 'package private', the only 'exception' to this is method declarations in an interface, which simply are always publicand therefor don't need to be prefixed.

还要注意,术语“默认访问”等同于“包私有”,唯一的“例外”是接口中的方法声明,它们总是总是这样public,因此不需要前缀。

Edit:

编辑:

As adenoyelle indicates in his answer, you can override a 'default' abstract method in a different package (as required by the rules in JLS 8.4.3.1. abstractMethods), as such you could consider them to be protected, but a quick scan of the JLS doesn't seem to make this explicit.

正如adenoyelle 在他的回答中指出的那样,您可以覆盖不同包中的“默认”抽象方法(根据 JLS 8.4.3.1. abstractMethods 中的规则的要求),因此您可以将它们视为protected,但可以快速扫描JLS 似乎没有明确说明这一点。

Edit 2:

编辑2:

I just tested it. It is impossible to implement an abstract class that has a method with default access in a different package. It simply does not compile. This shows that the method has default (package private) access, not protected. It also indicates that 8.4.3.1 doesn't actually require that it is always possible to implement an abstract method, just that it excludes nonsensical options like private abstract void method()

我刚刚测试了它。不可能在不同的包中实现具有具有默认访问权限的方法的抽象类。它根本无法编译。这表明该方法具有默认(包私有)访问权限,不受保护。它还表明 8.4.3.1 实际上并不要求始终可以实现抽象方法,只是排除了诸如private abstract void method()

For example compiling:

例如编译:

package example;

public abstract class AbstractTest {
    abstract void testMethod();
}

and

package example.sub;

import example.AbstractTest;

public class TestImpl extends AbstractTest {
    void testMethod() {
        //implemented
    }
}

Leads to compile error:

导致编译错误:

example\sub\TestImpl.java:8: error: TestImpl is not abstract and does not override abstract method testMethod() in AbstractTest
public class TestImpl extends AbstractTest {
       ^
1 error

回答by shreyansh jogi

The default visibility is known as “package” (though you can't use this keyword), which means the field will be accessible from inside the same package to which the class belongs.

默认可见性称为“包”(尽管您不能使用此关键字),这意味着可以从类所属的同一个包内部访问该字段。

uf you declare as public than it will be public for all no matter its abstract or not

如果您声明为公开,那么无论其抽象与否,它将对所有人公开

回答by Suresh Atta

Default access modifier means we do not explicitly declare an access modifier for a class, field, method etc.

默认访问修饰符意味着我们没有为类、字段、方法等显式声明访问修饰符。

A variable or methoddeclared without any access control modifier is available to any other class in the same package.

没有任何访问控制修饰符声明的变量或方法可用于同一包中的任何其他类。

So there is no matter of the method is abstract or not .

所以不管方法是否抽象。

回答by Ananth

The access level of the methods would remain as default(would be only visible within the package) even if the abstract class is of public access level. Only if the child class overrides the method with a pulbic access modifier, it would be visible outside the package.

即使抽象类是公共访问级别,方法的访问级别将保持默认(仅在包内可见)。只有当子类使用公共访问修饰符覆盖该方法时,它才会在包外可见。

回答by Marko Topolnik

You are on to something, just a bit off: in interfacesthe default—and in fact the only choice— is public. In all classes the default is the same, which is package-private.

你正在做一些事情,只是有点偏离:在接口中,默认的——实际上也是唯一的选择——是公开的。在所有类中,默认值都是相同的,即包私有的。

回答by Chaz

Even if the subclass "tries" to override the method with "default" access defined in the abstract class in the subclass with "public" access, compiler still complains that chap6.AbstractImplis not abstract and does not override abstract method getHelp()in random.AbstractLearner.

即使子类“尝试”来覆盖在与“公共”访问子类的抽象类定义的“默认”访问的方法,编译器仍然抱怨说,chap6.AbstractImpl不是抽象的,不重写抽象方法getHelp()random.AbstractLearner

So, in effect the compiler error message is really misleading here because there is no way that this can be fixed unless the access specifier for the getHelp()method in the AbstractLearneris changed to public.

因此,实际上编译器错误消息在这里确实具有误导性,因为除非将 中getHelp()方法的访问说明符AbstractLearner更改为 public,否则无法修复此问题。

package random;

public abstract class AbstractLearner {

    abstract void getHelp();

}

package chap6;

import random.AbstractLearner;

public class AbstractImpl extends AbstractLearner {

    public void getHelp() {
        System.out.println("Hello");
    }
}