【问题标题】:Java Generics - Bounded Type ParametersJava 泛型 - 有界类型参数
【发布时间】:2019-10-08 20:33:12
【问题描述】:

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

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()(根据本例)?

【问题讨论】:

  • 不,不使用当前的代码结构。两个 Childs 中的 sayBye 方法完全没有任何关系。他们同名的事实并不重要,这只是“巧合”。您需要将函数上移到 Base 类中,使其抽象化,然后在 Child 类中实现。
  • 为什么不让他们实现一个接口?
  • sayBye() 方法可用于ChildOne 及其子类;将签名更改为void genericFunction(ChildOne child)。或者,正如@MrHug 建议的那样,将您需要的方法放在接口中。
  • 是的,我知道如何通过接口和将代码抽象为基类等方式使其成为可能。但它们是不同包中的一些现有代码(基类),我不想碰它们。只是想知道是否有可能以其他方式制作。但无论如何,谢谢!
  • 那么答案是:没有

标签: java generics


【解决方案1】:

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

然后您可以更改泛型类型参数的类型绑定:

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

或者没有泛型:

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

【讨论】:

    【解决方案2】:

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

    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);
    }
    

    【讨论】:

      【解决方案3】:

      一种方法是将基类标记为抽象并具有抽象方法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();
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-10-06
        • 1970-01-01
        • 2012-08-15
        • 1970-01-01
        • 2012-01-23
        • 1970-01-01
        相关资源
        最近更新 更多