Re: abstract static methods (again)
On Mon, 19 Oct 2009 11:37:07 -0700, Marcin Rze??nicki wrote:
On 19 Pa??, 19:53, Tomas Mikula <tomas.mik...@gmail.com> wrote:
Right but implementation of addition surely checks for this case,
doesn't it?
Not necessarily:
abstract class Vector<V extends Vector<V>> {
public V add(V v);
}
class Vector2D extends Vector<Vector2D> {
private final int x, y;
public Vector2D(int x, int y){ this.x = x; this.y = y; } public
Vector2D add(Vector2D v){
return new Vector2D(this.x + v.x, this.y + v.y);
}
}
No checking that the argument of addition has the correct type, because
this is enforced by the compiler.
Formal arguments have to be invariant with respect to overriding in
Java, you simply created method overload which will be used when
compiler is sure that runtime type of argument will be Vector2D. You
will still have to provide 'generic' add method.
No. Notice how add() is declared in Vector:
public V add(V v);
It works on type V.
When Vector2D is declared as
Vector2D extends Vector<Vector2D>,
Vector2D is substituted for V. So Vector2D's add() method is only
required to work on Vector2D instances. If Vector2D was declared as
Vector2D<V extends Vector<V>> extends Vector<V>,
then Vector2D would have to implement the add() method that takes any
subclass of Vector and returns the same subclass of Vector as it takes.
Your example does not
help either (or I cannot see how it would) because you will not be able
to dispatch on v's actual type unless you change how invokestatic works.
I'm not sure if I understand, but in the implementation of Vector2D V is
bound to Vector2D at compile time.
Yes, consider
public abstract class IOStream //for reading disk streams {
public abstract static boolean isReadable(File f) //returns true
for files which a concrete class can hopefully process. ...
}
public class LocalIOStream extends IOstream { public static boolean
isreadable(File f) { return f.isLocalFile(); } ...
}
public class AudioVideoStream extends LocalIOStream { ???
}
in AVStream you have, if I understood you correctly, two choices -
either to redo all work of super-classes which is not really an
option, let's say,
public static boolean isReadable(File f) { return f.isLocalFile() &&
(f instanceof AudioFile && ((AudioFile)f).getAudioCodecID().equals
(...);}
You don't have to redo the work, you can call the superclass's static
method as usual:
public static boolean isReadable(File f){
return LocalIOStream.isReadable(f) &&
f instanceof AudioFile &&
((AudioFile)f).getAudioCodecID().equals(...);
}
Yeah, right, but consider what happens when someone implements multiple
interfaces, or when inheritance tree changes, or when someone inherits
multiple interfaces with conflicting statics and so on.
Right now I can't think of any problems different from those with non-
static methods.
This example is
basically hand-crafted implementation of virtual dispatch :-)
...
Well, ok, but it does not change anything. Still you have to re-
implement invokevirtual by hand all the time :-)
Well, if you want to extend the behavior of a non-static method, you
still have to call the inherited method by hand (super.someMethod()) and
then do your specific work. This is no different from my example. The
only real disadvantage is when you want to inherit the method as is. Yes,
this is not possible with my proposal and you have to call the
superclass's method by hand. Though my proposal was targeted at uses
where you want to provide own implementation in each class. But I'm
finally getting what you are trying to say - that this feature might
encourage design that will later turn out as wrong. Yes, there might be
this danger, as is with many other features.
or omit it so then you impose different context. Namely, pretend to
be able to read remote files while you are not. And one more
question:
//client code
Stream s = new AudioVideStream(..);
read10Bytes(s);
public byte[] read10Bytes(Stream s) { if (!Stream.isReadable(file))
//how would you dispatch it? There is no way I suppose
}
This would be a compile-time error, since isReadable() is abstract in
Stream.
This is really bad :-) Then actually your statics will be usable only
when you know exact type you want to work with.
And with generics and with dynamic loading.