如何在Java中使用接受扩展接口类型参数的函数来创建接口?

时间:2019-02-21 14:14:55

标签: java interface

我如何在Java中使用接受扩展接口类型参数的函数来创建接口?

例如,使用接口ISelfComparable

如果A类对其进行了扩展,那么我希望它能够实现

bool compareTo(A other)

但是如果类B扩展了它,那么我希望它能够实现

bool compareTo(B other)

我知道我可以使用通用接口,但似乎不正确,因为A扩展ISelfComparable

没有任何意义。

如果这不可能,那么在这种情况下的最佳实践是什么?

3 个答案:

答案 0 :(得分:1)

通常的解决方案是自约束泛型,如Enum类中所示。

interface Example<T extends Example<T>> {
    void foo(T t);
}

public class ExampleImpl implements Example<ExampleImpl> {
    @Override
    public void foo(ExampleImpl example) {
    }
}

它的工作原理有点令人头晕,但是例如here的解释很好。在here主题上也有很好的答案。

请注意,它并非万无一失,因为它允许这样做:

public class ExampleImpl2 extends Example<ExampleImpl {
    @Override
    public void foo(ExampleImpl example) {

    }
}

但是在实践中,自我约束的习语用于表达您所追求的事物。

如果确实确实需要参数对象始终与this完全相同,则必须进行运行时检查。 (这也引发了一个问题,为什么您需要它,但这会使我们脱离话题。)

答案 1 :(得分:0)

看看类java.lang.Comparable:它有一个参数,该参数带有可以在compareTo中使用的对象的类型。

比喻:

public interface ISelfComparable<T extends ISelfComparable<T>> {
    boolean compareTo(T other);
}

答案 2 :(得分:0)

有一种方法可以检查参数的类型,但只能在运行时检查。例如,您可以在默认方法中实现类型检查:

List<Fragment>

然后,此接口的每个实现应如下所示:

instantiateItem(ViewGroup container, int position)

在这种情况下,如果您致电public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //Attach the SectionsPagerAdapter to the ViewPager SectionsPagerAdapter pagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager()); ViewPager viewPager = findViewById(R.id.viewPager); viewPager.setAdapter(pagerAdapter); } // // //Adapter class private class SectionsPagerAdapter extends FragmentPagerAdapter { private static final int PAGE_HOME = 0; private int tabCount = 1; private List<Fragment> fragmentList = new ArrayList<>(); private List<String> fragmentTitleList = new ArrayList<>(); //private FragmentManager fragmentManager; SectionsPagerAdapter(FragmentManager fm) { super(fm); //fragmentManager = fm; //Default HomeFragment HomeFragment homeFragment = new HomeFragment(); //Callback interface homeFragment.setOnCategoryFragmentChangedListener(new HomeFragment.OnCategoryFragmentChangedListener() { //This method will be called when a button in HomeFragment is clicked @Override public void onAddNewCategory(String categoryName) { addNewCategory(categoryName); } }); fragmentList.add(homeFragment); fragmentTitleList.add("Home"); } @Override public Fragment getItem(int position) { return fragmentList.get(position); } @Override public int getCount() { return tabCount; } @Override public CharSequence getPageTitle(int position) { return fragmentTitleList.get(position); } @Override public Object instantiateItem(ViewGroup container, int position) { fragmentList.set(position, (Fragment) super.instantiateItem(container, position)); return fragmentList.get(position); } private void addNewCategory(String categoryName) { CategoryFragment fragment = new CategoryFragment(); tabCount += 1; fragmentList.add(fragment); fragmentTitleList.add(categoryName); notifyDataSetChanged(); } } } ,则会抛出interface ISelfComparable { default boolean compareTo(ISelfComparable param) { if (this.getClass() != param.getClass()) { throw new IllegalArgumentException(); } ... } }