Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/322.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
函数依赖于Java中未指定的类_Java_Generics_Inheritance - Fatal编程技术网

函数依赖于Java中未指定的类

函数依赖于Java中未指定的类,java,generics,inheritance,Java,Generics,Inheritance,如何在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 stuf

如何在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}
我试过了

  class A extends B{
    int var[];
     public static <C> void someFn(var, C Cclass){
        //initialize var;
        // Call fn(var, C1 or C2)
A类扩展B类{
int-var[];
公共静态void someFn(变量,C类){
//初始化var;
//呼叫fn(变量、C1或C2)

但这不起作用。我对Java还是有点陌生。我更希望不要重载
someFn

现在这只是伪代码的实现

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

使用泛型

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{}
公共A类扩展B类{
int-var[];
void someFn(int[]var,T){
this.var=var;
fn(var,t);
}
公共静态void main(字符串[]参数){
A=新的A();
int[]i={1,2};
C1=新的C1();
a、 someFn(i,c1);
C2=新的C2();
//a、 someFn(i,c2);//由于类型安全性的原因,这会给您带来复杂时间错误(好事情)
a2=新的A();
a2.someFn(i,c2);
}
}
B类{
无效fn(内部变量[],T c){
System.out.println(c.getClass().getName()+“func”);
/*Void甚至不能返回foo*/
}
}
类别C1{}
类C2{}
泛型类型 说(部分) 如果类声明了一个或多个类型变量(),则该类是泛型的

这些类型变量称为类的类型参数。类型参数部分位于类名之后,并用尖括号分隔

一个例子
void
函数无法返回值。但您可以这样做

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

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

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

那么您的
B
可能看起来像

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

假设您不想重载
someFn
(并且假设您不能将
C1
C2
作为同一父类的子类或实现同一接口,如Elliott的回答所示),我能看到的唯一方法是

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");
    }
}
(我假设由于
fn
在您的问题中不是静态的,因此必须有一个
B
类型的对象才能使用它;如果我的假设是错误的,请相应地修改代码。)


问题是,重载必须在编译时解决,而不是在运行时。也就是说,程序不能在运行时查看对象的类并决定调用两个
fn
中的哪一个。为了让编译器选择正确的一个,您必须告诉它您希望参数是哪个类。这就是cast到
(C1)
(C2)
可以。

为什么不直接重载
someFn()
?这是我最初的实现。我应该提到,如果我想更改
someFn
的其他部分,最好不要重载
someFn
。在
someFn
中,C1或C2的唯一用法是在调用fn(var、C1或C2)时使用谢谢,接口很好,我意识到我甚至不需要
类B
,因为
fn
的重载实例是其中唯一的东西,并且解决了我不想重载
someFn
的主要问题。
class B {
    void fn(int var[], C c1){
        c1.doSomething();
        return;
    }
}
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");
    }
}