2013-08-21 5 views
0

Приветствия и приветствия!Расширение абстрактного класса - реализация абстрактных методов

В настоящее время у меня есть абстрактный класс A, и многие классы подклассифицируют его. Код, общий для всех подклассов, которые я вложил в oneMethod(), и код, специфичный для каждой реализации, я применил два абстрактных метода.

public abstract class AbstractA { 
    public oneMethod() { 
      //do some intelligent stuff here 
      abstractMethodOne(); 
      abstractMethodTwo(); 
    } 
    protected abstract void abstractMethodOne(); 
    protected abstract void abstractMethodTwo(); 
} 

У меня есть класс, который переопределяет метод oneMethod().

public class B extends AbstractA { 
    @Override 
    public oneMethod() { 
      //do some other intelligent stuff here 
    } 
} 

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

Любая помощь приветствуется!

ответ

2

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

5

Нет. Если вы расширяете абстрактный класс, вы должны либо сделать дочерний класс абстрактным, либо выполнить контракт родительского класса.

Как конструктивное наблюдение, я предлагаю вам попытаться сделать oneMethod() окончательным или абстрактным. Трудно поддерживать программы, которые позволяют расширение, как вы его реализуете. Используйте другие абстрактные методы, чтобы дать дочерним классам перехватывать функции oneMethod().

0

Ну, если abstractMethodTwo и abstractMethodOne является конкретной реализацией, почему вы положили эти методы в базовом абстрактном классе? Возможно, общий интерфейс или какой-то определенный шаблон дизайна - это то, что вы ищете!

+0

Потому что oneMethod должен их называть. –

0

Если ваши классы B и A должны реализовать свой собственный метод oneMethod, возможно, потому, что нет ссылки на наследование, но они должны реализовать тот же интерфейс?

2

Вы можете тянуть oneMethod вверх в суперкласса:

public abstract class AbstractC { 
    public void oneMethod() { 
    } 
} 

public abstract class AbstractA extends AbstractC { 
    @Override 
    public void oneMethod() { 
    //do some intelligent stuff here 
    abstractMethodOne(); 
    abstractMethodTwo(); 
    } 

    protected abstract void abstractMethodOne(); 

    protected abstract void abstractMethodTwo(); 

} 

public class B extends AbstractC { 
    @Override 
    public void oneMethod() { 
    //do some other intelligent stuff here 
    } 
} 

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

+0

Ick. Несколько уровней абстрактного класса? Я бы не пошел по этому маршруту. –

+1

@EricStein - Это может быть «интерфейс», если абстракция вам неприятна. – OldCurmudgeon

1

Просто сделайте класс B также абстрактным.

public abstract class B extends AbstractA { 
+0

Это решит проблему компиляции, но мне также необходимо создать экземпляр класса позже, поэтому в любом случае понадобится заглушка. –

+1

Это будет то же самое, что не делать абстрактного абстракции и иметь пустые тела методов. В качестве альтернативы вы могли бы в конце сделать: 'new B() {@Override public void abstractMethodOne() {...} ...}'. –

+0

Это на самом деле работает лучше для меня, учитывая, что количество заглушек уменьшается до 2, а не (# подклассы, которые переопределяют oneMethod) * 2. –

1

С abstractMethodOne() и abstractMethodTwo() являются конкретной реализации, но вы знаете, что вы всегда будете называть их можно использовать композиции, как это:

public interface SomeInterface { 
    void abstractMethodOne(); 
    void abstractMethodTwo(); 
} 

и создать класс вроде этого:

public class SomeClass { 
    public void executeThem(SomeInterface onSomeObject) { 
     onSomeObject.abstractMethodOne(); 
     onSomeObject.abstractMethodTwo(); 
    } 
} 

, то вы можете составить это в любом из ваших классов, где вы должны называть эти методы следующим образом:

public class SomeImplementation implements SomeInterface { 

    public void abstractMethodOne() { 
     // ... 
    } 
    public void abstractMethodTwo() { 
     // ... 
    } 

    public void executeThem() { 
     new SomeClass().executeThem(this); 
    } 
} 

Таким образом, вы полностью избавились от наследования, и вы можете быть более гибкими в своих классах, реализуя SomeInterface.

+0

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

+0

Вы имеете в виду, что у суперкласса есть поля, которые вам нужно получить? –

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