2012-05-29 5 views
2

По какой-то причине я, похоже, не способен реализовать абстрактный класс за пределами пакета, в котором он определен. Абстрактный класс в пакете1 не может быть реализован в классе в пакете2. Почему это не законная Java?Невозможно реализовать абстрактный класс из другого пакета

package com.stackoverflow.abstraction.package1; 

abstract public class BaseClass { 
    abstract Long foo(); 
} 

package com.stackoverflow.abstraction.package1; 

public class Implement1 extends BaseClass { 
    @Override 
    Long foo() { 
     return null; 
    } 
} 


package com.stackoverflow.abstraction.package2; 

import com.stackoverflow.abstraction.package1.BaseClass; 

/** Compiling this class will output 
* - Implement2 is not abstract and does not override abstract method foo() in BaseClass 
* - error: method does not override or implement a method from a supertype 
*/ 

public class Implement2 extends BaseClass { 
    @Override 
    Long foo() { 
     return null; 
    } 
} 

Продолжительность: OS X 10.6.8 - Java (TM) SE Runtime Environment (сборка 1.6.0_31-b04-415-10M3646) - OpenJDK Runtime Environment (сборка 1.7.0-U4-b13 -20120301) Пробовал обе версии Java. Не в то же время, конечно :)

ответ

7

Ваши два foo метода имеют "пакет" по умолчанию доступ к. Ваш Implementation2 класс не мог даже позвонить метод - так что не имеет смысла быть в состоянии переопределить это.

Неясно, какой уровень доступа вам хотите их иметь, но самый простой подход, вероятно, сделать их общедоступными. В данный момент, вы говорите, что только абоненты в package1 могут звонить по номеру BaseClass.foo(), но только абоненты в package2 могут звонить по телефону Implement2.foo(). Это явно не имеет большого смысла. Кто вы такой хочу уметь получить доступ к этому методу? Если вы хотите, чтобы вызывающие абоненты внутри класса или подкласса могли его называть, сделайте это protected - в противном случае сделайте это public.

См. section 6.6 of the Java Language SpecificationJava tutorial) для получения дополнительной информации о модификаторах доступа. В частности, после прохождения различных модификаторов доступа:

В противном случае мы говорим, что есть доступ по умолчанию, который разрешен только в том случае, если доступ происходит изнутри пакета, в котором объявлен тип.

+0

@brimborium: Исправлено, спасибо. –

+0

Вы уверены, что можете быстро расширить свой ответ. Смешно видеть, как он развивается из одной строки :) – oligofren

+0

@oligofren: Я не думаю, что этот конкретный был когда-либо одной строкой, но да - я начинаю с голых костей, а затем добавляю больше контекста, предложений, ссылок и т. Д. , –

10

Этот метод - видимость уровня пакета, поэтому вы не можете переопределить его в другом пакете.

abstract Long foo(); 

Если метод не имеет никакого модификатора (по умолчанию, также известный как пакет-частное), она видна только в его собственном пакете

Если вам действительно нужно, чтобы заменить его, сделайте это как protected.

protected abstract Long foo(); 

Информация

+1

+1 его нужно «защищать» или «публично» –

+0

Вы «можете» или «не можете»? –

+0

@edalorzo это опечатка, см. Обновленный ответ. –

4

У вас есть четыре модификаторов доступа:
- публика - вы можете использовать его везде
- частный - вы можете использовать его только внутри класса
- защищенный - вы можете использовать только внутри класса и классов, которые наследуют его
- доступ к пакету (по умолчанию, без модификатора) - вы можете использовать его только в пакете, который класс принадлежит

В этом случае у вас нет модификатора, который в целом обрабатывается как доступ к пакету.

Смежные вопросы