Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/401.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 派生类的抽象方法限制控制_Java_Class_Abstract - Fatal编程技术网

Java 派生类的抽象方法限制控制

Java 派生类的抽象方法限制控制,java,class,abstract,Java,Class,Abstract,抽象基类是否可能具有抽象方法,其中只有某些派生类可以访问某些抽象方法?我想做的是限制可能从不同继承类调用的方法。以下是我的问题的一个例子: public abstract Foo { ... public abstract void fooMethod1(int num1); public abstract void fooMethod2(int num2); } public Bar1 extends Foo // This class shouldn't be ab

抽象基类是否可能具有抽象方法,其中只有某些派生类可以访问某些抽象方法?我想做的是限制可能从不同继承类调用的方法。以下是我的问题的一个例子:

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

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

不可以,超类中的所有公共抽象方法对子类都是可见的。 除此之外,所有子类都必须实现所有抽象方法


出于您的需要,我建议在Foo和Bar1之间使用另一个类,您可以在其中实现所需的方法。

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

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

  • 我会选择第一种方法。

    就是这样。然而,这可能不是你真正想要的。这取决于你的实际需求

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

    要加上我自己的两分钱,我会说,不要使用超级类,而是创建两个接口。ie
    Foo1
    Foo2
    。每个接口将包含其中一个方法。然后您可以让
    Bar1
    Bar2
    分别实现
    Foo1
    Foo2
    。此方法的好处是,您可以拥有一个实现两个接口的类
    Bar3
    ,而对于抽象类,您只能扩展一个超类。

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

    中,而不是私有变量中,如果子类扩展了超类,则它将有权访问该超类的所有成员。可能
    fooMethod2
    方法不属于
    Foo
    。为什么要这样做?您是说用“访问”来“覆盖”吗?如果你这样做了,这是不可能通过正常的方法做到的。因为它要么是最终的,要么不是。您可以使用一些反射魔法,使原始方法成为“final”,然后仅当当前类是特定类时才调用可重写方法,但这很糟糕。