Как переопределить класс в проекте библиотеки Android?

следующая моя ситуация:

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

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

3 ответов


это не работает с текущим макетом. Вы должны использовать шаблон стратегии. В вашей библиотеке определите 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());

ответ на вопрос Турбос:

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

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

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

простым решением было бы:

создать абстрактный LibraryActivity и расширить свой ProjectActivities от него. The 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);
    }        
}

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

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

Я думаю, вам нужно создать базовый класс, скажем, BaseB, который будет переменной экземпляра в классе A, и у вас может быть сеттер и геттер для этого, или вы можете сделать его параметром, переданным конструктору класса 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.

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

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

public class A extends libraryProject_A{

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

}