2015-05-01 2 views
2

Может ли подкласс класса Java и InputStream и OutputStream?Подкласс как InputStream, так и OutputStream

Я хотел бы иметь возможность расширять оба этих класса, если это возможно.

+0

Nope. Это невозможно. Если вы хотите предоставить единый интерфейс для обеих операций в вашем коде, напишите утилиту, которая зависит от обоих этих потоков и предоставит API пользователю. – K139

+0

В качестве примера обходного пути, java.net.Socket имеет метод getInputStream() и метод getOutputStream(). – Nayuki

+0

Печально InputStream и OutputStream не являются интерфейсами –

ответ

4

Java does not support multiple inheritance, поэтому вы не можете расширить несколько классов. Однако вы можете реализовать несколько интерфейсов.

Для чего вы пытаетесь сделать, вы хотите использовать композицию вместо наследования. Таким образом, ваш класс будет иметь экземпляр InputStream и OutputStream, и вы можете делегировать поведение каждому из них в зависимости от того, что вы хотите сделать.

Почему состав? Наследование обычно является первым, на что люди стремятся, хотя то, что они хотят сделать, - это использовать поведение родительского класса. Для множественного наследования обычно они хотят иметь доступ к поведению двух или более классов. Например, вам нужен класс C, который делает вещи класса Aи вещи, которые класс B делает. С точки зрения типа, наследование является отношением «является». Если вы скажете SubClass extends ParentClass, вы говорите, что SubClass по существу ParentClass по типу, и что вы можете заменить экземпляры ParentClass на SubClass, и ваша программа по-прежнему будет по существу правильной. Это называется Liskov Substitution Principle. Вы можете видеть, что создание класса, которое расширяет и InputStream, и OutputStream - это класс, который имеет оба поведения, но не строго тот или другой. Очень маловероятно, что вы сможете заменить экземпляры обоих экземпляром своего класса и ожидать, что все будет работать «правильно». Поэтому вам нужно подумать о том, что вы действительно хотите сделать. Если вы не заботитесь о внутренностях класса, о котором вы хотите расширить, но вы просто хотите использовать его поведение (или каким-то образом изменить его поведение), тогда вы можете сохранить его внутренний экземпляр и делегируйте это, делая какие-либо изменения в поведении, которое вам нужно.

Так что в вашем случае вы хотите получить доступ к поведению ввода-вывода обоих классов. Следовательно, вы можете просто поддерживать внутренние экземпляры, а затем предоставлять API из своего класса, который делегирует соответствующие методы для обоих экземпляров. Преимущество здесь - абстракция и инкапсуляция. Никто, кто использует ваш класс и его API, не знает, как он обрабатывает I/O внутри, и им не нужно знать; это деталь реализации. Кроме того, если вы хотите изменить внутреннюю реализацию в будущем, вы можете сделать это легко, так как единственный интерфейс для вашего класса - через общедоступный API. Пока вы не изменяете поведение и не нарушаете контракт своего API, вы можете изменить внутреннюю реализацию, как хотите.

5

И InputStream, и OutputStream являются классами (не интерфейсами). Java не поддерживает множественное наследование, поэтому невозможно подклассифицировать их напрямую.

Однако, используя композицию, вы можете иметь поведение от этих двух классов в одном классе.

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