Java private constructor with parameters [duplicate] - java

This question already has answers here:
Can a constructor in Java be private?
(16 answers)
Closed 4 years ago.
newbe question. Does it make any sense to have a private constructor in java with parameters? Since a private constructor can only be accessed within the class wouldn't any parameters have to be instance variables of that class?

Yes, if you are going to use that constructor in some method of your class itself and expose the method to other class like we do in the singleton pattern. One simple example of that would be like below :
public class MySingleTon {
private static MySingleTon myObj;
private String creator;
private MySingleTon(String creator){
this.creator = creator;
}
public static MySingleTon getInstance(String creator){
if(myObj == null){
myObj = new MySingleTon(creator);
}
return myObj;
}
public static void main(String a[]){
MySingleTon st = MySingleTon.getInstance("DCR");
}
}

Suppose that you have multiple public constructors with the same variable to assign to a specific field or that you need to perform the same processing, you don't want to repeat that in each public constructor but you want to delegate this task to the common private constructor.
So defining parameters to achieve that in the private constructor makes sense.
For example :
public class Foo{
private int x;
private int y;
public Foo(int x, int y, StringBuilder name){
this(x, y);
// ... specific processing
}
public Foo(int x, int y, String name){
this(x, y);
// ... specific processing
}
private Foo(int x, int y){
this.x = x;
this.y = y;
}
}

Related

How to differentiate between the private instance variable and a parameter having same name in java

There is a keyword this in java to access the instant variables which are public. But is there such way to access the private ones
class Foo {
private int a = 2;
public int b = 3;
public void test(int a, int b) {
this.b = b;
//but how to access a;
}
public static void main(String args[]) {
Foo x = new Foo();
x.test(1, 2);
}
}
Above is the code example I have....
Within the same class, both private and public variables can be accessed in the same way:
class Foo {
private int a = 2;
public int b = 3;
public void test(int a,int b){
this.b = b;
this.a = a; // accessing private field a
}
public static void main(String args[]){
Foo x = new Foo();
x.test(1,2);
}
}
All class methods have access to their own private members. Hence, this.a = a will work.
Follow Java tutorial on this keword it can access private members:
private int x, y;
public Rectangle(int x, int y, int width, int height) {
this.x = x;
A class object can access it's private members, otherwise nothing could access them and they'd be quite pointless. So this with private members works absolutely fine.
Class method have an access to private data member so you can use
this.a=a

Final variable and Constructor Overloading

I want to use Constructor Overloading in my class and I also would like to have some final variables to define.
The structure I would like to have is this:
public class MyClass{
private final int variable;
public MyClass(){
/* some code and
other final variable declaration */
variable = 0;
}
public MyClass(int value){
this();
variable = value;
}
}
I would like to call this() to avoid to rewrite the code in my first constructor but I have already defined the final variable so this give a compilation error.
The most convenient solution I have in mind is to avoid the final keyword but of course it is the worst solution.
What can be the best way to define the variable in multiple constructors and avoid code repetitions?
You are almost there. Rewrite your constructors such way that your default constructor call the overloaded constructor with value 0.
public class MyClass {
private final int variable;
public MyClass() {
this(0);
}
public MyClass(int value) {
variable = value;
}
}
If you have small number variable then it is ok to use Telescoping Constructor pattern.
MyClass() { ... }
MyClass(int value1) { ... }
Pizza(int value1, int value2,int value3) { ... }
If there is multiple variable and instead of using method overloading you can use builder pattern so you can make all variable final and will build object gradually.
public class Employee {
private final int id;
private final String name;
private Employee(String name) {
super();
this.id = generateId();
this.name = name;
}
private int generateId() {
// Generate an id with some mechanism
int id = 0;
return id;
}
static public class Builder {
private int id;
private String name;
public Builder() {
}
public Builder name(String name) {
this.name = name;
return this;
}
public Employee build() {
Employee emp = new Employee(name);
return emp;
}
}
}
You can not assign final variable in both constructors. If you want to keep the final variable and also want to set via constructor then one possibility that you will dedicate one constructor to set the final variable and also include common code functionality needed by the class. Then call this from another constructor like this(*finalVariableValue*);

Adding specific values for inherited fields

I am having some trouble with inheritance (Student here). I need to be able to utilize 1 inherited private field for each subclass I make. Obviously subclasses cannot have access to inherited fields however when a new object is created that inherited private field is a part of that object. For my purposes though each subclass needs to have it's own specific value for that inherited field. My first attempt looks something like this:
Public class A {
private int x = 0;
public A(int n) {
x = n;
}
public int useX() {
return x;
}
}
Public class B Extends A {
int n = 1;
public B() {
super(n);
}
useX(); // Return 1?
}
Public class C Extends A {
int n = 2;
public B() {
super(n);
}
useX(); // Return 2?
}
However my professors tell me that I could also be using a setter method inside of my Super class to create that new field, and from there I am confused. Can anyone help point me in the right direction?
An ordinary Java Bean provides public accessors and mutators (aka getters and setters) for it's fields. However, you could provide a protected setter. Something like,
public class A {
private int x = 0;
public int getX() { // <-- the usual name.
return x;
}
protected void setX(int x) {
this.x = x;
}
}
Then your subclasses can invoke that setter
public class B extends A {
public B() {
super();
setX(1);
}
}
And then B.getX() (or B.useX() if you really prefer) will return 1.

What's the correct way to "share" variables between methods in different classes?

I'm trying to share variables between methods in different classes, but I don't know if I'm doing this in the correct way. Basically when I wanna use the variables on method2 I have to "transport" them throught method1 to method2 from the Class A, just take a look at the example because I don't know how to explain this properly.
Is this the correct way to do it? Because sometimes I do this over an over through methods and it looks ugly.
Example:
public class A {
int var1, var2, var3;
B b = new B();
b.method1(var1, var2, var3);
}
public class B {
public void method1(int var1, int var2, int var3){
//doSomething
method2(var2, var3);
}
public void method2(int var2, int var3){
//doSomething
}
}
Btw, is there any community where code reviews are done? I'm pretty new to code and I'm afraid that I'm creating code that isn't effective.
Thanks for the help! :)
Use getters and setters to get variable of Class A from B as following..
public class A {
private int var1, var2, var3;
public int getVar1(){
return var1;
}
public void setVar1(int var1){
this.var1 = var1;
}
public int getVar2(){
return var2;
}
public void setVar2(int var2){
this.var2 = var2;
}
public int getVar3(){
return var3;
}
public void setVar3(int var3){
this.var3 = var3;
}
}
public class B{
// Use var 1 from class A as following
A a = new A();
int x = a.getVar1(); //x has the value of Var1 now
a.setVar1(2); // var1 in class A has value 2 now.
}
Use interfaces rather than directly call a method of another class.
public class A {
private InterfaceB interfaceB;
interfaceB.method1(var1, var2, var3);
}
public interface InterfaceB{
public void method1(int var1, int var2, int var3);
public void method2(int var2, int var3);
}
public class B implements InterfaceB{
#Override
public void method1(int var1, int var2, int var3){
//doSomething
method2(var2, var3);
}
#Override
public void method2(int var2, int var3){
//doSomething
}
}
You should read about encapsulation.
Passing 3 variables encapsulated in 1 object with appriopriate accessors sounds like a better option to me (at least the code looks a bit cleaner).
Also, think of creating a utility class with static methods if it makes sense of course - sometimes you do not need class member fields at all because there is no state to this class (Math class is an example) and static methods that return the result of some calculation/transformation is a better option.
On a side note I can recommend you considering "Program to an interfaces" principle. You can read the relevant section right on the top of this page.
In B class, you declare a instance of A class, variables in A class is public. when you can use variable in A class.
Here is my 2 cents...
public class Sample {
//Property of the class
private int valueA;
//method to do some operation
//that relies explicitly on a
//property of the class
public void doSomething(){
//valueA is over 9000!?
int valueA = valueA + 9000;
}
//Method that does something that does not explicitly
//rely on a property of the class
//could be called from this or another class
public int doSomeOperationWithSomething(int something){
return something++;
}
}
Another alternative would be to create a static "utility" class for your methods
public class Utils{
public static int doMagic(int var){
return var * var;
}
}
used like this,
int num = Utils.doMagic(9);
These come about when you have some code that does that one useful thing, but you just can't figure out where to put it.
More importantly, you will want to maintain proper "encapsulation" (Read about that) in your code. This means limiting access to variables by other classes and allowing access to only what is needed.
public class Website {
//No one should ever be able to
//access this variable directly
//So we set it a private
private String article;
//A reader should be able to get the aricle
public String getArticle(){
return article;
}
//The reader should never be able to set
//an aticle on the website only read it
//You can leave this part out or
//set the method to private as i did.
private void setArticle(String article){
this.article = article;
}
}
public class Reader {
//Reference to website
private Website website;
public Reader(){
...
//the user can read an article
website.getArticle();
// but this is not available to them
website.setArticle("Some text"); // results in ERROR
}
}

Math operations with static and non static variables

Can I multiply a static and a non static variables, like this:
public class C {
protected int c;
private static int s;
public int ma() { return this.c*this.s; }
}
Or:
public class B{
protected int x;
private static int y;
public static int ms() { return x + y; }
}
The second code is not working and I am wondering is it because it's expecting static?
The second block of code is not working because ms is static. You cannot reference non-static members (x) from a static context.
You need to either make ms a non-static function or make x a static variable.
Like this:
public class B{
protected static int x; // now static
private static int y;
public static int ms() { return x + y; }
}
Or like this:
public class B{
protected int x;
private static int y;
public int ms() { return x + y; } // now non-static
}
A static variable/function is one that is shared across the application. In your second example
public class B{
protected int x;
private static int y;
public static int ms() { return x + y; }
}
Your method is declared static and is therefore a static context. Rule of thumb: You can't access non-static things from a static context. Here is some reasoning as to why that is.
Say you have two objects of type B one where x=1 and one where x=2. Since y is static it is shared by both objects. Let y=0.
Suppose from somewhere else in your program you call B.ms(). You're not referring to any particular B object. Therefore the JVM is unable to add x + y because it doesn't know what value of x to use. Make sense?

Categories

Resources