20

假设我有以下类结构:

class Base {}
class A extends Base {}
class B extends Base {}
class C extends Base {}

我想编写方法,它接受AB的实例,但不接受C的实例。
我可以用Java实现吗?

我知道这不是很好的继承情况(AB应该有与C不同的共同父级),但我只是好奇用 Java 方式来处理这种情况。

编辑:
!!!
我知道更好的继承会解决问题。我只是好奇,如果 Java 有一些标准机制来解决这样的问题。
!!!

4

9 回答 9

43

使用一个接口A并且只有B实现它。

于 2012-12-21T12:47:22.310 回答
13

可以用接口吗?例如

class Base {}
interface MyGenericInterface {}
class A extends Base implements MyGenericInterface {}
class B extends Base implements MyGenericInterface {}
class C extends Base {}

这样,该方法可以接受 MyGenericInterface 的实现,并且由于 A 和 B 实现了接口但 C 没有实现,因此它将根据需要接受 A 和 B 的实例,但不接受 C。

于 2012-12-21T12:48:47.883 回答
8

如果某些东西应该接受AB但不是,C那么您应该重新考虑为什么C要从一开始继承Base。您可以添加额外的继承层:

   ---Base---
   |        |
--Sub--     C
|     |
A     B

然后你可以让你的方法只接受 type 的对象SubSub甚至不需要做任何事情,从技术上讲,它们都是Base

一个更快的解决方案将是一个肮脏的if( arg.instanceof(C) )...

于 2012-12-21T12:49:07.557 回答
8

您可以在运行时使用异常处理它:

void genericMethod(Base arg_in)
{
    if(arg_in instanceof C)
    {
        throw IllegalArgumentException("C class not accepted."); 
    }

    ...
    ...
}
于 2012-12-21T12:49:16.653 回答
8

不应该仅仅因为你想要这样的方法而改变类型层次结构。但是,如果您希望使用这种方法,则可能表明您应该考虑您的类型层次结构。

但是,如果您确定您的类型设计得很好,那么这种方法怎么样:

    public class T {

        public void doSomething(final A a) {
            doSomthing(a);
        }

        public void doSomething(final B b) {
            doSomthing(b);
        }

        private void doSomthing(final Base b) {

            // Here is the implementation

        }

    }
于 2012-12-21T13:11:13.483 回答
3

我想您的问题的答案是“不,java 没有处理此类问题的标准方法”。如果你有这个问题,那么你可以在这里查看其他答案,比如修复继承或使用MrSmith42 给出的聪明技术。

于 2012-12-21T13:16:54.993 回答
2

您可以使用它instanceof来检查对象是否属于某种类型。

当然,更好的想法是更好的继承结构。

于 2012-12-21T12:47:02.747 回答
2

泛型是为了类型安全。时期。不要“允许”或“禁止”任意事情。没有类型安全的理由来允许 A 和 B 而不是 C。

于 2012-12-21T19:48:00.377 回答
0

试试下面的片段

public <T extends Base> void setAuditorDetails(T model) 
{
         if(!(T instanceof C)){

              // Your Business logic

         }
}
于 2021-03-18T06:39:54.437 回答