same variable name - java

The below two situations also have a same variable a in super class and subclass . Does any problem will be raised if using these coding style? thanks
situation 1
public class A {
int a;
void meth(int b) {
a+=b;
}
}
public class B extends A {
int a;
void meh2(int b) {
a+=b;
}
}
situation 2
public class A {
int a;
void meth(int b) {
a+=b;
}
}
public class B extends A {
int a;
void meh2(int b) {
a+=b;
}
B(int a) {
this.a=a;
}
}

Depends on how you classify it as a problem. It will work as I believe you will expect. In short, it's an ill-advised practice, but the 'a' in class 'A' (with or without the 'this.') will never be seen or used by class 'B' due to the overshadowing.

Any style that could create confusion should be avoided, because inevitably it will create confusion.
My advice here would be to remove the declaration of int a from class B - let it use the a field from class A

This does not explicitly cause an error. What you are doing is taking away your access to the a in class A and instead giving access only to a in class B

Related

Difference between the code with "this" and without it

I'm a beginner in Java programming and I'm having some problems to understand some concepts. I would like to know if both implementations are the same:
Code 1
public class MyThisTest {
private int a;
public MyThisTest(int a) {
this.a = a;
}
Code 2
public class MyThisTest {
private int a;
public MyThisTest(int b) {
a = b;
}
Yes, both are the same, let's see why:
First
public class MyThisTest {
private int a;
public MyThisTest(int a) {
this.a = a;
}
You are using this to refer the member variable a. The use of this is because by parameter there is another a variable. If you don't use this what variable will be assigned the value? The same as the parameter, so it doesn't take effect because it is 'auto-assign' the value.
Word this ensures tthe member variable is referenced. This is mostly used in constructors and getter/setters because the parameter name should be the same as the member variable name, so to handle the ambiguity this is used.
The second code
public class MyThisTest {
private int a;
public MyThisTest(int b) {
a = b;
}
Into constructor there is no ambiguity between variables, so this is not needed, but you can still use this and it works perfectly.
Yes both implementations are same. But I would highly recommend you to read about it in detail so that you don't make any future mistake. This answer goes in detail about when we should use this.
this keyword would be added by compiler.
Actually, if you write something like this
public class A {
private int a;
public A(int b) {
a = b;
}
}
Compile and then decompile it you can see the work of compiler
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//
public class A {
private int a;
public A(int b) {
this.a = b;
}
}
So, i would say avoiding this is just a usage of some syntax sugar.

How can I get the data fields from subclass not superclass?

I have a super class named TestSuper
public class TestSuper {
int a = 0;
}
and I have 2 sub classes named TestSub and TestSub2 that extend TestSuper
public class TestSub extends TestSuper{
int a=1;
}
public class TestSub2 extends TestSuper{
int a=2;
}
in my main class i created a method that takes in a type TestSuper and returns the a value of it and in the main i display it on the console
public class Main {
public static void main(String[] args){
System.out.println(test(new TestSub())+" "+test(new TestSub2()));
}
public static int test(TestSuper b){
return b.a;
}
}
but the output is "0 0" instead of "1 2", what do I do?
You need to cast the reference so say which one you want.
public static int test(TestSuper b){
return b instanceof TestSub ? ((TestSub) b).a :
b instanceof TestSub2 ? ((TestSub2) b).a :
b.a;
}
If this seems needlessly complicated, it is. You should use polymorphism instead.
public class TestSuper {
int a = 0;
public int getA() { return a; }
}
public class TestSub extends TestSuper {
int a = 1;
public int getA() { return a; }
}
public class TestSub2 extends TestSuper {
int a = 2;
public int getA() { return a; }
}
public static int test(TestSuper b) {
return b.getA();
}
First understand the difference between hiding and overriding: https://docs.oracle.com/javase/tutorial/java/IandI/override.html
Then create a getter method in the base-class which you can override in the subclass.
You can look into the theory behind this, and then do the only reasonable thing -forget about writing such kind of code.
In good OOP you consider your fields to be part of your "secret" internal implementation. You don't use fields of sub classes in the super class context. Period.
You are even very conservative about making a field protected in the superclass and to use that in subclasses.
When you call test method like this:
test(new TestSub())+" "+test(new TestSub2())
You use upcasting. Upcasting seperates interface and implementation for an object. But for seperating interface and implementation and achieving true implementation in polymorphism, you must use polymorphic structures. The instance variables aren't polymorphic. Because of this, actually you call a variable which is in TestSuper class.
Only instance methods are polymorphic.

Initializing a final variable in an abstract class (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.

how to find change value of any field of a class?

Let's say I have 2 classes A.java and B.java and there is private int a in A class like that :
public class A {
private int a;
}
and I use this class in class B that I want to know or attach an handler to the field int a;
that to know it's value change in every asynchronous call. Let me more explain :
public class B {
private A aClass;
public static void main (String ... args) {
aClass = new A(); // now the int a; is changed how do I know this
// user may call many asynchronous method in class A and I want to know
// the changing value of int a; from A class in B class
}
}
Which design pattern should I use? What solution do you offer?
Thanks in advance,
hilal
Observer pattern or here
B registers itself as the observer of A. A is the subject and B is the observer .
Whenever the "a" changes, A notify()'s all the registered Observer's.
public class A {
private int a;
private B observer;
void setA(int i) {
a = i;
observer.notify();
}
void registerObserver(B b) {
observer = b;
}
}
Add a B object in A, and recall B's method.
You could turn class A into a JavaBean and add support for PropertyListeners.
However, you first have to register one with your A() instance.

Java; casting base class to derived class

Why can't I cast a base class instance to a derived class?
For example, if I have a class B which extends a class C, why can't I do this?
B b=(B)(new C());
or this?
C c=new C();
B b=(B)c;
Alright let me be more specific as to what I'm trying to do. Here's what I have:
public class Base(){
protected BaseNode n;
public void foo(BaseNode x){
n.foo(x);
}
}
public class BaseNode(){
public void foo(BaseNode x){...}
}
Now I want to create a new set of classes which extend Base and Basenode, like this:
public class Derived extends Base(){
public void bar(DerivedNode x){
n.bar(x);//problem is here - n doesn't have bar
}
}
public class DerivedNode extends BaseNode(){
public void bar(BaseNode){
...
}
}
So essentially I want to add new functionality to Base and BaseNode by extending them both, and adding a function to both of them. Furthermore, Base and BaseNode should be able to be used on their own.
I'd really like to do this without generics if possible.
Alright so I ended up figuring it out, partly thanks to Maruice Perry's answer.
In my constructor for Base, n is instantiated as a BaseNode. All I had to do was re-instantiate n as a DerivedNode in my derived class in the constructor, and it works perfectly.
because if B extends C, it means B is a C and not C is a B.
rethink what you are trying to do.
The existing answers are fine in terms of an abstract argument, but I'd like to make a more concrete one. Suppose you could do that. Then this code would have to compile and run:
// Hypothetical code
Object object = new Object();
InputStream stream = (InputStream) object; // No exception allowed?
int firstByte = stream.read();
Where exactly would the implementation of the read method come from? It's abstract in InputStream. Where would it get the data from? It simply isn't appropriate to treat a bare java.lang.Object as an InputStream. It's much better for the cast to throw an exception.
In my experience it's tricky to get "parallel class hierarchies" like the one you're describing to work. You may find that generics help, but it can get hairy very quickly.
You need to use the instanceof keyword to check the type of object referenced by n and typecast the object and call the bar() method. Checkout Derived.bar() method bellow
public class Test{
public static void main(String[] args){
DerivedNode dn = new DerivedNode();
Derived d = new Derived(dn);
d.bar( dn );
}
}
class Base{
protected BaseNode n;
public Base(BaseNode _n){
this.n = _n;
}
public void foo(BaseNode x){
n.foo(x);
}
}
class BaseNode{
public void foo(BaseNode x){
System.out.println( "BaseNode foo" );
}
}
class Derived extends Base{
public Derived(BaseNode n){
super(n);
}
public void bar(DerivedNode x){
if( n instanceof DerivedNode ){
// Type cast to DerivedNode to access bar
((DerivedNode)n).bar(x);
}
else {
// Throw exception or what ever
throw new RuntimeException("Invalid Object Type");
}
}
}
class DerivedNode extends BaseNode{
public void bar(BaseNode b){
System.out.println( "DerivedNode bar" );
}
}
You can create a constructor for B that takes C as a parameter.
See this post for ideas to do what you're trying to do.
Base classes shouldn't know anything about classes derived from them, otherwise the problems highlighted above will arise. Downcasting is a 'code smell', and downcasting in the base class to a derived class is particularly 'smelly'. Such designs can lead to difficult to resolve circular dependencies too.
If you want a base class to make use of derived class implementations use the Template method pattern i.e add a virtual or abstract method in your base class and override and implement it in the derived class. You can then safely call this from the base class.
You can't do that because C does not necessarily implement the behaviours you created when you extended it in B.
So, say C has a method foo(). Then you know that you can call foo() on a B, as B extends C, so you can cast accordingly a treat a B as if it was a C with (C)(new B()).
However - if B has a method bar(), nothing in the subclass relationship says that you can call bar() on C too. Thus you cannot treat a C as if it were a B, and so you cannot cast.
In your exemple, you can cast n into a DerivedNode if you are certain that n is an instance of DerivedNode, or you can use generics:
public class Base<N extends BaseNode> {
protected N n;
public void foo(BaseNode x){
n.foo(x);
}
}
public class BaseNode {
public void foo(BaseNode x){...}
}
public class Derived extends Base<DerivedNode> {
public void bar(DerivedNode x){
n.bar(x); // no problem here - n DOES have bar
}
}
public class DerivedNode extends BaseNode {
public void bar(BaseNode){
...
}
}
Because if B extends C, then B might have stuff that isn't in C (like instance variables you initialize in the constructor that are not in new C())

Categories

Resources