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
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