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.
Related
I know I'm asking some serious 101 question here...
I have some class Foo and a class Bar that extends Foo. In Foo I have a constructor that takes a set of parameters that it sets to its fields. Deriving classes such as Bar will typically not need to modify this. Now my IDE is giving me "There is no default constructor available in Foo". From a bit of Googling this appears to be because "constructors are not inherited". So all nice and well, but how do I now get this to work without duplicating this constructor in every deriving class? I'm assuming there is a more sane approach?
Use the super constructor:
public Bar(int a, double b, ...) {
super(a, b, ...);
}
So all nice and well, but how do I now get this to work without duplicating this constructor in every deriving class?
You do need to duplicate the constructor signatures - if you want the subclass to have constructors with the same signatures. But you don't need to duplicate the code - you just chain to the superclass constructor:
public Bar(int x, int y) {
super(x, y);
// Any subclass-specific code
}
Of course if you can work out the superclass parameters from a different set of parameters, that's fine. For example:
public Bar(int x) {
super(x, x * 2);
// Any subclass-specific code
}
You really need to work out what information is required to construct a Bar - that should dictate your constructors.
If this is a problem, it's possible that you're overusing inheritance. It's hard to say for sure without any idea of what your actual classes are, but you should look at using composition instead of inheritance. It's no panacea, but it can avoid this sort of thing.
No, there's no more "sane" approach. If your base class has no default constructor, then you must explicitly call the correct constructor from all the children classes.
Note this doesn't mean children classes need to have the exact same constructor than base class. For example this is perfectly valid:
class Foo {
protected int a;
protected int b;
protected Foo(final int a, final int b) {
this.a = a;
this.b = b;
}
}
class Bar extends Foo {
protected Bar() {
super(0,0);
}
}
The problem is solved with this:
class Foo{
Foo(int a, int b){}
}
class Bar extends Foo{
//Here must be a constructor OR declare a constructor in Foo without parameters
Bar(){super(1,1)} //this is an example
}
Other solution is:
class Foo{
Foo(int a, int b){}
Foo(){}
}
class Bar extends Foo{
}
Remember that if have a constructor with parameters in the SuperClass (in this case Foo), the implicit constructor on the child class (in this case Bar), always will have a implicit call to "Super()" (always have to be one unless explicit).
This error could also happen because you are calling your super constructor last. You might have to move it to be the first statement:
public SectionsPagerAdapter(FragmentManager manager, List<Fragment> fragmentList) {
mFragmentList = fragmentList;
super(manager);
}
public SectionsPagerAdapter(FragmentManager manager, List<Fragment> fragmentList) {
super(manager); --> this should come first
mFragmentList = fragmentList;
}
JVM will not provide a default constructor if you have provided one due to design reasons. What you can do define constructor in Bar with same signature and call super().
public Bar(int x,int y) {
super(x,y);
}
If parameters are not required and/or have default values then you can define default constructor (without parameters):
class Foo
{
public final int DEFAULT_A = 42;
protected int a;
protected int b;
public Foo(final int a, final int b)
{
this.a = a;
this.b = b;
}
// Is equal to new Foo(Foo.DEFAULT_A, 0);
public Foo()
{
this.a = this.DEFAULT_A;
}
}
class Bar extends Foo {}
class PiBar extends Bar
{
public final int DEFAULT_A = Math.PI;
}
Maybe this question was asked here before, but I couldn't find it here.
It is basic question for Java developers, but here it goes: lets say I have class A with attribute a. What is the difference between these 2 constructors:
public abstract class A
{
protected String a;
public A()
{
a = "text";
}
}
The second one:
public abstract class A
{
protected String a;
public A()
{
this.a = "text"; //Here is the same with this
}
}
In the case you've given, there's no difference. Typically this is used to disambiguate between instance variables and local variables or parameters. For example:
public A(String a) {
this.a = a; // Assign value from parameter to local variable
}
or
public void setFoo(int foo) {
this.foo = foo;
}
Some people prefer to always use this.variableName to make it clearer to anyone reading the code; personally I find that if the class is well designed and the methods are short enough, it's usually clear enough already and the extra qualification just adds cruft. YMMV.
There is no difference in your specific case. But let's think about a constructor with an argument which has the same name as an attribute:
public abstract class A {
protected String a;
public A(String a) {
this.a = a;
}
}
In that specific case, this.a is referring to the a attribute of class A, while a is referring to the local parameter
There is no difference at all, unless there is shadowing involved:
public abstract class A
{
protected String a;
public A(String a)
{
this.a = a; // assign external one to inner
}
}
vs
public abstract class A
{
protected String a;
public A(String a)
{
a = a; // assign inner one to inner one
}
}
From docs and with your same example ,
The most common reason for using the this keyword is because a field is shadowed by a method or constructor parameter.
There is no difference between the constructor this reference is used to automatically pass address of the caller object.
In the doJob() method, B is referenced through getter. I personally do not favor this idea and would prefer just b.execute() since I know for sure that getB() will never be modified.
I know that by doing this, would be moving away from encapsulation, but isn't encapsulating B object an overkill here?
class A{
private B b;
public void setB(B b){
this.b = b;
}
public B getB(){
return b;
}
public void doJob(){
getB().execute();
}
}
It really doesn't matter if you access B through its attribute or getter as long as the attribute remains private (so yes, calling getB() is an overkill, it certainly doesn't break any design pattern).
In this scenario it's probably overkill because it's a simple object. But what if there was lazy loading and your object looked like this..
class A{
private B b;
public void setB(B b){
this.b = b;
}
public B getB(){
this.b = this.b ?? new B();
return this.b;
}
public void doJob(){
getB().execute();
}
}
Then it's not overkill to access your private members via a property.
I don't know if this will help you, but if B is a dependency then your object should be setup like this where IB is the interface of the concrete object B. It's an inversion of control pattern to decouple the concrete object B from A. But this is overkill for simple object graphs as well
class A{
private IB b;
// Use inversion of control
public A(IB b){
this.b = b;
}
public IB getB(){
return this.b;
}
public void doJob(){
getB().execute();
}
}
You are minimizing risk by using the getter. What if it turns out the B was null in one use case or you need to initialize B because of a new requirement. This pattern allows you to update getB() without having to change anything else in A.
public B getB(){
if(b == null) {
b = getEntityManger().findB(); // or wherever you wanted to get B from
}
return b;
}
Providing accessor/mutator methods for a private member enables you to add error checking, change the storage of the member, and do other things internal to the class. How you access the member within the class is your choice.
If you discover you need to change the class internals later, then switching to the accessor/mutator can be done then. Certainly this simple example does not require the accessor (getter) method. But realize that a more complex case might benefit by using the getter.
That is ok only if you make the whole class, or at least make the setter and getter, final.
Otherwise this breaks:
class A2 extends A {
private B2 b;
#override
public void setB(B b){
this.b = new B2(b);
}
#override
public B getB(){
return b.toB();
}
}
Now calling the non-overriden doJob() will use wrong member variable.
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
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.