In the existing library, from the abstract class, three new non-abstract descendant classes are formed. It is necessary to add common fields and methods in the descendants. I do not want to correct the parent class directly in the library. Is it possible, without changing these library classes, to create new ones, so as not duplicating, to add common fields and methods in new classes?
The library is foreign. If it is updated, you will have to make your own changes. Having reviewed all the proposals, I decided to make changes to the library, adding my own functionality.

  • inherit from descendants and add new fields - Gardes
  • What is the purpose of expanding library classes? Will you use them from the outside or with library methods? Those. to transfer instances of these classes as parameters? - Artem Konovalov

2 answers 2

Option 1

If I understand correctly, then interfaces can help you:

There is an abstract class:

public abstract class Abstr { public abstract void method(); } 

And there is an interface: in which you can create a method with a default implementation and methods that you need to implement.

 public interface Interface { //ПолС, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΡ€ΠΈΡΡƒΡ‚ΡΡ‚Π²ΠΎΠ²Π°Ρ‚ΡŒ Π²ΠΎ всСх имплСмСнтациях public int field = 0; //"ΠŸΡƒΡΡ‚ΠΎΠΉ" ΠΌΠ΅Ρ‚ΠΎΠ΄ ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒ Π² ΠΈΠΌΠΏΠ»Π΅ΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΠΈ public void anotherMethod(); //ΠœΠ΅Ρ‚ΠΎΠ΄ с Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠ΅ΠΉ ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ, Π±ΡƒΠ΄Π΅Ρ‚ доступСн Π² ΠΈΠΌΠΏΠ»Π΅ΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΠΈ default int retInt(){ return 5; }; } 

Implementations:

 public class RealizationAbstr extends Abstr implements Interface { @Override public void method() { System.out.println("Hello from first Realization"); } @Override public void anotherMethod() { System.out.println(1); } } public class RealizationAbstr2 extends Abstr implements Interface { @Override public void method() { System.out.println("Hello from second Realization"); } @Override public void anotherMethod() { System.out.println(2); } } 

However, with this approach there is a limitation - the interface fields are essentially constants and there is no possibility to change them.

Option 2

Another option would be to embed an intermediate class. That is, move from this model of Inheritance:

 Abstract <- 3x(Realization) 

To this:

 Abstract <- AbstractWithFieldsAndMethods <-3x(Realization) 

The method is simple and suitable if you can edit classes that implement an abstract class.

    You can use defaulted implementations of interface methods .

    You make an heir and you specify an interface with it that contains the default implementation:

     class Base { public int functionFromBase() { return 0; } } class A extends Base { public int functionFromA() { return 1; } } class B extends Base { public int functionFromB() { return 2; } } interface Common { default int functionFromCommon() { return 7; } } class AA extends A implements Common {} class BB extends B implements Common {} 
     AA a = new AA(); BB b = new BB(); System.out.println(a.functionFromBase() + " " + b.functionFromBase() ); System.out.println(a.functionFromA() + " " + b.functionFromB() ); System.out.println(a.functionFromCommon() + " " + b.functionFromCommon()); 

    Full example: http://ideone.com/9adriG

    PS: In C #, extension methods play a similar role. In some other languages ​​(for example, js) the notion of mixins can be used.

    • @ sanek-zhitnik However, with this approach, there is a limitation - the interface fields are essentially constants and there is no possibility to change them. Unfortunately, the general fields are not static. - Konstantin Razumovsky