OO Design - which is better?

I’m creating a buffer object helper class which is usable by a user with little or no knowledge of OpenGL. I have a helper class for creating and handling buffers called NIOBuffer. No solution is going to be pretty but I’m wondering which solution would be best. The first problem is how to deal with inheritance as you cannot pass Buffer to e.g glBufferData - I could either:

    1. Eliminate inheritance and create five different classes for each data type.
    1. Cast to the correct buffer type.

I’d assume the latter is preferred for ease of use purposes but for design purposes they’re both ugly. Now lets consider the actual design of that. Here I have one of three choices:

    1. Hold the buffer data as the data type Buffer, like so:

public class BufferObject extends NIOBuffer {

	private int id;
	private int target;
	private int usage;

	public BufferObject(int target, Buffer buffer, int usage) {
		super(buffer);
		this.id = glGenBuffers();
		this.target = target;
		this.usage = usage;
	}

	//...
}
public class NIOBuffer {

	public Buffer data;

	public NIOBuffer(Buffer buffer) {
		data = buffer;
	}

	//...
}

Pros:
Easy to read
Cons:
Type-unsafe (doesn’t accept LongBuffer)

[li]2. This is pretty much thrown in as an opportunity to use generics which some would say is better OOD, but I could make the buffer type generic which would still require casting:


public class BufferObject<T extends Buffer> extends NIOBuffer<T> {

	private int id;
	private int target;
	private int usage;

	public BufferObject(int target, T buffer, int usage) {
		super(buffer);
		this.id = glGenBuffers();
		this.target = target;
		this.usage = usage;
	}

	//...
}
public class NIOBuffer<T extends Buffer> {

	public T data;

	public NIOBuffer(T buffer) {
		data = buffer;
	}

	//...
}

Pros:
Easy to read
Cons:
Not fully type-safe (again LongBuffer)

    1. Use multiple static nested classes and make it fully type-safe.

public class BufferObject<T extends NIOBuffer<?>> {

	private int id;
	private int target;
	private int usage;
	private T buffer

	public BufferObject(int target, T buffer, int usage) {
		this.id = glGenBuffers();
		this.target = target;
		this.usage = usage;
		this.buffer = buffer;
	}

	//...
}
public class NIOBuffer<T extends Buffer> {

	public T data;

	public NIOBuffer(T buffer) {
		data = buffer;
	}

		public static class NIOByteBuffer extends NIOBuffer<ByteBuffer> {

			public NIOByteBuffer(ByteBuffer buffer) {
				super(buffer);
			}

		}

		// other classes...

	}
}

Pros:
Type-safe
Cons:
Hard to read?

And then here is how I would have to cast everything (prepare to throw up):

Fields:


private Class<ByteBuffer> byteType = null;
private Class<ShortBuffer> shortType = null;
private Class<IntBuffer> intType = null;
private Class<FloatBuffer> floatType = null;
private Class<DoubleBuffer> doubleType = null;

In my constructor I’d have to add:


if(buffer.data instanceof ByteBuffer) {
	byteType = (Class<ByteBuffer>) buffer.data.getClass();
} else if(buffer.data instanceof ShortBuffer) {
	shortType = (Class<ShortBuffer>) buffer.data.getClass();
} else if(buffer.data instanceof IntBuffer) {
	intType = (Class<IntBuffer>) buffer.data.getClass();
} else if(buffer.data instanceof FloatBuffer) {
	floatType = (Class<FloatBuffer>) buffer.data.getClass();
} else if(buffer.data instanceof DoubleBuffer) {
	doubleType = (Class<DoubleBuffer>) buffer.data.getClass();
} else {
	throw new IllegalStateException(buffer.data.getClass().toString());
}

For a single OpenGL function…


if(byteType != null) {
	glBufferData(target, (byteType.cast(buffer.data)), usage);
} else if(shortType != null) {
	glBufferData(target, (shortType.cast(buffer.data)), usage);
} else if(intType != null) {
	glBufferData(target, (intType.cast(buffer.data)), usage);
 else if(floatType != null) {
	glBufferData(target, (floatType.cast(buffer.data)), usage);
} else if(doubleType != null) {
	glBufferData(target, (doubleType.cast(buffer.data)), usage);
}

So… have fun answering. Please give some other design alternatives too. Oh and if anyone has any better methods of casting stuff please post them below. This is just what I could think from off the top of my head.