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

Typically, the default access level for methods is local. But it seems to me that these are different for public abstract classes. In these classes, the default value seems public. Is it correct?

Update

@EJP

This was a mistake in my code. You can obscure the local package method using a public method that bothers me. This makes me think that a public essay might look like an interface where methods are publicly available. See an example:

and /A.java:

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

test_a.java:

 class test_a { static class NewA extends aA { public String a () { return "new a"; } } public static void main (String[] args) { NewA a = new NewA(); System.out.println(aa()); } } 
+8
source share
7 answers

False , let's see with a quick example:

 package apackage; public abstract class AbstractFoo { //A method with default visibility abstract void bar(); } 

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 

The compiler complains about visibility. Thus, the default visibility for methods is protected by the package , even if the class is public abstract .

+11
source

The Java Language specification for Java 7 does not contain separate rules for abstract methods, since such an abstract method without a qualified access level default aka package private, like a regular method.

See also 6.6.1. Availability Definition :

  • An element (class, interface, field or method) of a reference type (class, interface or array) or a constructor of a class type is available only if the type is available and a member or constructor is declared for access:

    • If a member or constructor is declared public, access is allowed.
      All interface members are implicitly public.
    • Otherwise, if a member or constructor is declared protected, access is allowed only when one of the following conditions is true:
      • Access to a member or constructor comes from a package containing a class in which a protected member or constructor is declared.
      • Access is correct as described in §6.6.2.
    • Otherwise, if a member or constructor is declared private, access is permitted only when it occurs inside the body of a top-level class (§7.6), which includes the declaration of a member or constructor.
    • Otherwise, we say that there is default access, which is only allowed when access occurs from within the package in which the type is declared.

(my emphasis)

Also note that the term "default access" is equivalent to a "closed package", the only "exception" for it are declarations of methods in the interface that are simply always public , and therefore it is not necessary to have a prefix.

Edit:

Since adenoyelle points to his answer , you can override the default abstract method in another package (according to the rules of JLS 8.4.3.1. abstract Methods ), so you can consider them protected , but a quick JLS scan does not seem to do this explicitly.

Edit 2:

I just tested it. It is not possible to implement an abstract class that has a method with default access in another package. It just doesn't compile. This shows that the method has default access (closed package), and is not protected. This also indicates that 8.4.3.1 does not actually require that you can always implement an abstract method, simply by eliminating meaningless options such as private abstract void method()

For example, compilation:

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

and

package example.sub;

 import example.AbstractTest; public class TestImpl extends AbstractTest { void testMethod() { //implemented } } 

Causes a compilation 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 
+2
source

The default visibility is known as the “package” (although you cannot use this keyword), which means that the field will be accessible from within the same package to which the class belongs.

uf, which you declare public, as it will be publicly accessible to all, regardless of whether it is abstract or not

+1
source

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

A variable or method declared without an access control modifier is available for any other class in one package.

So it doesn't matter which method is abstract or not.

+1
source

The method access level will remain by default (it will be displayed only inside the package ), even if the abstract class has a shared level. Only if the child class overrides the method using an access modifier, will it be visible outside the package.

0
source

You are on something, just a little off: in the default interfaces - mdash, and in fact the only choice is public. In all classes, the default is the same as private-package.

0
source

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

Thus, in reality, the compiler error message is really misleading, since it cannot be fixed if the access specifier for getHelp() in AbstractLearner is changed to 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"); } } 
0
source

Source: https://habr.com/ru/post/947821/


All Articles