jbu
jbu

Reputation: 16181

Java inheritance - added methods

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 ObjectOutputStreams 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

Answers (5)

Martin Lazar
Martin Lazar

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

Björn
Björn

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

Dan Vinton
Dan Vinton

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

Jens Schauder
Jens Schauder

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

stephendl
stephendl

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

Related Questions