Function depends on unspecified class in Java
How to implement the following pseudocode in Java:
class A extends B{
int var[];
void someFn(var, WANT TO INPUT EITHER a C1 or C2 CLASS HERE){
//initialize var;
// Call fn(var,C1 or C2)
public static void main(String[] arguments){
///main stuff
}
}
class B{
void fn(int var[], C1 c1){return foo;}
void fn(int var[], C2 c2){return other foo;}
}
class C1{stuff here}
class C2{other stuff here}
I tried
class A extends B{
int var[];
public static <C> void someFn(var, C Cclass){
//initialize var;
// Call fn(var, C1 or C2)
But it didn't work. I am still new to Java. I would rather not overloadsomeFn
source to share
Common types
JLS-8.1.2. General classes and type parameters (partially)
A class is generic if it declares one or more type variables ( ยง4.4 ).
These type variables are known as class type parameters. The type parameter section follows the class name and is separated by angle brackets.
Example
FunctionA void
cannot return a value. But you could do
class A<T> extends B<T> {
}
class B<T>{
void fn(int var[], T c1){
return;
}
}
Interface
JLS Chapter 9. Interfaces says (in part)
The interface declaration introduces a new reference type whose members are classes, interfaces, constants, and abstract methods. This type has no implementation, but otherwise unrelated classes can implement it by providing implementations for their abstract methods.
The program is for a generic interface C
, and you can avoid generic types.
interface C {
void doSomething();
}
with C1
and C2
how
class C1 implements C {
void doSomething() {
// do something
}
}
and
class C2 implements C {
void doSomething() {
// do something else
}
}
Then yours B
might look like
class B {
void fn(int var[], C c1){
c1.doSomething();
return;
}
}
source to share
Now this is just an implementation of your pseudocode
package com.so;
public class A extends B{
int var[];
void someFn(int[] var, Object object){
this.var = var;
if (object instanceof C1){
fn(var,(C1) object);
}
else if (object instanceof C2){
fn(var,(C2) object);
}
}
public static void main(String[] arguments){
A a = new A();
int[] i = {1,2};
C1 c1 = new C1();
a.someFn(i, c1);
}
}
class B{
void fn(int var[], C1 c1){
System.out.println("C1 func");
/*Void can not return even foo*/
}
void fn(int var[], C2 c2){
System.out.println("C2 func");
/*Void can not return even other foo either*/
}
}
class C1{}
class C2{}
Using generics
public class A<T> extends B<T>{
int var[];
void someFn(int[] var, T t){
this.var = var;
fn(var,t);
}
public static void main(String[] arguments){
A<C1> a = new A<C1>();
int[] i = {1,2};
C1 c1 = new C1();
a.someFn(i, c1);
C2 c2 = new C2();
//a.someFn(i, c2); //This will give you complie time error because of typesafety (good thing)
A<C2> a2 = new A<C2>();
a2.someFn(i, c2);
}
}
class B<T>{
void fn(int var[], T c){
System.out.println(c.getClass().getName() +"func");
/*Void can not return even foo*/
}
}
class C1{}
class C2{}
source to share
Assuming you don't want to overload someFn
(and assuming you cannot subclass C1
and C2
the same parent class, or implement the same interface as in Elliott's answer), the only way I can see is something like
void someFn(Whatever var, Object c) {
if (c instanceof C1) {
b.fn(var, (C1)c);
} else if (c instanceof C2) {
b.fn(var, (C2)c);
} else {
throw new RuntimeException("Invalid object passed to someFn");
}
}
(I am assuming that since fn
it is not static in your question, you must have an object of type B
in order to use it, if my assumption is wrong, change the code accordingly.)
The point is that overloads must be resolved at compile time, not at runtime. That is, the program cannot, while it is running, look at the class of the object and decide which of the two fn
to call. In order for the compiler to pick the right one, you must tell which class you expect from the parameter. What makes the listing (C1)
or (C2)
.
source to share