How do I finding the current static type?

B

Benno

Dear Java Gurus,

I need to find out what the static type (a.k.a. compile time type) of
a given object is at runtime[1]. What I want to achieve is this:

public interface ClassA { public void f(); }
public interface ClassB extends ClassA {}

ClassA classA;
ClassB classB = new ClassBImpl();
classA = classB;
classB.f(); // does something
classA.f(); // does something else

classB and classA are referencing the exact same object and on this
object f() is called but they should not do the same since the static
types are different (ClassA for classA and ClassB for classB).
So, ClassBImpl should look something like:

public class ClassBImpl implements ClassB {

public void f() {
if (
static type in caller of this
is proper subtype of ClassA
) {
//do something
} else {
//do something else
}
}
}

I'm sure you're wondering now why the heck he wants to do something
stupid like that. The reason is that I'm working on a Eiffel to Java
compiler at the moment and there are situations where the f() from
ClassA denotes a completely different method as the f() in ClassB,
they just have the same signature. I can't convince Java that they are
not the same and Java does therefore always bind dynamically to the
most recent implementation which may be the wrong one in some cases.
I'm thinking about this problem like for two weeks now and I'm
completely stuck. You'll make my month if you have any idea how to
solve it no matter how far fetched the idea may be.

Thanks for your time,
Benno

[1] I know, objects do not have a static type, what I mean is the type
of the last variable that was referencing that object.
 
M

Marcin Grunwald

Benno said:
Dear Java Gurus,

I need to find out what the static type (a.k.a. compile time type) of
a given object is at runtime[1]. What I want to achieve is this:

public interface ClassA { public void f(); }
public interface ClassB extends ClassA {}

ClassA classA;
ClassB classB = new ClassBImpl();
classA = classB;
classB.f(); // does something
classA.f(); // does something else

classB and classA are referencing the exact same object and on this
object f() is called but they should not do the same since the static
types are different (ClassA for classA and ClassB for classB).
So, ClassBImpl should look something like:

public class ClassBImpl implements ClassB {

public void f() {
if (
static type in caller of this
is proper subtype of ClassA
) {
//do something
} else {
//do something else
}
}
}

I'm sure you're wondering now why the heck he wants to do something
stupid like that. The reason is that I'm working on a Eiffel to Java
compiler at the moment and there are situations where the f() from
ClassA denotes a completely different method as the f() in ClassB,
they just have the same signature. I can't convince Java that they are
not the same and Java does therefore always bind dynamically to the
most recent implementation which may be the wrong one in some cases.
I'm thinking about this problem like for two weeks now and I'm
completely stuck. You'll make my month if you have any idea how to
solve it no matter how far fetched the idea may be.

Thanks for your time,
Benno

[1] I know, objects do not have a static type, what I mean is the type
of the last variable that was referencing that object.

You can't do something like that. You call method on object, type of
reference to that object doesn't matter.

I assume that you generate Java code from Eiffel so maybe try to generate
something little different:

public class ClassA { public static void f(ClassA obj) {} }
public class ClassB extends ClassA { public static void f(ClassB obj) {} }

ClassB classB = new ClassB();
ClassB.f(classB); // does something
ClassA.f(classB); // does something else

The same object (classB) and 2 different methods (ClassB.f(), ClassA.f()).
 
P

Patricia Shanahan

Benno said:
I'm sure you're wondering now why the heck he wants to do
something stupid like that. The reason is that I'm
working on a Eiffel to Java compiler at the moment and
there are situations where the f() from ClassA denotes a
completely different method as the f() in ClassB, they
just have the same signature. I can't convince Java that
they are not the same and Java does therefore always bind
dynamically to the most recent implementation which may
be the wrong one in some cases. I'm thinking about this
problem like for two weeks now and I'm completely stuck.
You'll make my month if you have any idea how to solve it
no matter how far fetched the idea may be.


The usual approach to this type of problem is to encode the
distinction in the method's identifier. That was, for
example, how C++ to C translators dealt with overloaded
function names in C++.

Patricia
 
J

John C. Bollinger

Benno said:
Dear Java Gurus,

I need to find out what the static type (a.k.a. compile time type) of
a given object is at runtime[1].

[moved up from later in the original post:]
[1] I know, objects do not have a static type, what I mean is the type
of the last variable that was referencing that object.

That is not an adequate definition of the property you want. There may
be multiple copies of the reference stored in variables of different
declared types at the same time.
What I want to achieve is this:

public interface ClassA { public void f(); }
public interface ClassB extends ClassA {}

ClassA classA;
ClassB classB = new ClassBImpl();
classA = classB;
classB.f(); // does something
classA.f(); // does something else

classB and classA are referencing the exact same object and on this
object f() is called but they should not do the same since the static
types are different (ClassA for classA and ClassB for classB).

It looks like what you really want is to choose a method to invoke based
on the type of a reference-type expression. You cannot achieve this
with virtual methods -- that's the whole point of them -- and all
non-static, non-private methods in Java are virtual.

[...]
I'm sure you're wondering now why the heck he wants to do something
stupid like that.

Yes, as a matter of fact I do.
The reason is that I'm working on a Eiffel to Java
compiler at the moment and there are situations where the f() from
ClassA denotes a completely different method as the f() in ClassB,
they just have the same signature. I can't convince Java that they are
not the same and Java does therefore always bind dynamically to the
most recent implementation which may be the wrong one in some cases.

It sounds like you are trying to convert Eiffel code into equivalent
Java code. I'd call software that performed that feat a "translator"
rather than a "compiler", but no matter. I know as much about Eiffel as
I was able to glean from ten minutes' study of this introduction:
http://archive.eiffel.com/doc/online/eiffel50/intro/language/invitation-00.html.
Nevertheless, I observe that Eiffel has static typing and dynamic
binding, just like Java. My only guess, then, as to why you want to do
what you asked is Eiffel's "feature renaming" ... err ... feature. But
this is not the only problem you have to overcome with class definition
and method dispatch, because Eiffel supports multiple inheritance of
implementation, whereas Java does not.
I'm thinking about this problem like for two weeks now and I'm
completely stuck. You'll make my month if you have any idea how to
solve it no matter how far fetched the idea may be.

You could use Java's static selection of method signatures to your
advantage here. Here's an example:

class ClassA { ... }
class ClassB extends ClassA {...}
class Foo {

void doSomething(ClassA arg) {
}
void doSomething(ClassB arg) {
}
void doIt() {
ClassB thingB = new ClassB();
ClassA thingA = thingB;

doSomething(thingB); // uses doSomething(ClassB)
doSomething(thingA); // uses doSomething(ClassA)
}
}

I don't think that gets you anywhere near where you need to be, however.
Given the inheritance and method name issues that present themselves,
I think you're going to need to provide your own method dispatch
mechanism, and possibly your own Java metaclass to represent Eiffel
classes. You are unlikely to be successful in an attempt to convert
arbitrary Eiffel classes directly into Java classes.
 
A

Anton Spaans

Benno said:
Dear Java Gurus,

I need to find out what the static type (a.k.a. compile time type) of
a given object is at runtime[1]. What I want to achieve is this:

public interface ClassA { public void f(); }
public interface ClassB extends ClassA {}

ClassA classA;
ClassB classB = new ClassBImpl();
classA = classB;
classB.f(); // does something
classA.f(); // does something else

classB and classA are referencing the exact same object and on this
object f() is called but they should not do the same since the static
types are different (ClassA for classA and ClassB for classB).
So, ClassBImpl should look something like:

public class ClassBImpl implements ClassB {

public void f() {
if (
static type in caller of this
is proper subtype of ClassA
) {
//do something
} else {
//do something else
}
}
}

I'm sure you're wondering now why the heck he wants to do something
stupid like that. The reason is that I'm working on a Eiffel to Java
compiler at the moment and there are situations where the f() from
ClassA denotes a completely different method as the f() in ClassB,
they just have the same signature. I can't convince Java that they are
not the same and Java does therefore always bind dynamically to the
most recent implementation which may be the wrong one in some cases.
I'm thinking about this problem like for two weeks now and I'm
completely stuck. You'll make my month if you have any idea how to
solve it no matter how far fetched the idea may be.

Thanks for your time,
Benno

[1] I know, objects do not have a static type, what I mean is the type
of the last variable that was referencing that object.

Example:
public interface MyClass { public void f(); }
public class ClassA implements MyClass { public void f() { /* do A */ }; }
public class ClassB implements MyClass { public void f() { /* do B */ }; }

public MyClassImplFactory
{
public static MyClass createImpl(some-parameters)
{
based-on-some-parameters-do-either:
return new ClassA();
or:
return new ClassB();
}
}

public static void main(String[] args)
{
MyClass classAorB =
MyClassImplFactory.createImpl(some-actual-parameters);
classAorB.f();
}

So, the decision which f() method will be actually executed later is made
when determining the values for the 'some-actual-parameters'.
This is a different approach. Would this work in your situation?
-- Anton.
 
P

P.Hill

Benno said:
public class ClassBImpl implements ClassB {

public void f() {
if (
static type in caller of this
is proper subtype of ClassA
) {
//do something
} else {
//do something else
}

Say what? This doesn't seem to match the verbal description
above. In Java since it is strongly typed, the reference in
the caller is always some subtype of ClassA "do something" is the only
path possible.

-Paul
 
P

P.Hill

Benno said:
Dear Java Gurus,
there are situations where the f() from
ClassA denotes a completely different method as the f() in ClassB,
they just have the same signature. I can't convince Java that they are
not the same and Java does therefore always bind dynamically to the
most recent implementation which may be the wrong one in some cases.

So, if the static analysis can determine the special situation where
you DONT want polymorphism and Java only has polymorphism, then you need
to munge the code to provide a different entry point for that special
case and use that different entry point when your code analysis says
you should.
So I have done the following:
1. Leave interfaces A and B the same (but dropping the "Class" from an
interface, that is just confusing, give it up!)
2. provided an implementation hook in the implementation of
AImpl and BImpl to get to each implementation:
a. used Patricia's suggestion of some type of name mangling
AND alternatively
b. used John's suggestion of
"use Java's static selection of method signatures"
then I can implement the following class which

public class OneThingAnother {
public static void main(String[] args) {
A a;
B b = new BImpl();
a = b;

((BImpl)b).fFromB(); // does something
((AImpl)a).fFromA(); // does something else

BImpl.f( b ); // does something
AImpl.f( a ); // does something else
}
}

Produces:
does something
does something else
does something
does something else

So I have invented two ways to do the same thing,
both of which contain a cast. Both are trivially
automatable transformations of the original code.

The trick is that all of these 'side door' methods
must have unique names in each Impl class, so they
don't get overwritten and these new methods need to be
able to get to the actual body regardless of overloaded
behavior, therefore, the real f() method and all of these special side
door methods all call a _private_ instance method fImpl(). We can't just
make fImpl public and call it, because it would become polymorphically
overridden at each level leaving us back in the same place we were
before if we had placed our implementation in f() and overrode it.

So if we want:
1. f() to be polymorhic and overridable
2. be able to insert some trick code to get a caller
to one particular implementation of f(),
3. A (super) doesn't know about B (Sub) in any of the interfaces or
classes.

My code uses classes of the form:

public class BImpl extends AImpl implements B {
/**
* Choice 1: Static entry to get to the implementation of f()
*/
public static void f( B b ) {
((BImpl)b).fImplB();
}

/**
* Choice 2: Dynamic name mangled entry to get to the implemenation
of f();
*
*/
public void fFromB() {
fImplB();
}

/**
* User entry point to f()
*/
public void f() {
fImplB();
}

/**
* The actual working body of f()
*/
private void fImplB() {
System.out.println( "does something");
}
}


The AImpl:

public class AImpl implements A {
public static void f( A a ) {
((AImpl)a).fImplA();
}

public void fFromA() {
fImplA();
}

public void f() {
fImplA();
}

private void fImplA() {
System.out.println( "does something else");
}
}

I'm assuming any class caste exceptions can be eliminated
at code analysis time of the calling class.

I'd be interested in what the Eiffel rules are
that cause some code to pick the none polymorphic
behavior.

Does anyone have any comments about the might be
the development impact, if I dropped the private method
and put the body in fFromA (and simply called it fA())?

Also, from the little I know AspectJ, this static analysis and
insertion sounds like a perfect job for AspectJ, but it
relies on specifying the right 'cut' when the
non-polymorphic should happen and I assume I can
move (rename?) an existing F() body to another method,
fImpl using AspectJ, but maybe that's a fantasy.

-Paul
 
B

Benno

P.Hill said:
Benno said:
Dear Java Gurus,
there are situations where the f() from
ClassA denotes a completely different method as the f() in ClassB,
they just have the same signature. I can't convince Java that they are
not the same and Java does therefore always bind dynamically to the
most recent implementation which may be the wrong one in some cases.

So, if the static analysis can determine the special situation where
you DONT want polymorphism and Java only has polymorphism, then you need
to munge the code to provide a different entry point for that special
case and use that different entry point when your code analysis says
you should.
So I have done the following:
1. Leave interfaces A and B the same (but dropping the "Class" from an
interface, that is just confusing, give it up!)
2. provided an implementation hook in the implementation of
AImpl and BImpl to get to each implementation:
a. used Patricia's suggestion of some type of name mangling
AND alternatively
b. used John's suggestion of
"use Java's static selection of method signatures"
then I can implement the following class which

public class OneThingAnother {
public static void main(String[] args) {
A a;
B b = new BImpl();
a = b;

((BImpl)b).fFromB(); // does something
((AImpl)a).fFromA(); // does something else

BImpl.f( b ); // does something
AImpl.f( a ); // does something else
}
}

Produces:
does something
does something else
does something
does something else

So I have invented two ways to do the same thing,
both of which contain a cast. Both are trivially
automatable transformations of the original code.

The trick is that all of these 'side door' methods
must have unique names in each Impl class, so they
don't get overwritten and these new methods need to be
able to get to the actual body regardless of overloaded
behavior, therefore, the real f() method and all of these special side
door methods all call a _private_ instance method fImpl(). We can't just
make fImpl public and call it, because it would become polymorphically
overridden at each level leaving us back in the same place we were
before if we had placed our implementation in f() and overrode it.

I can't inherit from AImpl in BImpl since I want to model multiple
inheritance. But of course name mangeling is a solution, but not a
nice one. Because the user of the generated Classes has to decide
which name denotes the right implementation in his situation, and in
Eiffel he does not have to think about that, the runtime chooses the
right implementation.
So if we want:
1. f() to be polymorhic and overridable
2. be able to insert some trick code to get a caller
to one particular implementation of f(),
3. A (super) doesn't know about B (Sub) in any of the interfaces or
classes.

My code uses classes of the form:

public class BImpl extends AImpl implements B {
/**
* Choice 1: Static entry to get to the implementation of f()
*/
public static void f( B b ) {
((BImpl)b).fImplB();
}

/**
* Choice 2: Dynamic name mangled entry to get to the implemenation
of f();
*
*/
public void fFromB() {
fImplB();
}

/**
* User entry point to f()
*/
public void f() {
fImplB();
}

/**
* The actual working body of f()
*/
private void fImplB() {
System.out.println( "does something");
}
}


The AImpl:

public class AImpl implements A {
public static void f( A a ) {
((AImpl)a).fImplA();
}

public void fFromA() {
fImplA();
}

public void f() {
fImplA();
}

private void fImplA() {
System.out.println( "does something else");
}
}

I'm assuming any class caste exceptions can be eliminated
at code analysis time of the calling class.

I'd be interested in what the Eiffel rules are
that cause some code to pick the none polymorphic
behavior.

See:
http://n.ethz.ch/student/bebaumga/secours/cowboy.pdf
for an example. If this example can be translated to Java (without
name mangling and the use of static) then I'll be fine. But I guess it
is realy not possible.

So as I see it I can either:
1. Use name mangling (maybe in combination with the static approach to
make it a bit more usable)
2. Extend the Java runtime and compile to a non standart JVM (belive
me: I will not do that)
Does anyone have any comments about the might be
the development impact, if I dropped the private method
and put the body in fFromA (and simply called it fA())?

Also, from the little I know AspectJ, this static analysis and
insertion sounds like a perfect job for AspectJ, but it
relies on specifying the right 'cut' when the
non-polymorphic should happen and I assume I can
move (rename?) an existing F() body to another method,
fImpl using AspectJ, but maybe that's a fantasy.

I had a quick look at the introduction at:

http://dev.eclipse.org/viewcvs/inde...ectj-home/doc/progguide/starting-aspectj.html

And it sounds promising. One can do something like multible
subclassing with AspectJ. I will investigate that further and keep you
informed if I find something usefull.

Benno
 
P

P.Hill

See:
http://n.ethz.ch/student/bebaumga/secours/cowboy.pdf
for an example. If this example can be translated to Java (without
name mangling and the use of static) then I'll be fine. But I guess it
is realy not possible.


Sorry, but since you have the change something. After all you are going
from one language to another, I'm not sure I understand your concern
about introducing new methods.

p i c t u r e s : LINKED LIST[PICTURE]
p i c t u r e s . extend ( a cowboy )

So what implementation of Picture is this supposed to be placed
in pictures when all you are providing is a Cowboy?

If the null arg constructor is sufficient then here is my solution:
1. generate an Eiffel-like substitute for a caste on multiple inherited
methods with rename using composite objects.
2. generate appropriate code for "rename draw as draw weapon"

public interface Cowboy {
void draw();
}
public class CowboyImpl extends EiffelObject implements Cowboy {
public void draw() {
System.out.println( "Draw Weapon");
}
}
where EiffelObject is:
class EiffelObject {
EiffelObject caste(Class clazz) {
// maybe this eactly right, since we might be dealing with
// subclass of Clazz
if ( this.getClass() == clazz ) {
return this;
}
throw new ClassCastException();
}

}
SIMILARLY FOR Picture and PictureImpl

Okay, so far all we've introduced is EiffelObject.

So here is the definition of CowboyPicture and its Impl
public interface CowboyPicture extends Picture {
void drawGun(); // Eiffel: rename draw as draw weapon
}

public class CowboyPictureImpl extends PictureImpl implements
CowboyPicture, Picture {
Cowboy c;
Picture p;

CowboyPictureImpl( Cowboy ac, Picture ap ) {
this.c = ac;
this.p = ap;
}

CowboyPictureImpl( Cowboy ac ) {
this( ac, new PictureImpl() );
}

CowboyPictureImpl( PictureImpl ap ) {
this( new CowboyImpl(), ap );
}

CowboyPictureImpl() {
this( new CowboyImpl(), new PictureImpl() );
}

// Eiffel: rename draw as draw weapon
public void drawGun() {
c.draw();
}

EiffelObject caste( Class clazz ) {
if ( clazz == Cowboy.class ) {
return (EiffelObject)c;
} if ( clazz == Picture.class ) {
return (EiffelObject)p;
}
throw new ClassCastException();
}
}

And now the code the is equivalent to
http://n.ethz.ch/student/bebaumga/secours/cowboy.pdf
page 23

public class Try {
public static void main(String[] args) {


CowboyPicture a_cowboy = new CowboyPictureImpl();

a_cowboy.draw();

// I'm not going to implement the generics version, so let's
try old fashion
// untyped with casts

LinkedList cowboys = new LinkedList();
LinkedList pictures = new LinkedList();
cowboys.add( a_cowboy );
Cowboy c = (Cowboy)((EiffelObject)(cowboys.get( 0 ))).caste(
Cowboy.class );
c.draw();

pictures.add( a_cowboy );
Picture p = (Picture)((EiffelObject)(pictures.get( 0 ))).caste(
Picture.class );
p.draw();
}
}


Using 1.5 Generics with our own Collection we could clean up the get
and make it,

Picture p = pictures.get( 0 );

but the operation would be equivalent down the replacement get method.

but I don't currently have a 1.5 installed.

-Paul
 
B

Benno

P.Hill said:
Sorry, but since you have the change something. After all you are going
from one language to another, I'm not sure I understand your concern
about introducing new methods.

I want to make it as easy to use as possible for the user. If the user
sees routines in a class like Af(), Bf(), Cf(), DCf()... which one
should he call? Which one is the right one in his situation? He has to
think realy hard about it each time he calls a routine.
p i c t u r e s : LINKED LIST[PICTURE]
p i c t u r e s . extend ( a cowboy )

So what implementation of Picture is this supposed to be placed
in pictures when all you are providing is a Cowboy?

If the null arg constructor is sufficient then here is my solution:
1. generate an Eiffel-like substitute for a caste on multiple inherited
methods with rename using composite objects.
2. generate appropriate code for "rename draw as draw weapon"

public interface Cowboy {
void draw();
}
public class CowboyImpl extends EiffelObject implements Cowboy {
public void draw() {
System.out.println( "Draw Weapon");
}
}
where EiffelObject is:
class EiffelObject {
EiffelObject caste(Class clazz) {
// maybe this eactly right, since we might be dealing with
// subclass of Clazz
if ( this.getClass() == clazz ) {
return this;
}
throw new ClassCastException();
}

}
SIMILARLY FOR Picture and PictureImpl

Okay, so far all we've introduced is EiffelObject.

So here is the definition of CowboyPicture and its Impl
public interface CowboyPicture extends Picture {
void drawGun(); // Eiffel: rename draw as draw weapon
}

public class CowboyPictureImpl extends PictureImpl implements
CowboyPicture, Picture {
Cowboy c;
Picture p;

CowboyPictureImpl( Cowboy ac, Picture ap ) {
this.c = ac;
this.p = ap;
}

CowboyPictureImpl( Cowboy ac ) {
this( ac, new PictureImpl() );
}

CowboyPictureImpl( PictureImpl ap ) {
this( new CowboyImpl(), ap );
}

CowboyPictureImpl() {
this( new CowboyImpl(), new PictureImpl() );
}

// Eiffel: rename draw as draw weapon
public void drawGun() {
c.draw();
}

EiffelObject caste( Class clazz ) {
if ( clazz == Cowboy.class ) {
return (EiffelObject)c;
} if ( clazz == Picture.class ) {
return (EiffelObject)p;
}
throw new ClassCastException();
}
}

And now the code the is equivalent to
http://n.ethz.ch/student/bebaumga/secours/cowboy.pdf
page 23

public class Try {
public static void main(String[] args) {


CowboyPicture a_cowboy = new CowboyPictureImpl();

a_cowboy.draw();

// I'm not going to implement the generics version, so let's
try old fashion
// untyped with casts

LinkedList cowboys = new LinkedList();
LinkedList pictures = new LinkedList();
cowboys.add( a_cowboy );
Cowboy c = (Cowboy)((EiffelObject)(cowboys.get( 0 ))).caste(
Cowboy.class );
c.draw();

pictures.add( a_cowboy );
Picture p = (Picture)((EiffelObject)(pictures.get( 0 ))).caste(
Picture.class );
p.draw();
}
}


Using 1.5 Generics with our own Collection we could clean up the get
and make it,

Picture p = pictures.get( 0 );

but the operation would be equivalent down the replacement get method.

but I don't currently have a 1.5 installed.

-Paul

"Casting" to the implementation object is a very interesting idea.
What do you think about something like:

public interface A {
public void f();
public Object downcast();
}

public class AImpl implements A {

private Object child;
public AImpl(Object child) {this.child = child;}

public void f() {System.out.println("Af");}
public Object downcast() {return child;}
}

public interface B extends A {
//rename f as g
//defines new f
public void g();

//"Casts"
public A asA();
}

public class BImpl implements B {

private AImpl aDelegate = new AImpl(this);

public void g() {aDelegate.f();}
public void f() {System.out.println("Bf");}

//"Casts"
public A asA() {return aDelegate;}
public Object downcast() {return null;}
}

And then use it like:

public static void main(String[] args) {
A a;
B b = new BImpl();
a = b.asA();
//a = b; valid but incorrect code
b.f(); //Bf
a.f(); //Af

b = (B) a.downcast();
b.f(); //Bf
}

If the user does the assignment right then it will work.

Benno
 
P

P.Hill

Benno said:
I want to make it as easy to use as possible for the user. If the user
sees routines in a class like Af(), Bf(), Cf(), DCf()... which one
should he call? Which one is the right one in his situation? He has to
think realy hard about it each time he calls a routine.

No he just calls f() (or draw in our case).
I am confised by your excessively generic naming.

"Casting" to the implementation object is a very interesting idea.
What do you think about something like:

It looks very simliar to my solution using delegation.
public interface B extends A {
//rename f as g
//defines new f
public void g();

//"Casts"
public A asA();
}
public class BImpl implements B {

private AImpl aDelegate = new AImpl(this);

public void g() {aDelegate.f();}
public void f() {System.out.println("Bf");}

//"Casts"
public A asA() {return aDelegate;}
public Object downcast() {return null;}
}

And then use it like:

public static void main(String[] args) {
A a;
B b = new BImpl();
a = b.asA();
//a = b; valid but incorrect code

It seems to me that you have confused yourself with overly
generic names. If A is a icture and B is a Cowboy
then

a = b
a.draw() get you picture.draw(), which is what I want if
I saw:
Picture a = b;
b.f(); //Bf
a.f(); //Af

b = (B) a.downcast();
b.f(); //Bf
}

If the user does the assignment right then it will work.

Yes, including in the case you were worried about.

-Paul
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,066
Latest member
VytoKetoReviews

Latest Threads

Top