2013-07-10 2 views
1

У меня есть класс под названием Packet, а класс под названием PacketClientConnecting ведьма расширяет его. Экземпляры PacketClientConnecting и другие пакеты хранятся в ArrayList<Packet>.Статический и нестатический доступ к значению

Я хочу получить доступ к значению id в static и non-static способами, например PacketClientConnecting.getStaticId() или packetArrayList.get(5).getId().

Как я могу это сделать без переопределения двух функций в каждом классе?

+0

В чем проблема, с которой вы столкнулись? –

+0

У вас есть список в базовом классе? – NINCOMPOOP

+0

Имеет ли параметр PacketClientConnecting.getStaticId() параметр? Каков его тип? Если getStaticId (x) просто возвращает x.getId(), вам не придется переопределять его. Но это просто предположение, поскольку я точно не знаю, чего вы пытаетесь достичь. – ajb

ответ

0

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

class Packet { 

    public static int getStaticId() { 
     return 1; 
    } 

    // This method is virtual and will be inherited without change 
    public int getId() { 
     try { 
      // Find and invoke the static method corresponding 
      // to the run-time instance 
      Method getStaticId = this.getClass().getMethod("getStaticId"); 
      return (Integer) getStaticId.invoke(null); 

     // Catch three reflection-related exceptions at once, if you are on Java 7+, 
     // use multi-catch or just ReflectiveOperationException 
     } catch (Throwable e) { 
      throw new RuntimeException(e); 
     } 
    } 
} 

Сейчас в подклассе все вам нужно, это определить getStaticId():

class PacketClientConnecting extends Packet { 
    public static int getStaticId() { 
     return 2; 
    } 
} 

Давайте проверить:

class Main { 
    public static void main(String[] args) { 
     // Both print 1 
     System.out.println(Packet.getStaticId()); 
     System.out.println(new Packet().getId()); 

     // Both print 2 
     System.out.println(PacketClientConnecting.getStaticId()); 
     System.out.println(new PacketClientConnecting().getId()); 
    } 
} 

Если вы хотите, чтобы избежать накладные расходы на вызов отражающих операций каждый раз, когда вы вызываете getId(), вы можете использовать поле в базовом классе для кэширования идентификатора:

class Packet { 

    public static int getStaticId() { 
     return 1; 
    } 

    private final int id = computeId(); 

    public int getId() { 
     return id; 
    } 

    // This method runs once per instance created 
    private int computeId() { 
     try { 
      Method getStaticId = this.getClass().getMethod("getStaticId"); 
      return (Integer) getStaticId.invoke(null); 
     } catch (Throwable e) { 
      throw new RuntimeException(e); 
     } 
    } 
} 
Смежные вопросы