2015-11-24 3 views
0

Хорошо, поэтому я не уверен, что этот вопрос уже существует, потому что я не знаю, как его отформатировать, но вот в чем проблема: может ли один и тот же метод производить другой результат в зависимости от конструктора? (Приносим извинения, если я повторяю вопрос или если это глупый вопрос.)Как переопределить метод в зависимости от конструктора?

Например, у меня есть интерфейс MyInterface с функцией public void foo();. Скажем, у нас есть класс:

public class MyClass implements MyInterface { 
    public MyClass() { 
     // I want foo() to print "Empty constructor" with sysout. 
    } 

    public MyClass(int x) { 
     // I want foo() to print "Constructor with int" with sysout. 
    } 
} 

Так что теперь, если создать две ссылки MyClass mc1 = new MyClass(); и MyClass mc2 = new MyClass(5);, а затем вызвать mc1.foo(); и mc2.foo();, результат должен быть:

пустой конструктор.

Конструктор с инт.

Я пробовал с new MyInterface { @Override public void foo() { ... } } внутри конструкторов, но, похоже, не работает.

+2

Итак, вы хотите использовать разные методы? Защитная переменная? Два разных класса – Emz

+0

Вы делаете это для удовольствия? В чем смысл? –

+0

Короткий ответ да, но вам нужно написать код, например, вы можете использовать поле экземпляра 'private Integer value;', в вашем конструкторе 'public MyClass (int x)' вы должны назначить значение 'x' на 'значение'; 'value = x'.Затем в 'foo' будет проверять' значение', чтобы увидеть, было ли оно «null» или нет; 'if (value == null)', когда 'value' является' null', вы должны печатать 'Empty constructor.', когда это не так, вы можете напечатать' Constructor with int''; в качестве примера – MadProgrammer

ответ

0

Да. Сохраните переменную и проверьте ее в методе foo.

public class MyClass implements MyInterface { 
    private int x; 
    public MyClass() { 
     // I want foo() to print "Empty constructor" with sysout. 
    } 

    public MyClass(int x) { 
     // I want foo() to print "Constructor with int" with sysout. 
     this.x = x; 
    } 

    public void foo(){ 
     if(x > 0) 
      System.out.println("Constructor with int"); 
     else 
      System.out.println("Empty constructor"); 
    } 
} 
+0

Итак, если я использую 'новый MyClass (-10)', он будет печатать 'Constructor with int' – MadProgrammer

+0

Если a пользователь создает экземпляр класса с '<= 0', это не сработает. Я рекомендую использовать какой-то «объект», как «Целое», просто проверяйте «null». – Emz

+0

Ну, вы можете сохранить логическое значение, указывающее, использовал ли он этот конструктор. Или вы можете сделать int целочисленным и вместо проверки на большее, чем ноль, проверьте, является ли оно нулевым. Он будет пустым для конструктора по умолчанию. –

0

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

Теперь странные детали: override и depending on constructor. Он не входит в объем overriding.

Метод, делающий разные вещи в зависимости от состояния Class, не слишком странный. Однако, делая метод уникальным из того, как класс был создан, я никогда не слышал. При этом здесь довольно уродливое решение.

public class Test 
{ 
    private final boolean intConstructorUsed; 

    public Test() { 
     intConstructorUsed = false; 
    } 

    public Test (int x) { 
     intConstructorUsed = true; 
    } 

    public void foo() { 
     if (intConstructorUsed == true) { 
      // do this 
     } else { 
      // do that 
     } 
    } 
} 

Метод foo не что странно. Странная часть состоит в том, что вы в основном должны иметь разные реализации foo в зависимости от того, какой конструктор вы уверены, что вам не нужен abstract class позади, со всеми общими методами, кроме одного abstract void foo(), который вы переопределите? Конечно, классы будут выглядеть почти одинаково, но они не являются, поскольку они не делят свои foo().

0

Да, это то, что несколько конструкторов предназначены для разрешения - изменения посредством создания объекта.

public class MyClass implements MyInterface { 
    private final String message; 
    public MyClass() { 
     message = "Empty constructor"; 
    } 

    public MyClass(int x) { 
     message = "Constructor with int"; 
    } 

    @Override 
    public void foo() { 
     System.out.println(message); 
    } 
} 

Это даже потокобезопасное.

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

Смежные вопросы