Initializing a final variable in an abstract class (Java) - java

So I have this abstract class
public abstract class A {
protected final boolean b;
protected A (boolean b){
this.b = b;
}
}
And this class that extends A
public class C extends A{
protected C() {
super(false);
}
}
I dont want "b" to be able to change its' value once it's initialized
But I dont know how to do it without the compiler going haywire.
Any suggestions are welcome. Thanks in advance.
EDIT1: static removed from b.
EDIT 2: Ok realised the problem and fixed see above.
Special thanks to J.Lucky :)

I'd suggest you make use of the final keyword.
Try the following codes:
abstract class A {
final protected boolean b;
A(boolean b) {
this.b = b;
}
//No setter method
//public abstract void setB(boolean b);
public abstract boolean getB();
}
class C extends A {
C(boolean b) {
super(b);
}
#Override
public boolean getB() {
return b;
}
}
Sample implementation would be:
public static void main(String args[]) {
C c = new C(true);
System.out.println(c.getB());
}
Since b now is a final variable, you will be forced to initialize it on your constructor and you will not have any way of changing b anymore. Even if you provide a setter method for b, the compiler will stop you.
EDIT 2:
Say you created another class called 'D' and this time you know you want to set it to false by default. You can have something like:
class D extends A {
D() {
super(false);
}
//You can also overload it so that you will have a choice
D(boolean b) {
super(b);
}
#Override
public boolean getB() {
return b;
}
public static void main(String[] args) {
D defaultBVal = D();
D customBVal = D(true);
System.out.println(defaultBVal.getB()); //false
System.out.println(customBVal.getB()); //true
}
}

Solution: You should change the boolean into a Boolean, make it private, provide a getter and a protected setter. In the setter you should check whether the Boolean has been initialized. If so, you should either ignore resetting, or throw and Exception

well how about this:
public abstract class A {
private static Boolean b;
//setB is declared here and, depending on the class that implements it,
//it initializes the value of the variable "b"
protected abstract void setB();
}
public class C extends A{
protected void setB() {
if(b != null) b = true;
}
}
Now the variable is only initialized once when its called. There are still some problems. Someone could use reflection to change the value. Also, when the object is serialized is possible that someone could change the value. If you have a multiple threads accessing this then you should synchronize the method. However, if these aren't issues then this solution might work for you.

Related

Can the object call the overriden method instead of its original method

If we have 2 classes like this :
public class A {
public static int m=10;
public int b(){ m++; return m;}
public int fun() {
return b();
}
}
public class Testfun() extends A {
#Override
public int b() {return 1;}
public void test(){
A a = new A();
assertEquals(1,a.fun());
}
}
Is there any way to make the method fun() in class A call the overriden b() instead of the its super b()?
The idea is:
I suppose to test the method fun() and do a stub b(). So I don't want the method to call the original b() and call the stub one.
Is there any way to make the method fun() in class A call the overriden b() instead of the its super b() ?
No way. The instance you have is of type A and methods from A gets called. Period.
No you can not call.The instance you have is of type A and methods from A gets called.
No, it's not possible, because object don't know how many of it's childs or are there any of it. When you want to test something inside a class and want to stub it it's signal of you need to make it dependency of the class like this:
public class A {
private final B b;
public A(B b) {
this.b = b;
}
public int fun() {
return b.b();
}
}
public interface B {
int b();
}
public class Testfun() {
public void test(){
B b = new B {
public int b() {
return 1;
}
};
A a = new A(b);
assertEquals(1, a.fun());
}
}
In this example we make B as dependency of class A and able to change B from desirable implementation in runtime to test dummy in testing. When you need to test B itself you need separate class that tests B. See https://en.wikipedia.org/wiki/Strategy_pattern
Thanks for all, it really helped me !
My mistake was here
A a = new A();
It should be :
A a = new Testfun();
Therefor the overriden b() will be called.

Passing objects in java through constructor

What is better : passing an object through a constructor and save it to new reference in another class, or passing through a constructor an directly pass it to method? Is there any difference?
class A
{
int a;
int b;
}
class B
{
public A refA;
public B(A refA)
{
this.refA = refA;
methodInB(refA);
}
public void methodInB(A refA)
{
...
}
}
OR -------------------------------------------------- OR
class A
{
int a;
int b;
}
class B
{
public B(A refA)
{
methodInB(refA);
}
public void methodInB(A refA)
{
...
}
}
It depends on whether A is integral part of B or not same goes for the methodInB. If we don't put A's reference in B then methodInB becomes kind of a utility method, which should better be static. If it's not a utility then it has a dependency on A and A's reference should be put in B.
Also if there are other methods in B which may need the same A instance to operate on, it's better to keep A's reference saved inside B.
If methodInB is acting as a utility then it should be put in a utility class with static modifier taking A and B type parameters.
Check below:
public class A { }
public class B { }
public class MyUtility {
public static void methodInB(A a, B b) {
//operate on a and b
}
}
// MyUtility can also have a dependency on A and B both and thus make methodInB a non static methodInB
public class MyUtilityBean {
private A a;
private B b;
public void methodInB() {
//operate on a and b
}
}
//Other wise A acts as a dependency of B
public class B {
private A a;
public void methodInB() {
//operate on a
}
}

Is it a good practice to provide check the instance type in the base class

I have four classes. A,B,D are derived classes, and C is the base class. If the given instance is A or D, return true; Otherwise, return false. Below is my codes:
//A.java
public class A extends C{
}
//B.java
public class B extends C {
}
//D.java
public class D extends C {
}
//C.java
public class C {
public boolean isSupported(C object){
boolean result= false;
// Object type check
if(object instanceof A || object instanceof D){ // A, D
result=true;
}
else { // B, C
result=false;
}
return result;
}
public static void main(String args[]){
C tmp = new A();
System.out.println(tmp.isSupported());
}
}
So is it a good practice to check the instance/object type in isSupported() of the base class C? (For C++, if four classes are defined in the different files, if I do so, I have to include the header files defining the Class A and D in the file providing the implementation of Class C, which is a little bit strange).
I know I can provide a override function in each of derived class. But is it kind of duplicate codes especially if I have a lot of derived classes.
Can anyone give me some suggestions?
Thanks
You should override isSupported in the subclasses so that A and D override it to return true and C defines the default behavior (returning false) and B inherits that default behavior from C without overriding.
public class C {
public boolean isSupported() {
return false;
}
}
public class A extends C {
#Override
public boolean isSupported() {
return true;
}
}
public class B extends C {
// inherits isSupported from C
}
public class D extends C {
#Override
public boolean isSupported() {
return true;
}
}
A base class should never need to know anything about classes extending it. Otherwise you would need to modify the base class when extending it. I would consider that very bad style (in other word, it "smells" - no, that's not an insult - see "code smell").
Why do you need to do that?

How to change a variable from a method

This question is a common issue, and I have tried to look at some thread as Is Java "pass-by-reference" or "pass-by-value"? or How to change an attribute of a public variable from outside the class
but in my case I need to modify a boolean variable, with a Singleton instance.
So far I have a class, and a method which changes the boolean paramter of the class. But I would like to separate this mehod in a manager. The scheme is something like:
public class Test{
private boolean b;
public String getb(){}
public void setb(){}
String test = ClassSingleton.getInstance().doSomething();
}
public class ClassSingleton{
public String doSomething(){
//here I need to change the value of 'b'
//but it can be called from anyclass so I cant use the set method.
}
}
Thanks,
David.
If I understand your requirement - this can solve your problem:
public interface IUpdatable
{
public void setB(boolean newValue);
}
public class Test implements IUpdatable
{
private boolean b;
public String getb(){}
public void setB(boolean newValue) {this.b = newValue;}
}
public class ClassSingleton
{
public String doSomething(IUpdatable updatable)
{
updatable.setB(true);
...
}
}
This way the Singleton does not need to know your Test class - it just knows the interface IUpdatable that supports setting the value of B. Each class that needs to set its B field can implement the interface and the Singleton can update it and remain oblivious to its implementation.
You could extract public void setb(){} into an interface (let's call it BSettable), make Test implement BSettable, and pass an argument of type BSettable into doSomething.
Alternatively, you could make b into an AtomicBoolean and make doSomething accept (a reference to) an AtomicBoolean.
Define b as static variable.
Then call Test.b = value
Perhaps:
public class Test {
private static boolean b;
public static String getB() {}
public static void setB() {}
}
should help? Static fields and methods can be called without an instance (i.e. Test.setB();).
I think your question is not very clear and your sample code is really badly done. Do you actually mean something like this?
public class Test{
private boolean b;
public boolean getb(){return b;}
public void setb(boolean b){this.b = b;}
String test = ClassSingleton.getInstance().doSomething(this);
}
public class ClassSingleton{
private static ClassSingleton __t__ = new ClassSingleton();
private ClassSingleton() {}
public String doSomething(Test t){
t.setb(true);
return null;
}
public static ClassSingleton getInstance(){
return __t__;
}
}
Do you mean your manager is a singleton? or your test class should be singleton? Please be more specific

Calling super super class method

Let's say I have three classes A, B and C.
B extends A
C extends B
All have a public void foo() method defined.
Now from C's foo() method I want to invoke A's foo() method (NOT its parent B's method but the super super class A's method).
I tried super.super.foo();, but it's invalid syntax.
How can I achieve this?
You can't even use reflection. Something like
Class superSuperClass = this.getClass().getSuperclass().getSuperclass();
superSuperClass.getMethod("foo").invoke(this);
would lead to an InvocationTargetException, because even if you call the foo-Method on the superSuperClass, it will still use C.foo() when you specify "this" in invoke. This is a consequence from the fact that all Java methods are virtual methods.
It seems you need help from the B class (e.g. by defining a superFoo(){ super.foo(); } method).
That said, it looks like a design problem if you try something like this, so it would be helpful to give us some background: Why you need to do this?
You can't - because it would break encapsulation.
You're able to call your superclass's method because it's assumed that you know what breaks encapsulation in your own class, and avoid that... but you don't know what rules your superclass is enforcing - so you can't just bypass an implementation there.
You can't do it in a simple manner.
This is what I think you can do:
Have a bool in your class B. Now you must call B's foo from C like [super foo] but before doing this set the bool to true. Now in B's foo check if the bool is true then do not execute any steps in that and just call A's foo.
Hope this helps.
To quote a previous answer "You can't - because it would break encapsulation." to which I would like to add that:
However there is a corner case where you can,namely if the method is static (public or protected). You can not overwrite the static method.
Having a public static method is trivial to prove that you can indeed do this.
For protected however, you need from inside one of your methods to perform a cast to any superclass in the inheritance path and that superclass method would be called.
This is the corner case I am exploring in my answer:
public class A {
static protected callMe(){
System.out.println("A");
}
}
public class B extends A {
static protected callMe(){
System.out.println("B");
}
}
public class C extends B {
static protected callMe(){
System.out.println("C");
C.callMe();
}
public void accessMyParents(){
A a = (A) this;
a.callMe(); //calling beyond super class
}
}
The answer remains still No, but just wanted to show a case where you can, although it probably wouldn't make any sense and is just an exercise.
Yes you can do it. This is a hack. Try not to design your program like this.
class A
{
public void method()
{ /* Code specific to A */ }
}
class B extends A
{
#Override
public void method()
{
//compares if the calling object is of type C, if yes push the call to the A's method.
if(this.getClass().getName().compareTo("C")==0)
{
super.method();
}
else{ /*Code specific to B*/ }
}
}
class C extends B
{
#Override
public void method()
{
/* I want to use the code specific to A without using B */
super.method();
}
}
There is a workaround that solved my similar problem:
Using the class A, B, and C scenario, there is a method that will not break encapsulation nor does it require to declare class C inside of class B. The workaround is to move class B's methods into a separate but protected method.
Then, if those class B's methods are not required simply override that method but don't use 'super' within that method. Overriding and doing nothing effectively neutralises that class B method.
public class A {
protected void callMe() {
System.out.println("callMe for A");
}
}
public class B extends A {
protected void callMe() {
super.callMe();
methodsForB(); // Class B methods moved out and into it's own method
}
protected void methodsForB() {
System.out.println("methods for B");
}
}
public class C extends B {
public static void main(String[] args) {
new C().callMe();
}
protected void callMe() {
super.callMe();
System.out.println("callMe for C");
}
protected void methodsForB() {
// Do nothing thereby neutralising class B methods
}
}
The result will be:
callMe for A
callMe for C
It's not possible, we're limited to call the superclass implementations only.
I smell something fishy here.
Are you sure you are not just pushing the envelope too far "just because you should be able to do it"? Are you sure this is the best design pattern you can get? Have you tried refactoring it?
I had a problem where a superclass would call an top class method that was overridden.
This was my workaround...
//THIS WOULD FAIL CALLING SUPERCLASS METHODS AS a1() would invoke top class METHOD
class foo1{
public void a1(){
a2();
}
public void a2(){}
}
class foo2 extends foo1{
{
public void a1(){
//some other stuff
super.a1();
}
public void a2(){
//some other stuff
super.a2();
}
//THIS ENSURES THE RIGHT SUPERCLASS METHODS ARE CALLED
//the public methods only call private methods so all public methods can be overridden without effecting the superclass's functionality.
class foo1{
public void a1(){
a3();}
public void a2(){
a3();}
private void a3(){
//super class routine
}
class foo2 extends foo1{
{
public void a1(){
//some other stuff
super.a1();
}
public void a2(){
//some other stuff
super.a2();
}
I hope this helps.
:)
Before using reflection API think about the cost of it.
It is simply easy to do. For instance:
C subclass of B and B subclass of A. Both of three have method methodName() for example.
public abstract class A {
public void methodName() {
System.out.println("Class A");
}
}
public class B extends A {
public void methodName() {
super.methodName();
System.out.println("Class B");
}
// Will call the super methodName
public void hackSuper() {
super.methodName();
}
}
public class C extends B {
public static void main(String[] args) {
A a = new C();
a.methodName();
}
#Override
public void methodName() {
/*super.methodName();*/
hackSuper();
System.out.println("Class C");
}
}
Run class C Output will be:
Class A
Class C
Instead of output:
Class A
Class B
Class C
In my simple case I had to inherit B and C from abstract class, that incapsulates equal methods of B and C. So that
A
|
Abstr
/ \
B C
While it doesn't solve the problem, it can be used in simple cases, when C is similar to B. For instance, when C is initialized, but doesn't want to use initializers of B. Then it simply calls Abstr methods.
This is a common part of B and C:
public abstract class Abstr extends AppCompatActivity {
public void showProgress() {
}
public void hideProgress() {
}
}
This is B, that has it's own method onCreate(), which exists in AppCompatActivity:
public class B extends Abstr {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); // Call from AppCompatActivity.
setContentView(R.layout.activity_B); // B shows "activity_B" resource.
showProgress();
}
}
C shows its own layout:
public class C extends Abstr {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); // Call from AppCompatActivity.
setContentView(R.layout.activity_C); // C shows "activity_C" resource.
showProgress();
}
}
This is not something that you should do normally but, in special cases where you have to workaround some bug from a third party library (if it allow to do so), you can achieve calling a super super class method that has already been overwritten using the delegation pattern and an inner class that extends the super super class to use as a bridge:
class A() {
public void foo() {
System.out.println("calling A");
}
}
class B extends A() {
#Overwrite
public void foo() {
System.out.println("calling B");
}
}
class C extends B() {
private final a;
public C() {
this.a = new AExtension();
}
#Overwrite
public void foo() {
a.foo();
}
private class AExtension extends A {
}
}
This way you will be able to not only call the super super method but also combine calls to other super super class methods with calls to methods of the super class or the class itself by using `C.super` or `C.this`.

Categories

Resources