Построение родительского абстрактного класса - PullRequest
0 голосов
/ 27 мая 2020

Java newb ie здесь. У меня есть два класса (назовем их A и B), и некоторые методы (например, doSomething(...)), которые они содержат, очень похожи в том смысле, что они фактически используют один и тот же код. Я решил сделать свой код более эффективным и использовать какой-то родительский абстрактный класс C, от которого будут унаследованы классы A, B.

Вот моя проблема. Метод doSomething в классе A имеет следующую сигнатуру:

doSomething(VievForA view, ...)

, тогда как тот же метод doSomething в классе B имеет сигнатуру, например:

doSomething(VievForB view, ...)

Как видите, метод doSomething использует другой тип первого параметра, поэтому я не знаю, как решить эту проблему в абстрактном классе.

What Как правильно создать класс C и как должен выглядеть метод doSomething? Надеюсь, я хорошо объяснил свою ситуацию, иначе я могу добавить еще псевдокод.

Ответы [ 5 ]

3 голосов
/ 27 мая 2020

У вас также может быть базовый класс представления, который будет унаследован ViewA и ViewB и использовать ViewBase в качестве параметра для doSomething.

2 голосов
/ 27 мая 2020

Вы можете структурировать свой код, используя Java дженерики следующим образом:

// View Classes
//====    

/**
 * The generic view parent class
 */
public abstract class GenericView{
}

/**
 * The specific A view class
 */
public class ViewForA extends GenericView{
    //...
}

/**
 * The specific B view class
 */
public class ViewForB extends GenericView{
    //...
}

// View Handler Classes
//====

/**
 * The generic view handler
 * @param <T> The view object that extends from GeneriView
 */
public abstract class C<T extends GenericView>{

    private void doGenericSomething(GenericView t) {
        //Do something generic on all views
    }

    //Do something specific on specific view
    abstract void doSpecificSomething(T t);

    //Do all stuff
    protected void doSomething(T t){
        doGenericSomething(t);
        doSpecificSomething(t);
    }

}

/**
 * The specific A view handler
 */
public class A extends C<ViewForA>{

    @Override
    void doSpecificSomething(ViewForA view) {
        //Do your stuff with viewForA
    }
}

/**
 * The specific B view handler
 */
public class B extends C<ViewForB>{

    @Override
    void doSpecificSomething(ViewForB view) {
        //Do your stuff with viewForB
    }
}

Таким образом вы можете вставить свой общий код в doGenericSomething(GenericView t) тело at C class, а затем пусть каждый указанный c класс просмотра, такой как классы A и B, реализует код specifici c на doSpecificSomething(ViewForSpecific t), где ViewForSpecifi c - это класс, наследуемый от GenericView (например, ViewForA и ViewForB в общем коде).

1 голос
/ 27 мая 2020

Вы можете использовать обычный унаследованный класс в качестве параметра метода:

doSomething(CommonViev view, ...)
{
   if (view instanceof VievForA)
   {
      VievForA vievForA = (VievForA)view;
      ...
   }
   else if (view instanceof VievForB)
   {
      VievForB vievForB = (VievForB)view;
      ...
   }
}
0 голосов
/ 27 мая 2020

Предполагая, что ваш doSomething() имеет повторяющийся код, вы можете реализовать общий код в abstract классе C и использовать его в реализации в A или B.

abstract class C {  
    protected Result doSomething(CommonStuff common){
        // doing common stuff and
        return result;  // returning the result
    }
} 


class A extends C { 
    public void doSomething(ViewForA view, ..){
         CommonStuff common = view.getStuff();
         Result result = this.doSomething(common);
         view.applyResult(result);
    }
}

Но это очень ... абстрактный пример. Если ваши ViewForA и ViewForB имеют общий интерфейс любого типа, было бы даже лучше использовать его. Когда-то я использовал общий интерфейс вроде этого:

 abstract class C {

      abstract protected ViewInterface getView();

      protected void doSomething(){
           this.getView().doStuffWithView();
      }
 }


 class A extends C {
     private ViewForA myViewForA; 

     @Override
     protected ViewForA getView(){
          return this.myViewForA;
     }
  }

Тогда абстрактный класс может обрабатывать doSomething, предполагая, что будет использоваться какой-либо общий экземпляр View. И классы A и B автоматически реализуют общий doSomething, и вы можете использовать его как

A a = new A();
a.doSomething();
0 голосов
/ 27 мая 2020

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

doSomething(Object view, ...)

и в классе A или классе B, используйте, как показано ниже

doSomething(Object view, ...){

VievForA(B) vievForA(B) = (VievForA(B)) view;     //basically typecast it as per child class

}

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...