2013-03-12 2 views
0

Я пытаюсь разработать интерфейсы и классы для анализа некоторых типов пакетов внутри файла формата pcap. (Я знаю, что существуют специальные библиотеки, но мне нужно сделать это самостоятельно)Дженерики, необходимые для расширения/реализации этих интерфейсов?

Итак, у меня есть интерфейс классификатора, метод будет проверять, является ли он действительным пакетом.

public interface Classifier { 
    boolean classify (PcapPacket pcapPacket); 
} 

Метод интерфейса анализатор может преобразовать массив байтов внутри PcapPacket в некоторых областях. P означает новый анализируемый пакет и S для статистики.

public interface Parser<P, S> extends Classifier { 
    P parsePacket (PcapPacket pcapPacket); 
    P parsePacket (PcapPacket pcapPacket, P outPacket); 
    S parseReader (PcapReader pcapReader); 
} 

Теперь я реализовал AParser, который может анализировать определенный пакет или файл.

public class AParser implements Parser<APacket, AStats>, Classifier { 

Но теперь у меня возникли трудности для реализации BParser на вершине AParser, учитывая, что BPacket extends APacket.

public class BParser extends AParser implements Parser<BPacket, BStats> {

В parsePacket я хочу сделать что-то вроде этого:

BPacket parsePacket (PcapPacket pcapPacket) { 
    APacket apacket = super.parse(pcapPacket); 
    BPacket bpacket = new BPacket(apacket); 

    //extract val1 and val2 from pcapPacket 
    bpacket.set(val1, val2); 
    return bpacket; 
} 

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

Как вы мне поможете переделать этот код, чтобы он работал и гибким в будущем?

+0

Моя первая мысль изменить Parser так, что она определена в терминах двух других интерфейсов, Packet и статистика, а не с точки зрения конкретных классов. Тогда не обязательно было бы быть общим, и APacket и BPacket и AStats и BStats просто должны были бы реализовать Packet и Stats. Но я не достаточно знаком с pcap, чтобы узнать, возможно ли это. –

+0

@DavidConrad, но для пакета я не могу думать об обобщении. У них могут быть совершенно разные поля. –

+0

Но есть ли у них и другое поведение? Просто потому, что они имеют разные внутренние элементы, это не значит, что они не могут реализовать один и тот же интерфейс (подумайте о ArrayList и LinkedList, которые оба реализуют List, с совершенно разными реализациями), но если они имеют разное поведение, то они не только не смогут реализовать тот же интерфейс, они не могут наследовать друг от друга! –

ответ

1

Да, дженерики и подклассы не играют вместе так. Вы уже объявили специализацию вашего парсера (AParser), который связывает свой общий параметр с данным объектом (APacket). Затем вы не можете перейти от этой специализации к другому набору общих параметров. Его, как вы пытаетесь сделать это:

public class BParser implements Parser<APacket, AStats>, Parser<BPacket, BStats> { 

, который не будет работать, так как тип стирания означает, у вас есть несколько методов, которые переводят к одной и той же подписи. Более жизнеспособное решение будет слишком толкать общую функциональность для ваших специализированных парсеров в абстрактный базовый класс, который не связывает общие параметры с определенным типом. Иллюстрированный с псевдокоде:

public abstract class BaseParser<P, S> implements Parser<P, S> { 
    // common functionality here 
} 

public class AParser extends BaseParser<APacket, AStats> { 
    // functionality specific to AParser 
} 

public class BParser extends BaseParser<BPacket, BStats> { 
    // functionality specific to BParser 
} 
+0

нормально ли смешивать интерфейсы и абстрактные классы? –

+0

и было бы лучшим решением, чем дженерики? –

+0

@NikolayKuznetsov - нет ограничений на то, как вы можете смешивать и сопоставлять интерфейсы и абстрактные классы, если эти комбинации не приводят к нарушениям спецификации Java. И это решение все еще использует generics, оно просто использует их законным (компилируемым) способом. – Perception

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