【问题标题】:Abstract method restriction control for derived classes派生类的抽象方法限制控制
【发布时间】:2013-03-14 07:56:10
【问题描述】:

抽象基类是否有可能拥有只有某些派生类才能访问某些抽象方法的抽象方法?我正在尝试做的是限制能够从不同的继承类调用的可能方法。这是我的问题的一个例子:

public abstract Foo
{
    ...
    public abstract void fooMethod1(int num1);
    public abstract void fooMethod2(int num2);
}

public Bar1 extends Foo // This class shouldn't be able to access fooMethod2()
{
    ...
    @Override
    public void fooMethod1(int num1)
    {
        System.out.println((num1 * 5));
    }
}

public Bar2 extends Foo // This class has no restrictions
{
     ...
     @Override
     public void fooMethod1(int num1)
     {
          System.out.println((num1 * 10));
     }

     @Override
     public void fooMethod2(int num2)
     {
          System.out.println((num2 * 5));
     }

【问题讨论】:

  • 除私有变量外,如果子类扩展了超类,则它可以访问超类的所有成员。
  • 可能fooMethod2方法不属于Foo
  • 为什么要这样做?

标签: java class abstract


【解决方案1】:

必须在每个子类中重写所有公共抽象方法。 你可以做什么:

  1. Foo抽象类拆分为两个类:BaseFooExtendedFoo,其中ExtendedFoo应该扩展BaseFoo,所以Bar1扩展BaseFooBar2扩展ExtendedFoo。 >
  2. 重写不需要的方法以抛出UnsupportedOperationException,因此如果调用此方法,它将抛出(有意义的)异常。

我会采用第一种方法。

【讨论】:

    【解决方案2】:

    应该是这样的。但是,这可能不是您真正想要的。这取决于您的实际需求。

    public abstract class Foo
    {
    
    }
    
    public abstract class FooMeth1 extends Foo {
        public abstract void fooMethod1(int num1);
    
    }
    
    public abstract class FooMeth2 extends FooMeth1 {
        public abstract void fooMethod2(int num2);
    }
    
    public class Bar1 extends FooMeth1 // This class shouldn't be able to access fooMethod2()
    {
        @Override
        public void fooMethod1(int num1)
        {
            System.out.println((num1 * 5));
        }
    }
    
    public class Bar2 extends FooMeth2 // This class has no restrictions
    {
         @Override
         public void fooMethod1(int num1)
         {
              System.out.println((num1 * 10));
         }
    
         @Override
         public void fooMethod2(int num2)
         {
              System.out.println((num2 * 5));
         }
    }
    

    【讨论】:

      【解决方案3】:

      可以通过将 Bar2 放在同一个包中,将 Bar1 放在不同的包中,并分别使方法受包保护和公开。或者您可以创建注释并生成代码以通过反射蛮力检查调用者。

      【讨论】:

      • 你的意思是用“访问”来“覆盖”吗?如果你这样做,那是不可能通过普通方法做到的。因为它要么是最终的,要么不是。您可以做一些反射魔术,以便将原始方法设为“最终”,然后仅当当前类是特定类时才调用可覆盖方法,但这很讨厌。
      【解决方案4】:

      你不能,你在超类中的所有公共抽象方法对子类都是可见的。 不仅如此,所有子类都必须实现所有抽象方法。

      根据您的需要,我建议在 Foo 和 Bar1 之间设置另一个类,您可以在其中实现所需的方法。

      【讨论】:

        【解决方案5】:

        要加上我自己的两分钱,我会说不是使用超类,而是创建两个接口。即Foo1Foo2。每个接口都将包含其中一种方法。然后你可以让Bar1Bar2 分别实现Foo1Foo2。这种方法的好处是您可以拥有一个实现 Both 接口的 Class Bar3,而对于 Abstract 类,您只能扩展一个 Superclass。

        【讨论】:

          【解决方案6】:

          如果 Foo 类只有抽象方法,你可以将 Foo 类分成 2 个接口,然后在 bar1 和 bar2 中实现所需的接口。或者将仅在 bar1 中需要的方法拆分为一个接口,其余的留在 foo 中

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2012-09-19
            • 2017-01-19
            • 1970-01-01
            • 2010-11-11
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多