Как переопределить класс в проекте библиотеки Android? - PullRequest
11 голосов
/ 03 июля 2011

Вот моя ситуация:

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

Но каждый раз, когда класс A делает вызов, он попадает в класс B из библиотеки. Как я могу сказать Android, что класс B из моего проекта должен использоваться INSTEAD класса B из библиотеки?

Ответы [ 3 ]

3 голосов
/ 03 июля 2011

Это не работает с текущим макетом. Вы должны использовать шаблон стратегии. В вашей библиотеке определите LibA с помощью конструктора, который принимает в конструктор объект типа LibB:

class LibA{
    LibB b;
    public LibA(LibB b)
        this.b = b;
    }
}

Затем вы можете переопределить LibB в своем проекте и создать LibA с классом, расширяющим LibB:

class ProjectB extends LibB{

}

LibA a = new LibA(new ProjectB());

Ответ на вопрос Turbos:

Вы хотите запустить Project-Activity из вашей библиотеки. Затем переместите код, который создает Intent в ваши проекты , потому что только в вашем проекте вы знаете тип или имя Activity, которое должно быть запущено.

Решение, которое вы упомянули в своем комментарии ( здесь ), создает Intent в проекте библиотеки, угадывая имя Activity, которое должно быть запущено. В этом нет ничего плохого, но это не элегантное решение. Вы можете запустить только Activities, которые следуют этой специальной схеме именования. И из-за этого вы не можете запускать произвольные Activities, которые видны в ваших проектах, например Activities, из других библиотек, где вы не можете изменить имя класса.

Чтобы переместить создание Intent в свои библиотеки, вы можете использовать стратегию, шаблон или шаблон фабричного метода. См. Шаблоны проектирования в Википедии , чтобы узнать еще больше (творческих) шаблонов, соответствующих дизайну вашей библиотеки.

Простое решение будет:

Создайте реферат LibraryActivity и расширьте ваши ProjectActivities из него LibraryActivity определяет абстрактный метод, который возвращает Intent. Реализация этого абстрактного метода выполняется в вашем ProjectActivities.

abstract class LibActivity{

    private void doSomething(){
        //Library does something

        //and finally calls createIntent() to start an project specific Activity
        startActivity(this.createIntent());
    }

    protected abstract Intent createIntent();
}


class ProjectActivity extends LibActivity{

    protected Intent createIntent(){
        return new Intent(ProjectActivity.this, AnyActivityYouWant.class);
    }        
}
0 голосов
/ 27 февраля 2012

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

Я создаю класс A из проекта, и этот класс расширяется от проекта библиотеки

public class A extends libraryProject_A{

//here i put all methods from the new class B to override methods from library class B

}
0 голосов
/ 03 июля 2011

Как я вижу из вашего комментария, у вас есть класс A, который использует класс B

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

Я думаю, вам нужно создать базовый класс, скажем, BaseB, который будет переменной экземпляра в классе A, и у вас могут быть для этого методы set и get или вы можете сделать его параметром, передаваемым конструктору класса A. и при создании экземпляра A вы должны выбрать, какой использовать.

Давайте посмотрим на код

Class A {
 private BaseB b;
 public A(BaseB aB) {
   b = aB;
 }

 public void set(BaseB aB) {
  b = aB;
 }
 public BaseB get() {
   return b;
 }
}

interface BaseB {
}


// in the library have this
class B implements BaseB {
}

// in your project have the other implementation
class B implements BaseB {
}

// you can then instantiate A like this
A a = new A(new B());
// you can choose which one to use here in the previous statement.
...