0

Suppose I have class/interface A that is extended/implemented by class B and class C. Class/interface A contains method X. Is there a way to have method X without a body (X();) and so it must be implemented by class B and class C, but not give class B and class C (or any other class except possibly class/interface A) access to each other's method X?

? class/interface A {
  ? X();
}

? class B extends/implements class/interface A {
  @Override
  ? X() {
    ...code...
  }
}

? class C extends/implements class/interface A {
  @Override
  ? X() {
    ...code...
  }
}

I am not sure of modifiers, represented with question marks above, and I am not sure if A should be a class or interface.

EDIT: Additionally, instances of classes B and C are created in class D. The instance of class C in class D is constructed with the instance of class B in class D as a parameter, which is set as a class variable which this instance of class C is constantly getting data from. I do not want this instance of class C to be able to call its class variable object B's method X.

Makazau
  • 615
  • 7
  • 17
  • 1
    If I understand you correct, you want to give your method `X()` the visibility `protected`. – Progman Dec 09 '18 at 22:52
  • 1
    What are you trying to do? `C` has access to all `protected` and `public` methods of `B`. So the only option is to make the method `private`. But you can not enforce a private method with `abstract` or an `interface`. – k5_ Dec 09 '18 at 22:52
  • 1
    Who exactly should be able to call X? (Only A?). And why is exact access so important? (But the closes thing to what you want, is that a,b and c should be classes, and ? should be protected. – MTilsted Dec 09 '18 at 22:56
  • 3
    I have to wonder if this is possibly an [XY Problem](http://xyproblem.info) in disguise. Consider telling more background of the overall problem that you're trying to solve with this program, the motivation behind your question. Also please show real code rather than kind-of sort-of code. – Hovercraft Full Of Eels Dec 09 '18 at 23:01
  • X would need to be implemented differently in b and c, and they are just helper methods that are called in a few places in b and c (b calls b's X in a few places, and c calls c's X in a few places). It would just be confusing to be able to call b's X from c and the reciprocal. – Makazau Dec 09 '18 at 23:04
  • OOP problems...why don't you just NOT call b's X from c and vice versa. This is when you know you're in deep – smac89 Dec 10 '18 at 02:26
  • @MathiasStrohkirch But if the method is only called directly on b and c, why do you want the method to be defined in A at all? – MTilsted Dec 11 '18 at 13:43

1 Answers1

1

Provided classes B and C do not live in the same package as class A, you can make X protected abstract in A.

This implies that you will need to make A an abstract class not an interface because interface methods are always public.

So you will have A:

package a.b.c

public abstract class A {
    protected abstract Foo X();
}

Create B in a new package

package a.b.d

public class B extends a.b.c.A {
    // ... implement X
}

Create C in a different package

package a.b.e

public class C extends a.b.c.A {
    // ... implement X
}

Now if you want class D to be able to call X, you will need to place D in the same package as A i.e. a.b.c, but you will need to cast each of them to A in order to call X.

package a.b.c

public class D {
    public D(a.b.d.B b, a.b.e.C c) {
        // ... call ((A)b).X() or ((A)c).X()
    }
}
smac89
  • 39,374
  • 15
  • 132
  • 179
  • This makes a lot of sense. Essentially creating "private" methods in B and C by making the methods protected and putting them in their own package. Thank you – Makazau Dec 10 '18 at 03:45