ceving
ceving

Reputation: 23876

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

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

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:

package a;

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

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());
    }
}

Upvotes: 13

Views: 17606

Answers (7)

Mark Rotteveel
Mark Rotteveel

Reputation: 109146

The Java Language Specification for Java 7 does 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.

See also 6.6.1. Determining Accessibility:

  • 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.

(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 public and therefor don't need to be prefixed.

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. abstract Methods), as such you could consider them to be protected, but a quick scan of the JLS doesn't seem to make this explicit.

Edit 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()

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

Upvotes: 4

Chaz
Chaz

Reputation: 1

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.AbstractImpl is not abstract and does not override abstract method getHelp() in 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 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");
    }
}

Upvotes: 0

Arnaud Denoyelle
Arnaud Denoyelle

Reputation: 31253

False, let's see with a quick example:

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.

Upvotes: 15

Marko Topolnik
Marko Topolnik

Reputation: 200236

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

Upvotes: 0

Ananth
Ananth

Reputation: 206

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.

Upvotes: 0

Suresh Atta
Suresh Atta

Reputation: 122006

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

A variable or method declared 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 .

Upvotes: 1

shreyansh jogi
shreyansh jogi

Reputation: 2102

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

Upvotes: 2

Related Questions