I have 6 classes as shown in figure below.
Now, class A has an object of class B as a private variable defined. Also class A methods calls many methods from class B, for example B.method1().
Now, class A_Base1 is which is derived from class A, needs to call methods from the derived class B_Base1; for example B1.method2(). And also methods of class A_Base2 needs to call methods from class B_Base2; for example B2.method3().
Now in class A I define the variable as -
private B bObject
Now in method of A_Base1, I cannot cannot call the methods like bObject.method2() since its a base class object.
I need suggestions on -
Is it possible to call derived class object methods using base class object?
Or do I need to re-design this scenario in some other good way?
Using inheritance like this imo only makes sense if the Bx.methodX() do something that means she same to the different Ax. And in that case, you should name them that way:
public class B {
public void doWhatAMeans() {
method1();
}
public class B1 extends B {
#Override
public void doWhatAMeans() {
method2();
}
public class B2 extends B {
#Override
public void doWhatAMeans() {
method3();
}
and then you only need A to call doWhatAMeans() and the A1 and A2 only need to be injected the appopriate instances of Bx.
On the other hand, if doWhatAMeans does not make sense because the methodX do different things that mean different things to Ax, then you need to rethink your object model, probably the parallel structures A,A1,A2 and B,B1,B2 are wrong then.
you could always cast. suppose your class A provides this method:
protected B getBInstance() {
return bObject;
}
then in A_Base1 you could do something like:
((B_Base1)getBInstance()).method2();
this, however, is a VERY bad design. if your A_Base1 class needs an instance of B_Base1 it should be handed such an instance directly at construction time:
public class A_Base1 extends A {
private B_Base1 b1Object;
public A_Base1(B_Base1 instance) {
super(B_Base1); //works as a B for parent
this.b1Ovject = instance;
}
}
and then you can use that
since A is a parent of A_Base1 (I'm assuming extended) you can make the function call that Accesses B public (or protected) and then A_Base1 or A_Base2 can use the same function A does to call into B.
Related
Please read full question, Its different from this type of question
Difference between interface and class objects
Example: 1
Class implementing Interface
public interface a{
void foo();
}
public class b implements a{
#Override
void foo(){}
void bar(){}
}
Working behaviour
a asd=new b(); can call only foo()
b asf=new b(); can call both foo() and bar()
I hope upto here its clear.
Example 2:
Now there is one class CheckingPhase and IdentifyCheckingPhase
class IdentifyCheckingPhase {
private static a getPhase() {
return a;
}
private static void matchPhase(){
(CheckingPhase)IdentifyCheckingPhase.getPhase().bar();
}
}
class CheckingPhase implements a {
#Override
void foo() {
}
void bar(){
}
}
In Example 1. Interface instance only able to call its own implemented method in class and class instance able to all methods (class itself and Interface too). If that's a case, am sure something different being maintanied in compiler side that's why its able to differentiate.
Doubt First, Its correct to say that Interface and Class ref always points to different types instances of same class ? I guess yes, that's they are able to call their own methods. (Interface only its own methods but class ref can call all)
If not, Then In second example, a returned from getPhase(), should not be allowed to replace with CheckingPhase in matchPhase() and call its class instance method. Because a allowed to call only foo and CheckingPhase can call foo and bar both.
Doubt 2, I'm wondering, Is it syntactically correct using CheckingPhase instead of a while coming from method getPhase() to matchPhase() ?
I hope its clear what am trying to ask. Please let me know if may qyestion is not clear. (Its more about how java is using Syntax for above use case)
I came across a situation like this.
public class B{
public final void run() {
}
}
public class A extends B implements Runnable{
//I want to implement Runnable's run method here.
//But it does not allow as the run method in B is final
}
can someone suggest any way I can achieve this.
What is the important thing here: that A is a B or that A is a Runnable?
If it's the former (or it's important that it is both a B and Runnable), there is nothing you can do: B.run is final, and final means you can't override it.
If it's the latter, use composition:
class A implements Runnable {
final B b; // initialize on field or in constructor.
#Override public void run() {
// Your implementation, calling methods/fields on b
// where you need the behaviour/data of B.
}
}
Unfortunately you cannot implement run method in class A under the given circumstances as in class B which is parent class of class A run method has been declared and you can never override final methods.
You can either change the name of method in class B or you can make the method non-final.
abstract class Base{
protected abstract void a();
}
class Child extends Base{
#Override
public void a(){
//why is this valid
}
}
Why is that we can't reduce the visibility but can increase it?
Also I need to implement Template pattern in which the public methods visible can only be of base class.
Example:
abstract class Base{
public void callA(){
//do some important stuff
a();
}
protected abstract void a();
}
class Child extends Base{
#Override
public void a(){
//why is this valid
}
}
Now if java allows to increase visibility then there are two methods visible publicly??
I know interface is one solution but is there some other way out???
Why decreasing visibility is not allowed is already explained in other responses (it would break the contract of the parent class).
But why it is allowed to increase the visibility of a method? First, it would not break any contract, so there is no reason to not allow it. It can be handy sometimes, when it makes sense in the child class for a method to not be protected.
Second, not allowing it could have the side effect of making impossible sometimes to extend a class and implement an interface at the same time:
interface Interface1 {
public void method();
}
public class Parent {
protected abstract void method();
}
public class Child extends Parent implements Interface1 {
#Override
public void method() {
}
//This would be impossible if the visibility of method() in class Parent could not be increased.
}
About your second question, you can do nothing about it. You have to trust that the person who implements the child class doesn't do anything that breaks your implementation. Even if java wouldn't allow to increase visibility, that would still not fix your problem, because a public method with a different name could be created that calls the abstract method:
class Child extends Base{
#Override
protected void a(){
}
public void a2() {
a(); //This would have the same problems that allowing to increase the visibility.
}
}
If the base class makes a promise regarding visibility, then the subclass cannot break that promise and still satisfy the Liskov substitution principle. You can't use a subclass in any situation where the promised method is exposed if that promise is broken.
The subclass IS-A base class. If the base class exposes a method, so must the subclass.
There's no way out in Java or C++. I'd guess the same is true in C#.
Why is that we can't reduce the visibility but can increase it?
Suppose that it would be possible to reduce the visibility. Then look at the following code:
class Super {
public void method() {
// ...
}
}
class Sub extends Super {
#Override
protected void method() {
// ...
}
}
Suppose that you would have another class, in another package, where you use these classes:
Super a = new Sub();
// Should this be allowed or not?
a.method();
To check whether a method call is allowed or not, the compiler looks at the type of the variable you call it on. The type of the variable a is Super. But the actual object that a refers to is a Sub, and there the method is protected, so you would say it should not be allowed to call the method from an unrelated class outside the package. To solve this strange situation, it's made forbidden to make overridden methods less visible.
Note that the other way around (making a method more visible) doesn't lead to the same problem.
Since Java allows Super class reference to point to sub class object.. So, restriction should not be increased from compile-time to runtime..
Lets see this through an example: -
public class B {
public void meth() {
}
}
class A extends B {
private void meth() { // Decrease visibility.
}
}
Now, you create an object of class A and assign it the reference of class B..
Lets see how: -
B obj = new A(); // Perfectly valid.
obj.meth(); // Compiler only checks the reference class..
// Since meth() method is public in class B, Compiler allows this..
// But at runtime JVM - Crashes..
Now, since compiler only checks the type of the reference variable, and check the visibility of methods in that class (class B), and it doesn't check what kind of object does the reference obj refers to.. So, it is not worried about that.. It is left to JVM at runtime to resolve the appropriate method..
But at runtime, JVM will actually try to invoke the meth method of class A as object is of class A.. But, now what happens... BooooOOMM ---> JVM Crashes.. because meth method is private in class A...
That's why visibility is not allowed to be decreased..
I'm new to Java but used to OOP programming. Is there a way I can force implementing an abstract class nested into another abstract class like in the code below :
public abstract class A
{
public abstract class B extends C
{
#Override
public abstract void foo();
}
}
I would like B to be implemented in each subclass of A. Is it possible?
Thank you for your help,
If I read your question correctly, where you want each sub-class of A to CONTAIN a subclass of B, there is not a direct way to do this. However, you could do something like the below:
public abstract class A
{
public abstract class B extends C
{
#Override
public abstract void foo();
}
protected abstract B getBInstance();
}
Because this forces sub-class of A to return an instance of B, they must have access to some sub-class of B.
However, you should really ask yourself why A should care about its sub-classes implementing B unless A uses B in some way which would require the above.
Yes, make B an interface, as shown in When an Abstract Class Implements an Interface.
This is not possible. The A class should only provide what behaviour an instance of A has (either through the abstract or implemented methods). It should not state anything about how A is implemented.
It's not even clear how this would be useful either since you could not call the implemented class B so it would need to be named something else meaning it's existence could be ignored.
I have an interface I that is implemented by a base class B. The base class is extended by a bunch of classes (A,C,D) that must init some of the protected vars declared in base class B. I'd like to make the declaration of a constructor mandatory in the subclasses (A,C,D), to discourage the user from relying on default constructor that's declared in B. Yet I do want the B's default constructor to execute automatically, since B can be used by itself as well. How can I accomplish this?
thanks
Use an abstract superclass of B with a private constructor:
public abstract class BSuper {
private BSuper() {
// initialize stuff
}
protected BSuper(some params) {
this():
// other init with parms
}
}
public class B extends BSuper {
public B(some other params) {
super(some params);
}
}
public class A extends B {
public A() {
super(some other params);
}
}
or similar
Make B's default constructor private and call this(); from within the parameterized constructor...
public class B {
private B() {
super();
}
public B( Foo foo ) {
this();
}
public static B createInstance() {
return new B();
}
}
Edit: Miss read the issue, removed abstract keyword from class declaration. Also added public static factory method for creating B class. It calls B's default constructor.
Just write a comment in the Javadoc that says "Use of default constructor is discouraged when subclassing." In my experience, trying to enforce that programmatically is not worth the effort and could cause problems latter on. Simple English will do.
If class B is going to have its own default constructor, what you want is impossible. When you derive from a class, you're telling the compiler that it should allocate memory for a base class object in every instance of the derived class. There's no way to tell a java compiler to suddenly take away some of the base class's functionality every time that something is inherited from it.
Also note that constructors and static factory methods can't be abstract, so even if B could be an abstract class you would have to do something like:
public class B {
B() {
initialize();
}
protected abstract void initialize();
}
...along with making sure that the derived classes implement default constructors that call super()