Перепрыгните через родительского конструктора для вызова прародителя

Interop медленнее, чем просто ловля исключения:

В счастливом пути, с 10 000 Гуидов:

Exception:    26ms
Interop:   1,201ms

В несчастном пути:

Exception: 1,150ms
  Interop: 1,201ms

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

12
задан German 20 December 2009 в 20:49
поделиться

7 ответов

Легко (но почему?):

class AbstractClass {
   AbstractClass(){ /* useful implementation */ }
}

class ConcreteClass1 extends AbstractClass {
     ConcreteClass1(){ super(); /* useful implementation */ }
     ConcreteClass1(boolean skip){ super(); }
}
class CustomizedClass1 extends ConcreteClass1 {
     CustomizedCLass1(){ super(true); /* useful implementation */ }
}
10
ответ дан 2 December 2019 в 03:14
поделиться

Вы не можете сделать это на Java. У меня часто есть студенты, которые хотят это сделать, но я никогда не видел случая, чтобы это действительно было тем, чем они хотели заниматься.

Вы можете привести конкретный пример того, что вы хотите делать и почему (ваше описание слишком расплывчато) и я уверен, что решение может быть достигнуто :-)

Изменить:

В качестве реального примера того, почему вы не хотите этого делать (обычно), будет иерархия вроде:

Animal (constructor makes the eyes)
  |
Mammal (constructor makes the lungs)
  |
Human (constructor sets the language)

Если конструктор Human может пропустить конструктор Mammal, тогда вы получите человека, у которого нет легких ... не очень полезно.

21
ответ дан 2 December 2019 в 03:14
поделиться

Два комментария: Во-первых, вы не должны думать о таких конструкторах, как «перепрыгивать через них». Во-вторых, на самом деле звучит так, будто вам нужно переосмыслить отношения между классами.

Каждый раз, когда вы обнаруживаете, что думаете: «A расширяет B, за исключением того, что ...» - это очень хорошее время, чтобы взглянуть на вещи дальше. 'Extends' подразумевает 'is a', которое является отношением "или-или": наличие необязательного поведения добавляет серые области, которые вас укусят позже.

Как люди сказали, вы можете предоставить несколько конструкторов для ConcreteClass1 для выполнения вашей инициализации require в каждом случае, возможно, сделав их защищенными, чтобы они могли использоваться только подклассами. Но вот вопрос: что, если кто-то захочет написать CustomizedClass2, которому нужны некоторые (но не все) функциональные возможности ConcreteClass1? Вы добавляете еще один пользовательский конструктор?

7
ответ дан 2 December 2019 в 03:14
поделиться

Для меня это звучит как смесь проблем - с чем-то Java не справляется.

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

Как сказал @TofuBeer, это не то, что поддерживает Java. Вот почему некоторые современные языки (например, Scala w / Traits) привлекают энтузиастов разработчиков.

1
ответ дан 2 December 2019 в 03:14
поделиться

Почему бы просто не настроить только что созданный экземпляр ConcreteClass1 , чтобы он вел себя как экземпляр AbstractClass (при условии, что ConcreteClass1 имеет соответствующие защищенные методы только для этого)? То есть:

class AbstractClass {
     public AbstractClass() { /* useful implementation */ }
}

class ConcreteClass1 extends AbstractClass {
     public ConcreteClass1() { 
        /* A hidden super() call put here by the compiler. */
        /* Useful implementation */ 
     }

     protected void customize_with(SomeParams customization_params) {
        /* 
        Customize this ConcreteClass1 instance according to parameters 
        passed. As a result, the instance behavior will 'revert' (in the 
        way you need it) to that of an AbstractClass instance.
        */
     }
}

class CustomizedClass1 extends ConcreteClass1 {
    public CustomizedCLass1() {
        /* A hidden super() call put here by the compiler. */
        customize_with(customization_params);
        /* Rest of useful implementation */ 
     }
}

Намерения и логика проекта могут быть следующими:

  1. Вы хотите получить (основное) поведение ConcreteClass1 через наследование, вы наследуете от него (это, конечно, требует его проектирования стоит унаследовать от).

  2. Вы хотели бы настроить поведение, обеспечиваемое ConcreteClass1 по умолчанию. Настройку, которую вы хотите достичь, обычно можно описать с помощью некоторых параметров. Просто передайте эти параметры специальному методу CustomizedClass1 (который можно защитить),

0
ответ дан 2 December 2019 в 03:14
поделиться

Любой экземпляр CustomizedClass1 также является экземпляром ConcreteClass1 по определению, поэтому он должен быть сконструирован как допустимый Экземпляр ConcreteClass1 перед запуском конструктора CustomizedClass1 . Иначе что произойдет, если вы вызовете для него методы ConcreteClass1 ? Они будут пытаться работать с переменными, которые еще не были инициализированы.

Если вы думаете, что вам нужно это сделать, скорее всего, ваш дизайн нуждается в переосмыслении. Если вам нужна только часть функций из ConcreteClass1 , например, эта функциональность может быть выделена в суперкласс ConcreteClass1 ,

8
ответ дан 2 December 2019 в 03:14
поделиться

Один из способов, который я придумал:

class AbstractClass {
     AbstractClass(){ init(); }
     protected init(){ /* useful implementation */ }
}

class ConcreteClass1 extends AbstractClass {
     ConcreteClass1(){ init(); /* useful implementation */ }
}

class CustomizedClass1 extends ConcreteClass1 {
    CustomizedCLass1(){ init(); /* useful implementation */ }
}

Таким образом, CustomizedClass1 получает необходимое поведение от AbstractClass, не проходя через инициализации ConcreteClass1.

EDIT: Ой, это не работает, потому что родительские конструкторы вызываются неявно как заметил один из комментаторов, я думаю, что проще всего использовать разные конструкторы.

0
ответ дан 2 December 2019 в 03:14
поделиться
Другие вопросы по тегам:

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