Obecnie piszę klasę, która powinna służyć jako dodatek do już istniejących zajęć. Na przykład, niech moja klasa dodatkowa będzie następująca:

public class NewClass {}

Załóż również, że istnieją już zajęcia, takie jak:

public final class ExistingClassA {}
public final class ExistingClassB {}
...

Te nie wolno mi się zmieniać. W przypadku niektórych algorytmów chciałbym jednak zdefiniować istniejące zajęcia, które mają być dziećmi mojego {x0}}. Więc zamiast dziedziczyć z niektórych klasy z extends, chcę osiągnąć odwrotnie: Chcę "adoptować" klasę, jak gdyby istniejące klasy były pierwotnie określone w ten sposób:

public final class ExistingClassA extends NewClass {}
public final class ExistingClassB extends NewClass {}
...

Czy to nawet możliwe w Javie? A jeśli tak, to również możliwe, aby dodać klasę jako rodzic klasy, który już rozszerza inną klasę?

Edytuj:

Aby moja sytuacja była nieco wyraźniejsza, spróbuję opisywać, co chcę osiągnąć bardziej szczegółowo. Na przykład. Załóż na zmienną myVar, co powinno być tylko instancji określonych klas. Jeśli te klasy należały do wspólnej klasy rodzicielskiej, nie byłoby to problemu:

public final class ExistingClassA extends CommonParentClass {}
public final class ExisitingClassB extends CommonParentClass {}
public final class ExistingClassC extends CommonParentClass {}

...
/* We're inside some class now... */
CommonParentClass myVar; // May be of ExistingClassA, ExistingClassB, or ExistingClassC.

Powiedz teraz, chcę myVar być tylko z klasy ExistingClassA lub ExistingClassB. Zakładając, że mogę "adoptować" te dwie klasy z moim NewClass, mogłem również napisać:

NewClass myVar; // May be of ExistingClassA, or ExistingClassB, but not ExistingClassC.

Ponieważ wydaje się to nie być możliwym (od czytania komentarzy), jakie podejście byłoby najmądrzejsze, aby osiągnąć cel po prostu pozwalający myVar tak być podzbiorem CommonParentClass ?

0
TiMauzi 16 luty 2021, 03:06

1 odpowiedź

Najlepsza odpowiedź

Nie ma mechanizmu czasu kompilacji, aby sprawdzić, czy klasa rozciąga się ani klasa A lub B. Jeśli autorzy {X1}} i {X1}} i {X1}} nie zdefiniowały, że są powiązane, nie są.

Masz kilka możliwości:

  • Możesz użyć instanceof, a następnie odrzucić do określonego typu.

    Object myObj = ...;
    if (myObj instanceof Alpha) {
        ((Alpha) myObj).doSomething();
    }
    else if (myObj instanceof Bravo) {
        ((Bravo) myObj).doSomethingElse();
    }
    else {
        throw new IllegalArgumentException("myObj" must be of either Alpha or Bravo");
    }
    
  • Lub możesz dokonać obiektu opakowania akceptowanego w konstruktorze:

    class Either<A, B> {
        A a;
        B b;
        boolean isA;
        Either(A a) {
            this.a = a;
            this.isA = true;
        }
        Either(B b) {
            this.b = b;
        }
        boolean isA() {
            return isA;
        }
        A getA() {
            return a;
        }
        B getB() {
            return b;
        }
    }
    

    a potem nazwij to:

    Either<Alpha, Bravo> either = new Either(...);
    if (either.isA()) {
        either.getA().doSomething();
    }
    else {
        either.getB().doSomethingElse();
    }
    

Ale nie widzę jak chcesz użyć tych dwóch klas. Czy mają metodę o tej samej nazwie? I dlaczego po prostu nie użyjesz dwóch zmiennych?

1
MC Emperor 19 luty 2021, 00:53