db1234
db1234

Reputation: 807

Have a function depend on an unspecified class in Java

How do I implement the following pseudo-code 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 that did not work. I am still sorta new to Java. I would prefer to not overload someFn

Upvotes: 3

Views: 635

Answers (3)

Shahzeb
Shahzeb

Reputation: 4785

Now this is simply the implementation of your pseudo code

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{}

Upvotes: 2

ajb
ajb

Reputation: 31699

Assuming you don't want to overload someFn (and assuming you can't make C1 and C2 subclasses of 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'm assuming that since fn isn't static in your question, you have to have an object of type B to use it on; if my assumption is wrong, modify the code accordingly.)

The thing is, overloads have to be resolved at compile time, not run time. That is, the program cannot, while it's running, look at an object's class and decide which of the two fn's to call. In order for the compiler to pick the correct one, you have to tell it which class you're expecting the parameter to be. That's what the cast to (C1) or (C2) does.

Upvotes: 0

Elliott Frisch
Elliott Frisch

Reputation: 201497

Generic types

JLS-8.1.2. Generic Classes and Type Parameters says (in part)

A class is generic if it declares one or more type variables (§4.4).

These type variables are known as the type parameters of the class. The type parameter section follows the class name and is delimited by angle brackets.

An Example

A void function can't return a value. But you could do

class A<T> extends B<T> {
}

class B<T>{
    void fn(int var[], T c1){
        return;
    }
}

An Interface

JLS Chapter 9. Interfaces says (in part)

An 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 its abstract methods.

Program to a common C interface and you can avoid generic types.

interface C {
   void doSomething();
}

with C1 and C2 like

class C1 implements C {
   void doSomething() {
      // do something
   }
}

and

class C2 implements C {
   void doSomething() {
      // do something else
   }
}

Then your B might look like

class B {
    void fn(int var[], C c1){
        c1.doSomething();
        return;
    }
}

Upvotes: 1

Related Questions