Private access errors - java

I'm having trouble with a problem I'm working on for class.
The errors occurring are
TC1.java:17: error: myQuantity has private access in CheckItem
items[i].myQuantity=quantities[i];
and
TC1.java:20: error: myPrice has private access in CheckItem
a[i]=items[i].myPrice*((items[i].mySalesTax\100)+1);
This is the code I currently have.
public class CheckItem
{
private double myPrice,
mySalesTax;
private int myQuantity = 1;
public CheckItem( double price, double salesTax )
{
myPrice = price;
mySalesTax = salesTax;
}
public int getQuantity()
{
return myQuantity;
}
public void setQuantity( int qty )
{
myQuantity = qty;
}
public double lineItemTotal()
{
return roundMoney((myPrice*myQuantity)*((mySalesTax/100)+1));
}
public static double roundMoney( double amount )
{
return (int)(100 * amount + 0.5) / 100.0;
}
public static void setQuantities( CheckItem[] items, int[] quantities )
{
for (int i=0;i<quantities.length;i++){
items[i].myQuantity=quantities[i];
}
}
public static double[] lineItemTotals( CheckItem[] items )
{
double[] a=new double[items.length];
for (int i=0;i<items.length;i++){
a[i]=items[i].myPrice*((items[i].mySalesTax/100)+1);
}
return a;
}
}

The problem is that static methods can't access private instance variables. Define getters and setters for those variables, and use them:
items[i].setQuantity(quantities[i]);
a[i]=items[i].getPrice()*((items[i].getSalesTax()\100)+1);
and it will work.

This code compiles fine. If you are trying to access private members outside this class you would get private access error during compilation. In that case standard fix is to provide setters and/or getters.
** EDIT **
Seems like there is confusion about allowed access. You can NOT access any instance variables from static methods/context DIRECTLY! But you CAN access instance variables via instance itself as shown here:
class Test {
private int s = 123;
void instPrint() {
System.out.println(s); // fine
}
static void statPrint(Test ss) {
System.out.println(ss.s); // this is fine too!
// System.out.println(s); // does not compile obviously
}
}
This is the same case as in the code above. This has nothing to do with access modifiers because it's all happening in the same class.

Your code declares these two member variables in class CheckItem with the private scope. This means no other classes can access them directly on a CheckItem instance:
private double myPrice,
mySalesTax;
If you want class TC1 to be able to read or modify them, declare them in CheckItem.java as public. Alternatively, and generally a better practice, you could add public methods to CheckItem.java to allow other classes to access their values:
public double getMyPrice() {
return this.myPrice;
}
public void setMyPrice(double price) {
this.myPrice = price;
}
public double getMySalesTax() {
return this.mySalesTax;
}
public void setMySalesTax(double st) {
this.mySalesTax = st;
}
public int getMyQuantity() {
return this.myQuantity;
}
public void setMyQuantity(int newQty) {
this.myQuantity = newQty;
}
Then, in TC1.java you'd use these methods instead of direct access:
items[i].setMyQuantity(quantities[i]);
and
a[i]=items[i].getMyPrice()*((items[i].getMySalesTax()\100)+1);

Related

"Getter and Setter methods for all the member variables" what does it mean..?

In a project I want, Getter and Setter methods for all the member variables. how can i do this? and what does this mean?
the following is the code where i want to use getter and setter method
public abstract class Connection {
int previousReading;
int currentReading;
float[] slabs;
public Connection(int currentReading, int previousReading,float slabs[])
{
this.currentReading = currentReading;
this.previousReading = previousReading;
this.slabs = slabs;
}
public abstract float computeBill();
}
In order to achieve the desired design, you need to follow the Encapsulation concept (also known as 'Data hiding'), which is one of the basic OOP concepts.
What Encapsulation means is basically, wrapping the variables in accessors methods (called getters and setters) in order for them to be hidden from other classes.
The variables can be accessed only through those getters and setters and not directly.
In order to achieve this:
Declare the variables of a class as private.
Provide public setter and getter methods to modify and view the
variables values.
Example:
public class Person {
private String name;
private int age;
public String getName() {
return this.name;
}
public String setName(final String name) {
this.name = name;
}
public String getAge() {
return this.age;
}
public String setAge(final String age) {
this.age = age;
}
}
Why do we need Encapsulation for?
Using Encapsulation we can:
Control the allowed accessors of a variable (by declaring the access level as protected/public).
Limit the values that can be stored in a field.
Perform an action when a field is modified (perform validation, trigger an event, call another method).
Change the data representation (convert the input data type).
Provide thread safety using synchronization.
public class Connection {
private int previousReading;
private int currentReading;
private float[] slabs;
public Connection(int currentReading, int previousReading,float slabs[])
{
this.currentReading = currentReading;
this.previousReading = previousReading;
this.slabs = slabs;
}
public int getPreviousReading() {
return previousReading;
}
public void setPreviousReading(int previousReading) {
this.previousReading = previousReading;
}
public int getCurrentReading() {
return currentReading;
}
public void setCurrentReading(int currentReading) {
this.currentReading = currentReading;
}
public float[] getSlabs() {
return slabs;
}
public void setSlabs(float[] slabs) {
this.slabs = slabs;
}
}

How to handle the Duplicated blocks

I ran sonarqube, but it informed me the error
"Duplicated blocks" in class Gold & Silver.
I modified many things, but it didn't solve the problem
Here is my source
Gold and Silver is extends Plan
Here is a Plan.Source
public abstract class Plan {
public abstract double getBasicRate();
public abstract int getBasicMinute();
public abstract double getAdditionalLineRate();
public abstract double getRatePerExcessMinute();
public abstract String getPlanName();}
Here is Gold.Source
public class Gold extends Plan {
private static final double BASIC_RATE = 49.95;
private static final int BASIC_MINUTE = 1000;
private static final double ADDITIONAL_LINE_RATE = 14.50;
private static final double RATE_PER_EXCESS_MINUTE = 0.45;
private static final String PLAN_NAME = "Gold";
public double getBasicRate() {
return BASIC_RATE;
}
public int getBasicMinute() {
return BASIC_MINUTE;
}
public double getAdditionalLineRate() {
return ADDITIONAL_LINE_RATE;
}
public double getRatePerExcessMinute() {
return RATE_PER_EXCESS_MINUTE;
}
public String getPlanName() {
return PLAN_NAME;
}
}
Here is a Silver.Source
public class Silver extends Plan {
private static final double BASIC_RATE = 29.95;
private static final int BASIC_MINUTE = 500;
private static final double ADDITIONAL_LINE_RATE = 21.50;
private static final double RATE_PER_EXCESS_MINUTE = 0.54;
private static final String PLAN_NAME = "Silver";
public double getBasicRate() {
return BASIC_RATE;
}
public int getBasicMinute() {
return BASIC_MINUTE;
}
public double getAdditionalLineRate() {
return ADDITIONAL_LINE_RATE;
}
public double getRatePerExcessMinute() {
return RATE_PER_EXCESS_MINUTE;
}
public String getPlanName() {
return PLAN_NAME;
}
}
please help me
The code in Gold and Silver is identical, except from the data being assigned to the variables. You could refactor to something like this to remove duplication:
public class Plan {
private final double BASIC_RATE;
private final int BASIC_MINUTE;
private final double ADDITIONAL_LINE_RATE;
private final double RATE_PER_EXCESS_MINUTE;
private final String PLAN_NAME;
public Plan(double BASIC_RATE, int BASIC_MINUTE,
double ADDITIONAL_LINE_RATE, double RATE_PER_EXCESS_MINUTE,
String PLAN_NAME) {
this.BASIC_RATE = BASIC_RATE;
this.BASIC_MINUTE = BASIC_MINUTE;
this.ADDITIONAL_LINE_RATE = ADDITIONAL_LINE_RATE;
this.RATE_PER_EXCESS_MINUTE = RATE_PER_EXCESS_MINUTE;
this.PLAN_NAME = PLAN_NAME;
}
public double getBasicRate() {
return BASIC_RATE;
}
public int getBasicMinute() {
return BASIC_MINUTE;
}
public double getAdditionalLineRate() {
return ADDITIONAL_LINE_RATE;
}
public double getRatePerExcessMinute() {
return RATE_PER_EXCESS_MINUTE;
}
public String getPlanName() {
return PLAN_NAME;
}
}
Then Gold would look something like this:
public class Gold extends Plan {
public Gold() {
super(49.95, 1000, 14.50, 0.45, "Gold");
}
}
What we have done here is take code that is shared by 2 classes and moved it up into its parent class. By calling the super constructor in Gold we assign the variables to the values required by this implementation of the super class Plan.
We've also removed the static from the class variables. This means that the variables will be related to an instance of the class rather than the class itself.
We do this so that the variables in Plan will be related to each instance of Plan. This means we can use them in both the extending classes without data being mixed between.
In a lot of cases you wouldn't usually use static unless you actively wanted a variable to be accessible without a class instance. You can read more about static here.
I had this issue recently. Although you already have an accepted solution (and it's been 4 years), I would like to share another way.
I prefer to keep these constants as I find it more readable. A (soooo) simple solution was to rename the constant names ;) (i.e - prefixing them with SILVER_ or GOLD_).
KISS principle and it worked perfectly.
public class Gold extends Plan {
private static final double GOLD_BASIC_RATE = 49.95;
private static final int GOLD_BASIC_MINUTE = 1000;
private static final double GOLD_ADDITIONAL_LINE_RATE = 14.50;
private static final double GOLD_RATE_PER_EXCESS_MINUTE = 0.45;
private static final String GOLD_PLAN_NAME = "Gold";
public double getBasicRate() {
return GOLD_BASIC_RATE;
}
public int getBasicMinute() {
return GOLD_BASIC_MINUTE;
}
public double getAdditionalLineRate() {
return GOLD_ADDITIONAL_LINE_RATE;
}
public double getRatePerExcessMinute() {
return GOLD_RATE_PER_EXCESS_MINUTE;
}
public String getPlanName() {
return GOLD_PLAN_NAME;
}
If you really want to have a separate Gold and Silver class like this you can't avoid the duplicate code blocks. You could suppress the Sonar violations, either by adding the following line above the line causing the violation (see Sonar FAQ):
// NOSONAR
Alternatively you could use an enum to represent these values:
public enum Plan {
GOLD(49.95, 1000, 14.50, 0.45, "Gold"),
SILVER(29.95, 500, 21.50, 0.54, "Silver");
private double basicRate;
private int basicMinute;
private double additionalLineRate;
private double ratePerExcessMinute;
private String planName;
private Plan(double basicRate, int basicMinute, double additionalLineRate, double ratePerExcessMinute, String planName) {
this.basicRate = basicRate;
this.basicMinute = basicMinute;
this.additionalLineRate = additionalLineRate;
this.ratePerExcessMinute = ratePerExcessMinute;
this.planName = planName;
}
public double getBasicRate() {
return basicRate;
}
public int getBasicMinute() {
return basicMinute;
}
public double getAdditionalLineRate() {
return additionalLineRate;
}
public double getRatePerExcessMinute() {
return ratePerExcessMinute;
}
public String getPlanName() {
return planName;
}
}
This also avoids duplicated blocks but might not suit your needs.

Trying to get default value from the data definition class

Please consider two classes :
Data Definition Class :
public class A {
private int amount = 1000;
public A(int amount){
this.amount = amount
}
public int getAmount(){
return amount ;
}
}
Main Class :
public class B {
public static void main (String arg[]){
A a = new A(2000);
System.out.println("Amount:"+a.getAmount());
}
}
Since I am passing 2000 to the constructor, I am getting 2000 in the output. But I would like to keep a option of if the user doesn't specifiy any amount, it should print
the default value which is 1000 as mentioned in the private variable in data definition class.
Is there a way I can accomplish my task using the constructor?
public class A {
private int amount;
public A() {
amount = 1000;
}
public A(int amount) {
this.amount = amount;
}
public int getAmount() {
return amount;
}
}
You just need to create an empty constructor
public A(){
}
And in your main you will be able to do this:
A a = new A();
You can provide default constructor along with the one argument constructor you mentioned. This way user don't have to pass the amount if he don't want to while creating the object.
Create an empty constructor
public class A {
private int amount = 1000;
public A(){
}
public A(int amount){
this.amount = amount;
}
public int getAmount(){
return this.amount;
}
}

How to create a public static variable that is modifiable only from their class?

I have two classes:
class a {
public static int var;
private int getVar() {
return var; //Yes
}
private void setVar(int var) {
a.var = var; //Yes
}
}
class b {
private int getVar() {
return a.var; //Yes
}
private void setVar(int var) {
a.var = var; //No
}
}
Q: Can i make modifiable member only from his class, for other classes would be constant ?
No, the public access modifier basically allows you to modify the value of the reference from anywhere in your code base.
What you can do is have a private or less-restricted access modifier according to your specific needs, and then implement a getter, but no setter.
In the latter case, remember to add some logic to prevent mutable objects, such as collections, from being mutated.
Example
class Foo {
// primitive, immutable
private int theInt = 42;
public int getTheInt() {
return theInt;
}
// Object, immutable
private String theString = "42";
public String getTheString() {
return theString;
}
// mutable!
private StringBuilder theSB = new StringBuilder("42");
public StringBuilder getTheSB() {
// wrapping around
return new StringBuilder(theSB);
}
// mutable!
// java 7+ diamond syntax here
private Map<String, String> theMap = new HashMap<>();
{
theMap.put("the answer is", "42");
}
public Map<String, String> getTheMap() {
// will throw UnsupportedOperationException if you
// attempt to mutate through the getter
return Collections.unmodifiableMap(theMap);
}
// etc.
}
Just remove setter and make variable private. Then other class only can read the value stetted.
public class a {
private static int var=2;
public static int getVar() {
return var;
}
}
But when you come to Java reflection there is no such protection.
The answer Is NO you can't make a public static variable only modified from its class you can make the variable private and has only public getter or you can add setter private

Why do I get different results on variable value?

I'm kind of confused about the outputs.
This is the first program.
class A {
private int price;
private String name;
public int getPrice() {
return price;
}
public String getName() {
return name;
}
}
class B {
public static void main(String[] args) {
A a = new A();
System.out.println(a.getName());
System.out.println(a.getPrice());
}
}
This program compile without error. And the variables have values.
output -
null
0
Second program is,
class B {
public void value() {
int x;
System.out.println(x);
}
}
This program won't even compile.
B.java:4: error: variable x might not have been initialized
The question is why these variables act different? What is the reason.
This may be a very simple question. But kindly explain me.
Thanks.
Instance variables are declared inside a class. not within a method.
class A {
private int price; //instance variable
private String name; //instance variable
}
And instance variables always get a default value( integers 0, floating points 0.0, booleans false, String / references null).
Local variables are declared within a method.
class B {
public void value() {
int x; // local variable
}
}
Local variables must be initialized before use.
class B {
public void value() {
int x = 2; // initialize before use it.
System.out.println(x);
}
}

Categories

Resources