繁体   English   中英

Java泛型-有界类型参数

[英]Java Generics - Bounded Type Parameters

让我用一个例子来描述我的意图,

class Base {
  public void sayHi() {
    System.out.println("Hi");
  }
}

class ChildOne extends Base {
  public void sayBye() {
    System.out.println("Bye-1");
  }
}

class ChildTwo extends Base {
  public void sayBye() {
    System.out.println("Bye-2");
  }
}

public class MainClass {
  public static <T extends Base> void genericFunction(T child) {
    child.sayBye();
  }

  public static void main(String[] args) {
    ChildOne childOne = new ChildOne();
    ChildTwo childTwo = new ChildTwo();
    genericFunction(childOne);
    genericFunction(childTwo);
  }

}

该代码是错误的。 但是我的意图是子类(项目中某些已经存在的类)在它们之间具有相似的属性,即它们扩展了基类并具有sayBye()成员函数。

有没有一种方法可以将所有子类作为参数传递给泛型函数并调用成员函数sayBye()(根据本示例)?

当然,您可以为所有具有sayBye方法的类创建公共基类或公共接口。

然后,您可以更改通用类型参数的类型界限:

public static <T extends CommonInterface> void genericFunction(T child) {
    child.sayBye();
}

或没有泛型:

public static void nonGenericFunction(CommonInterface child) {
    child.sayBye();
}

您可以通过引入定义通用接口的接口并创建扩展通用对象的空类来将通用功能组合在一起而无需调整层次结构。

class Base {
    public void sayHi() {
        System.out.println("Hi");
    }
}

class ChildOne extends Base {
    public void sayBye() {
        System.out.println("Bye-1");
    }
}

class ChildTwo extends Base {
    public void sayBye() {
        System.out.println("Bye-2");
    }
}

// The common functionality I want to use.
interface Bye {
    public void sayBye();
}

class ChildOneBye extends ChildOne implements Bye {
    // Don't need anything here.
}

class ChildTwoBye extends ChildTwo implements Bye {
    // Don't need anything here.
}

public static <T extends Bye> void genericFunction(T child) {
    child.sayBye();
}

public void test(String[] args) {
    Bye childOne = new ChildOneBye();
    Bye childTwo = new ChildTwoBye();
    genericFunction(childOne);
    genericFunction(childTwo);
}

一种方法是将基类标记为抽象,并使用抽象方法sayBye() 这样,您无需在代码库中进行任何其他更改。

abstract class Base {
    public void sayHi() {
        System.out.println("Hi");
    }

    public abstract void sayBye();
}

另一种方法是使用接口ByeInterface并使用它来调用sayBye() 这是带有所需更改的。

interface ByeInterface {
   void sayBye();
}

class Base {
   public void sayHi() {
   System.out.println("Hi");
  }
}

 class ChildOne extends Base implements ByeInterface {
 public void sayBye() {
     System.out.println("Bye-1");
  }
}

  class ChildTwo extends Base implements ByeInterface {
  public void sayBye() {
     System.out.println("Bye-2");
 }
}

public class MainClass {
    public static <T extends ByeInterface> void genericFunction(T child) {
    child.sayBye();
 }

   public static void main(String[] args) {
       ChildOne childOne = new ChildOne();
       ChildTwo childTwo = new ChildTwo();
       genericFunction(childOne);
       genericFunction(childTwo);
   }

 }

如果无法将基类标记为抽象类,则可以使用此方法。 使用接口,甚至可以在不使用泛型的情况下调用它。

public static void nonGenericFunction(ByeInterface child) {
    child.sayBye();
}

在基类中包括sayBye() ,因为当您扩展< T extends Base>到泛型函数时; 表示从基类或基类本身派生的任何Type类。 在此失败,就好像您将基类对象作为参数提供一样,它也会失败。 因此,要修复此问题,您可以在基础中添加相同的功能以使其工作..!

class Base {
       public void sayHi() {
        System.out.println("Hi");
     }

    public void sayBye() {
        System.out.println("Bye-base");
    }
 }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM