Що таке стандартний рівень доступу для методів в загальнодоступному абстрактному класі в Java?

Зазвичай рівень доступу за замовчуванням методів - локальний пакет. Але мені здається, що для публічних абстрактних класів це відрізняється. У цих класах загальнодоступний за замовчуванням. Це правильно?

Оновити

@ EJP

Це було помилкою в моєму коді. Можна тіньувати локальний метод пакета за допомогою відкритого методу, що мене заплутує. Це змушує мене думати, що публічний абстракт може бути схожим на інтерфейс, де методи є загальнодоступними. Див. Приклад:

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());
    }
}
8
Чи ви вважаєте, що тестувати його з компілятором? Або шукати JLS?
додано Автор EJP, джерело

6 Відповіді

False, let's see with a quick example:

package apackage;

public abstract class AbstractFoo {

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

}

Швидка реалізація:

public class Foo extends AbstractFoo {

  @Override
  void bar() {}
}

Тепер, в іншому пакеті:

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

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

Компілятор скаржиться на видимість. Тож видимість методів за замовчуванням - захищений пакунками , навіть якщо клас public abstract .

10
додано
На підставі JLS я б сказав, що він повинен бути приватним, але оскільки кожен може застосувати (публічний) абстрактний клас і буде потрібно його реалізувати, він, напевно, є protected .
додано Автор Mark Rotteveel, джерело
Метод не protected , але 'package private', ви не можете перевизначити абстрактний метод доступу за замовчуванням в іншому пакеті. Див мой відредагований відповідь.
додано Автор Mark Rotteveel, джерело

Специфікація Java Language для Java 7 не згадується окремі правила для абстрактних методів, тому що такий абстрактний метод без кваліфікованого рівня доступу є за замовчуванням aka пакунок приватний, точно так само, як був би звичайний метод.

Див. Також 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 і 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 і 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.

(наголос мій)

Також зауважте, що термін " доступ до стандартного доступу " еквівалентний " пакету приватного ", єдиним "виключенням" до цього є декларації способу інтерфейсу, які просто завжди < код> загальнодоступний , тому для них не потрібно вказувати префікс.

Редагування:

Оскільки adenoyelle вказує в його відповідь , ви можете замінити абстрактний метод за замовчуванням в іншому пакеті (як вимагається правилами в JLS 8.4.3.1. abstract ), ви можете вважати їх protected , але швидка перевірка JLS, здається, не робить це явним.

Редагувати 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 requires that it is always possible to implement an abstract method, just that it excludes nonsensical options like private abstract void method()

Наприклад, компіляція:

package example;

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

і

package example.sub;

import example.AbstractTest;

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

Викликає скомпілювати помилку:

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

2
додано

Модифікатор доступу за умовчанням означає, що ми не оголошуємо модифікатор доступу для класу, поля, методу тощо.

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

Тому немає сенсу, чи метод є абстрактним чи ні.

1
додано

Видимість за умовчанням відома як "пакет" (хоча ви не можете використовувати це ключове слово), а це означає, що поле буде доступне з того самого пакунка, до якого належить клас.

ви оголошуєте як публічну, ніж буде публічно для всіх, незалежно від того, чи є вона абстрактною чи ні

1
додано

Рівень доступу до методів залишатиметься за умовчанням ( буде видимим лише в пакеті ), навіть якщо абстрактний клас має загальнодоступний рівень доступу. Тільки якщо дочірній клас перевизначить метод з модифікатором пульсирующего доступу, він буде видно за межами пакета.

0
додано

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.

0
додано
ІТ КПІ - Java
ІТ КПІ - Java
436 учасників