Наследование - не единственный способ повторно использовать обычную функциональность.Сдерживание может быть предпочтительнее в общем случае.Рассмотрим следующее решение, в котором классы A и B являются синглетонами, а общая функциональность - в классе AB, но вместо расширения AB, A и B используют экземпляр AB, который сам является одиночным.
class AB { //common functionality of A and B
//singleton pattern here
//common data and functionality here
}
class A {
private AB ab = AB.getInstance();
//singleton pattern here
//unique functionality and data of A
//to use any of the functionality in AB delegate to member ab
}
класс B аналогичен A.
. В этом решении есть один экземпляр всех данных и функций как A, так и B (и AB)
Обратите внимание, что если клиенты Aи B необходимо получить доступ к общим открытым методам в AB, тогда AB, A и B должны реализовать интерфейс этих открытых методов, а реализация A и B должна делегировать вызов ab.
Решение, предложенное Эрнестом ниже, в некоторых ситуациях может быть сокращением, но в целом это неправильное решение.
Чтобы объяснить, почему решение Эрнеста может быть неправильным, давайте опишем, чтоРешение по-другому.Предположим, у меня есть одноэлементный класс A, и я обнаружил, что мне нужно написать еще один одноэлементный класс B, но мне нужны некоторые функциональные возможности A в B. Поэтому я выделяю общие данные и функциональные возможности A в абстрактный класс AB и создаюи A и B расширяют AB.В общем, причина его неправильности в том, что это решение берет подмножество данных и функциональных возможностей, которые должны существовать только один раз, и помещает их в подкласс (AB), эффективно и потенциально дублируя их в каждом подклассе.класс, который будет создан.Теперь, после получения экземпляра A и экземпляра B, у вас есть два экземпляра данных подмножества и функциональности в AB.
Если, например, общая функциональность, размещенная в базовом классе, записывает некоторые исходные данные в файл с именем «myData», то оба ваших синглета будут выполнять этот код, даже если он должен был быть выполнен только один раз,и когда последний выполнит его, он уничтожит файл, созданный первым.
Следовательно, в общем случае решение, описанное здесь, не использует наследование и гарантирует, что синглтон инкапсулирует общие функциональные возможности, а такжеодноэлементные классы, которые его используют.