Това може да изглежда като странно нещо, но има ли начин в Java да спре подкласовете да добавят нови методи (включително конструктори), като същевременно позволява на подкласовете да заменят методите?
Действителната ситуация е, когато имаме abstract
клас с някои абстрактни методи и конструктор
abstract class A {
abstract A doX();
abstract boolean isY();
public A(String s){ ... };
}
и искаме всички конкретни подкласове на този клас да заменят само тези методи и конструктор.
Става въпрос за налагане на определен стил в нашия код, т.е. спиране на други хора, работещи върху кода, да добавят неща. Можем просто да им кажем да не го правят, но това рядко работи, така че се чудехме дали има програмен начин да постигнем това.
Очевидно класът не може да бъде final
. Ефективността не е от първостепенно значение - по-изчистеният код е по-важен.
Актуализация - динамичен подход
Както беше посочено в отговорите, няма начин да направите това статично, тъй като единственият начин да предотвратите създаването на подкласове е използването на final
, което няма да работи. Но бих могъл да използвам динамичен подход, така че настоящото ми решение е да добавя това aspect
към проекта (който вече използва AspectJ
).
public aspect WatchA{
before() : execute(* A.*()) || execute(* A.*(..)) {
String methodCalled = joinPoint.getSignature().getName();
Class<?> c = Class.forName(args[0])
Method[] allMethods = c.getDeclaredMethods();
boolean found = false;
for(Method m : allMethods)
found |= m.getName().equals(methodCalled);
if(!found)
throw new RuntimeException("Do not add method "+methodCalled+" to A");
}
}
Което ще доведе до провал на тестовете им, ако използват някой от тези нови методи.