Java "абстрактный как" метод с телом

существуют следующие классы:

public abstract class Super
{
    public abstract void run();
}

public class Sub1 extends Super
{
    @Override
    public void run ()
    {
        System.out.println("Method called");
        System.out.println("Sub1 called");
    }
}

public class Sub2 extends Super
{
    @Override
    public void run ()
    {
        System.out.println("Method called");
        System.out.println("Sub2 called");
    }
}

Как я могу избежать того, что мне нужно написать систему".из.метод println("метод");" два раза?

Спасибо за ответы

калибра.50

6 ответов


приведите общую функциональность к суперклассу и определите другой абстрактный метод, для которого подклассы будут определять свою собственную реализацию.

public abstract class Super {
    public void run() {
        System.out.println("Method called");
        printMessage();
    }
    abstract void printMessage ();
}

public class Sub1 extends Super {
    @Override
    void printMessage() {
        System.out.println("Sub1 called");
    }
}

public class Sub2 extends Super {
    @Override
    void printMessage () {
        System.out.println("Sub2 called");
    }
}

таким образом, вы можете избежать дублирования вызова общего метода суперкласса в два раза.


вы можете поместить реализацию run () в абстрактный класс:

// Super is still an abstract class
public abstract class Super
{
    // While method run is not an abstract method:
    public void run() 
    {
        System.out.println("Method called");
    }
}

public class Sub1 extends Super
{
  // There's no need of declaring run() here unless you want to change its behaviour
}

public class Sub2 extends Super
{
}

в отредактированной версии вашего вопроса Вы можете просто использовать унаследованную реализацию запуска

// Super is still abstract
public abstract class Super
{
    // But method run is not abstract
    public void run() 
    {
        System.out.println("Method called");
    }
}

public class Sub1 extends Super
{
  @Override
  public void run()
  {
      super.run(); // <- call Super.run() that prints "Method called"
      System.out.println("Sub1 called");
  }
}

public class Sub2 extends Super
{
  @Override
  public void run()
  {
      super.run();
      System.out.println("Sub2 called");
  }
}

если часть реализации run() является общим для Sub1 и Sub2, я предлагаю вам просто использовать наследование и переопределение run в подклассах. Вот пример кода:

public abstract class Super
{
    public void run() {
        // Code shared by all subclasses
        System.out.println("Method called");
    }

}

public class Sub1 extends Super
{
    @Override
    public void run ()
    {
        super.run();
        System.out.println("Sub1 called");
    }
}

public class Sub2 extends Super
{
    @Override
    public void run ()
    {
        super.run();
        System.out.println("Sub2 called");
    }
}

фокус здесь в том, что Super класс может быть определен abstract при реализации методов. Если у вас есть подклассы, которым не нужен общий код, вы можете переопределить run() без super.run() код и изменить все это.


вы можете поместить общий код в Метод супер класса и вызвать его из методов подкласса .

public abstract class Super
{
   public abstract void run();
   // code common to both the sub classes implemented
   public void print() {
     System.out.println("Method called");
   }
}

public class Sub1 extends Super
{
   @Override
   public void run ()
   {
     print();
     System.out.println("Sub1 called");
     // sub class specific code here
   }
}

public class Sub2 extends Super
{
   @Override
   public void run ()
   {
      print();
      System.out.println("Sub2 called");
      // sub class specific code here
   }
}

используйте "шаблон метода шаблона":

public class Super
{
    public void template() {
        System.out.println("Method called");
        run();
    }

    public abstract void run();
}

public class Sub1 extends Super
{
    @Override
    public void run () // out called before run
    {

    }
}

public class Sub2 extends Super
{
    @Override
    public void run () // out called before run
    {

    }
}

Aditionally вы можете сделать запуск защищенным.


Если вы хотите, чтобы все подклассы имели одинаковое поведение, то правильным методом было бы кодировать метод только в суперклассе, позволяя подклассам наследовать его. Но это исключило бы необходимость того, чтобы ваш суперкласс был абстрактным в этом случае, так как он будет реализовывать свой единственный метод.