Reputation: 16181
I want to have a base class, BaseConnect
, which contains an OutputStream
and children classes ObjectStreamConnect
and DataStreamConnect
. In my BaseConnect
class I have OutputStream os;
And in my Two children classes I have the constructors that do "os = ObjectOutputStream(...)
" or "os = DataOutputStream(...)
", respectively.
Since ObjectOutputStream
s have a writeObject(Object o)
method and DataOutputStreams
do not, it seems that I cannot have my ObjectStreamConnect
class do a "os.writeObject(object)
" since the parent class, OutputStream
, does not have writeObject(Object o)
.
I'm sure this is code-smelly, and I'm wondering how to handle it.
My thoughts:
I thought of making the method that contains os.writeObject
abstract, so that ObjectStreamConnect
could implement it differently, but then I realized that DataStreamConnect
would also have to implement it, which it does not need to.
I also do not want to just get rid of the parent and have the two classes implement everything separately, because they do have a lot of the same methods with the same implementations.
Please help. For some reason, the answer to this problem is not coming to me.
jbu
edit: I can't paste entire code but it goes something like this:
public class BaseConnect {
OutputStream os;
...
}
public class ObjectStreamConnect extends BaseConnect {
public ObjectStreamConnect () {
...
os = new ObjectOutputStream(socket.getOutputStream);
}
public void writeObject(Object o) {
os.writeObject(o);
}
}
public class DataStreamConnect extends BaseConnect {
public DataStreamConnect () {
...
os = new DataOutputStream(socket.getOutputStream);
}
}
Upvotes: 0
Views: 341
Reputation: 1340
If I understand the probleam correctly, you should have the BaseConnect class declared as abstract with the common behavior encapsulated in it. The problematic method writeObject should be declared as abstract as well and you should leave it up to the concrete implementation in a subclass how it manages the desired goal.
Then in the ObjectStreamConnect you can test the type of the stream with instanceof operator, then convert the object to ObjectOutputStream and then you can use the os.writeObject(o) with no probleam.
In the DataStreamConnect you have to implement this method another way.
I mean something like this:
public abstract class BaseConnect {
protected OutputStream os;
...
public abstract void writeObject(Object o);
// common behavior implemented in this class
}
public class ObjectStreamConnect extends BaseConnect {
public ObjectStreamConnect () {
...
os = new ObjectOutputStream(socket.getOutputStream);
}
public void writeObject(Object o) {
if (os instanceof ObjectOutputStream) {
((ObjectOutputStream) os).writeObject(o);
} else {
// throw some exception here or something, because this should not happen
}
}
}
public class DataStreamConnect extends BaseConnect {
public DataStreamConnect () {
...
os = new DataOutputStream(socket.getOutputStream);
}
public void writeObject(Object o) {
// implement writing of the object in another way here
}
}
Maybee you should also rename the BaseConnect to AbstractConnect, but this depends on your code conventions.
Upvotes: 0
Reputation: 29401
You should use an interface to declare the shared vital methods of the two classes. You shouldn't care about future sub-implementation in a base class - it's against the OO-law! Or do you just want a base class so you don't have to write duplicate code? Use an interface and a helper class, as DanVinton suggested.
Upvotes: 0
Reputation: 26769
What you seem to be saying is "my two objects use some shared methods, and I'm sharing them through inheritance of a superclass".
Then you get stuck because inheritance actually says "this is one of these, and so has this API" when it isn't - as your difficult-to-implement method suggests.
If you put the shared methods in some sort of helper class, and supply both DataStreamConnect
and OutputStreamConnect
with an instance of the helper, you can share the support code without having to share the same API.
Upvotes: 4
Reputation: 81998
If you are using java 1.5 or above you can us a generic class:
public class Base<T extends OutputStream>{
T os;
...
}
public class OutputStreamConnect extends Base<ObjectOutputStream>
public OutputStreamConnet(){
os = new ObjectOutputStream();
}
public void doWrite(Object o){
os.writeObject(o);
}
}
Upvotes: 1
Reputation: 722
Can you just have one abstract method on OutputStream
write(Object o)
(I'm guessing that you can 'write' to both sub-classes) and both subclasses implement it in their own way?
Upvotes: 0