2012-01-31 5 views
1

Я не знаю exacly как описать мою проблему, так что я буду делать пример:методов после расширения абстрактного класса

public abstract class A { 

    public abstract void methodToOverride(); 
    public void methodNotToOverride() { } 

} 

public class B extends A { 

    @Override 
    public void methodToOverride() { } 
    public void someOtherMethodNotFromClassA() { } 

} 

теперь мне нужно сделать такую ​​вещь в моем коде:

A object = new B(); 
object.someOtherMethodNotFromClassA(); 

но я получаю «Невозможно разрешить ошибку метода». Определение такого метода в абстрактном классе не является вариантом. Любая подсказка?

+1

'class' - это ключевое слово в Java. вы не можете использовать его как (переменный) идентификатор. – Vlad

+0

Я сделал это в спешке, извиняюсь за синтаксис – kamil

ответ

3

Это невозможно. В то время как объект типа В, ссылка имеет тип A. Таким образом, вы только в состоянии получить доступ к методам видимых классу А.

Если вы измените это:

A a = new B(); 

к этому:

B a = new B(); 

вы сможете получить доступ к someOtherMethodNotFromClassA. Другим вариантом было бы, чтобы бросить a к типу B:

A a = new B(); 
((B)a).someOtherMethodNotFromClassA(); 
+1

Ну ... вот и все, у меня было затемнение или sth и я не мог понять это сам, спасибо :) – kamil

2

Несмотря на, что есть некоторые другие синтаксические ошибки, Оливер Weiler прав, ссылка типа А, таким образом, вы можете только методы доступа типа А .

Если вы приводите его к типу в, то вы можете также получить доступ к методам типа B. для перехода в безопасности, проверьте, если тип действительно B с instanceof

A clazz = new B(); 
if (clazz instanceof B) 
    ((B)clazz).someOtherMethodNotFromClassA(); 

Я считаю, что ваш реальный код немного сложнее, поэтому вы может думать о литье ...

И btw: переменное имя «класс» не работает, используйте somethign different.

+0

'class' на самом деле это имя, которое компилятор не допустит ты используешь. Большинство людей используют 'clazz' вместо этого, чтобы идентифицировать объект класса. – Marcelo

1

Если вы действительно нужно использовать метод из класса B и действительно нужно указать, если с помощью абстрактного суперкласса A, вы можете использовать:

A clazz = new B(); 
((B)clazz).someOtherMethodNotFromClassA(); 

Пожалуйста, обратите внимание, что это не очень хорошая практика.

1

У вас есть два вопроса в коде.

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

@Override 
public void methodToOverride(){ 
// does nothing 
} 

Во-вторых, и что более важно, когда вы создать экземпляр объекта как тип A, только методы, относящиеся к A доступны. Поскольку вы определяете new B() как тип A, у вас не будет доступа к методу someOtherMethodNotFromClassA.

Если вы хотите получить доступ к нему, вам необходимо либо создать его экземпляр в качестве класса B, или бросить его в качестве класса B:

B someClass = new B(); 
someClass.someOtherMethodNotFromClassA(); 

или

A someClass = new B(); 
((B)someClass).someOtherMethodNotFromClassA(); 

Но имейте в виду, что последний вариант довольно уродлив и не прост в обслуживании.

0

Я только что наткнулся на эту проблему, и это ужасно! Как вы должны создавать повторно используемый код, если вы не можете использовать подклассы в качестве аргументов? например в библиотеке:

public abstract class AbstractSetting { 
    private boolean property = false; 
    public void getProperty() { return property; } 
} 

public abstract class AbstractFoo { 
    protected AbstractSetting setting; 

    protected void setSetting(AbstractSetting setting) { 
     this.setting = setting; 
    } 

    public boolean foo() { 
     setting.getProperty(); 
    } 
} 

Затем в программе:

public class Setting extends AbstractSetting { 
    private boolean extraProperty = false; 
    public void getExtraProperty() { return extraProperty; } 
} 

public class Foobar extends AbstractFoo { 
    public void foobar() { 
     setting.getProperty(); 
     setting.getExtraProperty(); // CAN'T RESOLVE ! 
    } 
} 

Foo foo = new Foo(); 
foo.setSetting(new Setting()); 
foo.foobar(); 

Как одну работу вокруг этого?

+0

Хорошо, чтобы ответить на мой собственный вопрос, я подумал о добавлении 'property' в подкласс, переопределяя' setSetting' и вызывая 'super.setSetting'. Но что такое клод. Вы могли бы подумать, что можете просто переопределить 'свойство' новым типом. Но это не работает. Вы получаете нулевую ошибку для любого метода в абстрактном классе. – trans