Классы Помощника/Утилиты должны быть абстрактными?

class IDontControl
{
    class Nested
    {
        Nested(int i);
    };
};

Мне нужна прямая ссылка вроде:

class IDontControl::Nested; // But this doesn't work.

Мое обходное решение было:

class IDontControl_Nested; // Forward reference to distinct name.

Позже, когда я смог использовать полное определение:

#include <idontcontrol.h>

// I defined the forward ref like this:
class IDontControl_Nested : public IDontControl::Nested
{
    // Needed to make a forwarding constructor here
    IDontControl_Nested(int i) : Nested(i) { }
};

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

Но в моем очень простом случае это работает.

45
задан shsteimer 22 November 2008 в 16:18
поделиться

10 ответов

Вы могли просто объявить частного конструктора, который ничего не делает.

проблема с объявлением класса "краткий обзор" состоит в том, что абстрактное ключевое слово обычно означает, что класс предназначается, чтобы быть разделенным на подклассы и расширенным. Это определенно не, что Вы хотите здесь.

72
ответ дан Outlaw Programmer 8 November 2019 в 00:53
поделиться

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

Точка сравнения для заинтересованных: в C# Вы объявили бы, что класс статичен, делая его кратким обзором и изолированный (финал Java) в скомпилированной форме, и без любого конструктора экземпляра вообще. Это также делает его ошибкой времени компиляции для объявления параметра, переменной, массив и т.д. того типа. Удобный.

18
ответ дан Jon Skeet 8 November 2019 в 00:53
поделиться

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



public final class Utility
{
    private Utility(){}

    public static void doSomethingUseful()
    {
        ...
    }
}
9
ответ дан user38051 8 November 2019 в 00:53
поделиться

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

3
ответ дан Paul Sonier 8 November 2019 в 00:53
поделиться

Я добавил бы больше шага вне частного конструктора:

public class Foo {
   // non-instantiable class
   private Foo() { throw new AssertionError(); }
}

Бросок эти AssertionError предотвращает методы в том же классе от инстанцирования класса (хорошо, они могут попробовать). Это обычно не проблема, но в среде команды Вы никогда не знаете то, что кто-то сделает.

Что касается "абстрактного" ключевого слова, я заметил классы утилит, разделенные на подклассы в многочисленных экземплярах:

public class CoreUtils { ... }
public class WebUtils extends CoreUtils { ... }

public class Foo { ... WebUtils.someMethodInCoreUtils() ... }

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

С уважением, LES

3
ответ дан Dylan Davidson 8 November 2019 в 00:53
поделиться

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

Краткий обзор для классов, которые ДЕЙСТВИТЕЛЬНО имеют основанные на экземпляре детали реализации, которые будут использоваться экземплярами производных классов...

0
ответ дан Charles Bretana 8 November 2019 в 00:53
поделиться

кто-то упомянул, что в C# 3.0 Вы могли выполнить это с помощью дополнительных методов. Я не парень C#, сделал немного назад в 1.5/2.0 дни, но не использовали его с тех пор. На основе очень поверхностного понимания я думаю, что что-то подобное может быть выполнено в Java со статическим импортом. Я не понимаю нисколько то же самое, но если цель состоит в том, чтобы просто заставить эти служебные методы казаться немного более "собственными" (из-за отсутствия лучшего термина) к классу вызова, я думаю, что это добьется цели. При принятии класса Утилит я объявил в своем исходном вопросе.

import static Utilities.getSomeData;

public class Consumer {

    public void doSomething(){

        String data =  getSomeData();
    }

}
0
ответ дан shsteimer 8 November 2019 в 00:53
поделиться

Помощник / Служебные методы очень хорошо. Не волнуйтесь о добавлении их к библиотеке в Вашем приложении или Платформе. Большинство платформ, которые я видел, использует их во многих вариантах.

Однако если Вы хотите стать действительно лукавыми о них, необходимо изучить дополнительные методы в C# 3.0. Используя дополнительный метод сделает Ваши Утилиты немного больше "целостной" части Вашей платформы, которая походит на то, что Вы пытаетесь сделать путем рассмотрения для создания их абстрактными. Не говоря уже о дополнительном методе большая забава записать!

0
ответ дан Iterator 8 November 2019 в 00:53
поделиться

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

, Поскольку другие показали, как это сделано с другими языками, здесь прибывает, как Вы делаете это в следующей версии C++, как сделать класс non-instantiable:

struct Utility { 
    static void doSomething() { /* ... */ } 
    Utility() = delete; 
};
2
ответ дан Johannes Schaub - litb 8 November 2019 в 00:53
поделиться

Я мог бы дать некоторый конструктивный совет?

при выполнении большого количества этого существует две проблемы, с которыми Вы столкнетесь.

, В первую очередь, статический метод, который берет параметр, должен часто быть частью объекта, который является тем параметром. Я понимаю, что это не помогает для объектов как Строка, но если она берет объекты, Вы определили, Вы могли бы почти наверняка улучшить объект включением Вашего помощника как метод того объекта.

, Если это принимает все собственные значения, Вы, вероятно, могли бы определить объект, из которого это является метод. Посмотрите, можно ли найти какую-либо группировку тех собственных значений и сгруппировать их как объект. Если Вы просто попробуете это, то Вы найдете большое другое использование для того небольшого мини-объекта, и перед знанием этого, это будет удивительно полезно.

Другая вещь, если у Вас есть служебный класс с набором полусвязанных статических методов и статических переменных, Вы почти всегда, хочет, чтобы он был одиночным элементом. Я узнал это методом проб и ошибок, но когда Вы узнаете необходимость больше чем в 1 (в конечном счете, Вы будете), НАМНОГО легче превратить одиночный элемент в multipleton(?) затем, чтобы попытаться изменить статический класс в multipleton (хорошо, таким образом, я составляю слова теперь).

Удача. Этот материал был главным образом методом проб и ошибок для меня - понял это как 5 лет назад, хотя, и я никогда не находил экземпляр, где я сожалел, что не имел статического класса/методов.

0
ответ дан Bill K 8 November 2019 в 00:53
поделиться
Другие вопросы по тегам:

Похожие вопросы: