有什么方法可以强迫子类覆盖超类的非抽象方法?

我需要能够创建父类的实例,但是如果一个类扩展了该类,则它必须给出自己的某些方法的定义。

有帮助吗?

解决方案

据我所知,没有直接的编译器强制方法可以做到这一点。

您可以通过使父类可实例化来解决此问题,而是提供一种工厂方法来创建具有默认实现的某些(可能的私有)子类的实例: 通用标签

您现在不能编写new Base(),但是您可以执行Base.create()以获得默认实现。

其他提示

正如其他人指出的那样,您不能直接这样做。

但是执行此操作的一种方法是使用策略模式,如下所示: 通用标签

考虑使用此方法创建接口。类后代必须实现它。

我认为最简单的方法是创建一个从基类继承的抽象类: 通用标签

否,这是抽象方法的全部要点。您的用例是什么?也许我们可以根据基本需求进行思考。

How about this: inside the default implementation of the method, use reflection to get the exact Class of the object. If the Class does not match your base class exactly, throw a RuntimeException or equivalent.

public class Parent {

    public void defaultImpl(){
        if(this.getClass() != Parent.class){
            throw new RuntimeException();
        }
    }

}

There's a reason it's not possible!

The derived class could simply call the base class's implementation when overriding the method.

So what's the point of forcing the class to override your method? I don't think there's any benefit.

Answer would be a no. You can redesign using template design pattern. It may help you.

Alternatively, you can make your child classes implement an interface. The interface may or may not be implemented by the super class.

You can always make the base class have a method that throws an exception.

Technically the base class has defined the method, but it is not usable without overriding the method. In such a case, I prefer a runtime exception as they don't require an explicit throws statement. An example follows

public class Parent {

  public void doStuff() {
    throw new RuntimeException("doStuff() must be overridden");
  }

}

public class Child extends Parent {

  @Override
  public void doStuff() {
    ... all is well here ...
  }

}

The downside is that this doesn't prevent creation of Base objects; however, anyone attempting to use one of the "must be overridden" methods will soon find that they should have overridden the class.

While this solution meets the description of the request well, your application would probably benefit from not requiring a solution like this one. It's much better to avoid runtime crashes with compiler checks, which is what the abstract keyword provides.

I will mirror the other answers and say that there is no compiler-enforced way to force derived classes to override a non-abstract method. The whole point of making a method abstract is to define that a method with this signature must exist, but cannot be specified at the base level and therefore must be specified at a derived level. If there is a working, non-trivial implementation (as in it's not empty and doesn't just throw an exception or show a message) of a method at the base level, then this isn't strictly necessary in order for a call to the method from a consumer of the derived class to succeed. So, the compiler doesn't have to enforce overriding a method that can run quite successfully on either the base or derived levels.

In situations where you would want a derived class to override your working implementation, it should be pretty obvious that the base implementation doesn't do what the derived class's consumers will want; the base class either doesn't have enough implementation, or the wrong one. In those cases, you have to trust that a programmer deriving from your class will know what he is doing and thus know that the method needs to be overridden because it does not produce the right answer in the context of using his new object.

I can think of one thing you could do. It would require an abstract base, with a sealed (final for the Javaheads) "default" implementation. That way, there is a basic implementation of the method that is readily available to use as if it were a "base" class, but in order to define a different class for a new scenario, you must go back to the abstract class, and are thus forced to reimplement the method. This method could be the only abstract thing on the class, thus still allowing you to make use of basic implementations of other methods:

public abstract class BaseClass
{
   public abstract void MethodYouMustAlwaysOverride();

   public virtual void MethodWithBasicImplementation() { ... }
}

public final class DefaultClass:BaseClass
{
   public override void MethodYouMustAlwaysOverride() { ... }

   //the base implementation of MethodWithBasicImplementation 
   //doesn't have to be overridden
}

...

public class DerivedClass:BaseClass
{
   //Because DefaultClass is final, we must go back to BaseClass,
   //which means we must reimplement the abstract method
   public override void MethodYouMustAlwaysOverride() { ... }

   //again, we can still use MethodWithBasicImplementation, 
   //or we can extend/override it
   public override void MethodWithBasicImplementation() { ... }
}

However, this has two drawbacks. First, because you do not have access to DefaultClass's implementation through inheritance, you cannot extend DefaultClass's implementation, meaning that to do what DefaultClass does, plus a little more, you must rewrite the code from DefaultClass, violating DRY. Second, this only works for one level of inheritance, because you cannot force overriding if you allow inheritance from DerivedClass.

maybe this helps:

class SuperClass {

    void doStuff(){

        if(!this.getClass().equals(SuperClass.class)){

            throw new RuntimeException("Child class must implement doStuff Method");
        }else{
            //ok
            //default implementation
        }
    }
}

class Child extends SuperClass{

    @Override
    void doStuff() {
        //ok
    }
}

class Child2 extends SuperClass{

}


 new SuperClass().doStuff(); //ok
 new Child().doStuff();         //ok
 new Child2().doStuff();        //error

ok, let's learn it this way. I adhere to java style guidelines and use java syntax. So it is assumed that multiple inheritance and C++ templates are unavailable.

making the parent class method abstract is not a must, in OOP you use the concept of polymorphism. you can use the same method in two or more different ways. This is called method overriding.

let's take an example.

    public class Animal{
       public void makeSound(){
          System.out.println("Animal doesn't know how to make sound");
       }

    }

    public class PussyCat extends Animal{
        public void makeSound(){

           System.out.println("meowwww !!!");
        }

        public static void main(String args[]){
           PussyCat aCat=new PussyCat();
           aCat.makeSound(); 
        }
    }

this will print "meowww !!!" on the screen.

but this doesn't imply that the method makeSound must be overridden in the child class.

If you need the child class to be forced to override the methods, you better implement an interface by the class.

      public Interface audible{
         public void makeSound();

      }

      public class pussyCat implements audible{
          // now you must implement the body of makeSound method here
          public void makeSound(){
            System.out.println("meowwww !!!"); 
          }

          public static void main(String args[]){
           PussyCat aCat=new PussyCat();
           aCat.makeSound(); 
        }
      }

this will also print "meowwww !!!" on the screen

It may not be recommended, but you can throw an exeption( something like MethodeMustBeOverRiddenExp) in your methode implementation. Of course it is RunTime forcing but may be better than nuthing.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top