2015-10-28 2 views
0

Я пытаюсь создать общий метод, но для этого требуются данные из подкласса. Есть ли способ сделать это, или есть лучшая реализация?Как получить доступ к переменной подкласса из универсального суперкласса

Пример моей ситуации:

public class Super { 
    public static Object method() { 
     return doSomethingWith(specificToSubClassValue); 
    } 
} 

public class Sub1 extends Super { 
    public static String specificToSubClassValue = "123"; 
} 

public class Sub2 extends Super { 
    public static String specificToSubClassValue = "456"; 
} 

я, очевидно, не может это сделать. Какой подход лучше?

Один из вариантов, о котором я могу думать, состоит в том, чтобы переопределить метод #method в каждом подклассе, но в каждом экземпляре он будет одним и тем же кодом, поэтому я хотел бы бросить его в родительский класс (и он не будет действительно переопределено, поскольку оно является статичным), но я не уверен, как с ним обращаться, поскольку он зависит от значения подкласса.

+3

Статические методы не вызывается полиморфно. Их нельзя переопределить. –

+0

Я знаю, что упоминал это в скобках. Часть причины этого вопроса :) Я искал способ обойти это, но не могу думать о рабочем решении. Я думаю, что моя реализация (очевидно) бедна и хотела знать о хорошем пути решения этой проблемы или о правильной реализации, чтобы избежать этой проблемы. – rys

ответ

0

Объявление абстрактного метода в Super, которое будет использоваться для возврата значения из классов реализации. Обратите внимание, что это может быть достигнуто только с помощью нестатических методов. Согласно комментарию @JB Nizet, статические методы не могут быть переопределены подклассами. Я удалил статический модификатор из кода ниже, чтобы показать вам, как он будет работать.

public class Super { 
    public static Object method() { 
     return doSomethingWith(specificToSubClassValue); 
    } 

    protected abstract Object getValue(); 
} 

public class Sub1 extends Super { 
    public static String specificToSubClassValue = "123"; 

    @Override 
    protected Object getValue() { 
     return specificToSubClassValue; 
    } 
} 

public class Sub2 extends Super { 
    public static String specificToSubClassValue = "456"; 

    @Override 
    protected Object getValue() { 
     return specificToSubClassValue; 
    } 

} 
+1

Метод() является статическим. Он не может вызвать getValue(). (и вы все равно забыли его назвать). –

+0

@JBNizet Правда, я не видел, чтобы его методы были статичными. Я отрегулирую свой ответ, спасибо;) – Laf

+0

Дайте мне знать, когда вы отрегулируете свой ответ :) – rys

0

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

Что вам нужно здесь, это метод экземпляра, который вы можете перезаписать. Вы также можете использовать дженерики.

public class Super<T> { 
    public Object method() { 
     final T specificToSubClassValue = getSpecificToSubClassValue(); 
     if (specificToSubClassValue != null) { 
      return specificToSubClassValue.hashCode(); 
     } else { 
      return null; 
     } 
    } 

    protected T getSpecificToSubClassValue() { 
     return null; 
    } 
} 

class Sub1 extends Super<String> { 
    @Override 
    protected String getSpecificToSubClassValue() { 
     return "abc"; 
    } 
} 

class Sub2 extends Super<Integer> { 
    @Override 
    protected Integer getSpecificToSubClassValue() { 
     return 123; 
    } 
} 
+0

У вас есть решение, когда 'method' является' static'? – rys

+0

@rys no. Статический метод принадлежит * только * классу, в котором он объявлен. Он не может иметь доступ к текущему экземпляру, поэтому его нельзя использовать с наследованием. – user996142

-1

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

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

Вы могли бы:

public class Super { 
    public Object method(String specificValue) { 
     return doSomethingWith(specificToSubClassValue); 
    } 

А затем ваш суб сделать это

public class Sub1 extends Super { 
    public static String specificToSubClassValue = "123"; 
    Object method(specificToSubClassValue); 
} 

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

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