When can I access an objects variable using object.variable? - java

Probably a simple question I should by now. I'm writing some code for a class and I have 1 class that I have 3 instance variables of
class LruC {
int counter
int RAM_address
boolean valid_invalid
constructor takes no parameters
methods
private class Page {
private Page () {
count = 0;
invalid_valid = false;
}
}
Then I have the nested class Page inside of LruC. In some of my methods that are inside the LruC class I'm creating instances of the Page object, then I'm trying to access their variables by just doing Page.count or Page.invalid_valid and I'm getting compile time errors saying it doesn't recognize the variables.
When is it feasible to access an objects variable by just doing object.variable_name? Does it have something to do with the fact that the count and invalid_valid variables are not inside the Page class? I thought since it was nested it would have access to all those variables?

I could not quite understand how the relationship between your two classes. But it seems like a problem with scope of your variables (protected, private or public). One class can access public variables of another class. If you haven't but any statement before your variable the compiler assumes it is private, therefore you can not access from another class. You need to put public before your variable or create a Get method which returns the variable.
Note: this is a very simple answer so and I am assuming that all your classes are in separate files and none of your classes extends or implements each other.

Related

Accessing private method from different instance of the same class

I just came across a code.In one case i am not able to access the private members of the class using its instance (which is fine) but in other case i am able to access the private members with its different instance (belongs to the same class). Can anyone please explain me why its happening?
class Complex {
private double re, im;
public String toString() {
return "(" + re + " + " + im + "i)";
}
Complex(){}
/*Below c is different instance, still it can access re,im( has a private access)
without any error.why? */
Complex(Complex c) {
re = c.re;
im = c.im;
}
}
public class Main {
public static void main(String[] args) {
Complex c1 = new Complex();
Complex c2 = new Complex(c1);
System.out.println(c1.re); /* But getting an error here ,
which is expected as re and im has a private access in Complex class.*/
}
}
You can access private members from any code block that is defined in the same class. It doesn't matter what the instance is, or even if there is any instance (the code block is in a static context).
But you cannot access them from code that is defined in a different class.
Your first reference is in the same class, Complex, which is why it works. And the second is in a different class, Main, which is why it doesn't work.
The reason is class Main cannot access to private fields of other classes. In this case to the private fields of Complex class.
You can access to private fields in Complex class only from methods in this class. In other words, if you move main method to Complex class the code will be compiled.
If you want to get/set values in Complex class from Main (or other classes) you should add setters/getters in Complex class.
Here is the table explaining access modifiers:
As you can see, in the private row, everything is N except for the column Class. That means you can access private members as long as you are accessing them in the same class as they are declared. You can even access private non-static members from a static context in the same class using an instance. There is no access modifier that only allows access from the same instance.
Why?
Because figuring out whether this and c are the same instance at compile time is a pain. You have to actually run the code to see if they are referring to the same instance or not.
Conceptually the access specifiers are # class level, not # instance level.
Following could be the reasons to keep access specifiers # class level.
From JLS Documentation, we can clearly see that the access is for users, who are implementing(or using a class/package) based on the contract.
To put in simple terms, as a developer(users) all I am concerned is what are the members(variables,methods) available, and what they do, how I can use them(the base of abstraction concept).
In your case, it is the same class and it has all the privilege to access its member and hence the observed behaviour.

How do I call variables and methods from other classes?

I'm doing a homework assignment, and I need to create methods in one class "coinDispenser", and call them in the main class, "HW1"
I'm not sure how this works, however. This is a sample of my code in coinDispenser.java:
private int numNickles = 0;
And then calling the method later in HW1.java:
System.out.println("There are "+numNickles+" nickles in the machine.")
But I always get the error "numNickles cannot be resolved to a variable" and it wants me to create the integer in the HW1 class.
How do I call the integer from within HW1.java? Changing the integer to public int type doesn't make any difference.
Well, you definitely can't access a private member variable from one class to another. In order to access a public member in a different class, you need to either make a static variable and reference it by class, or make an instance of CoinDispenser and then reference that variable.
So, in CoinDispenser, it'd be:
public int numNickles = 0;
and in HW1, you'd have:
CoinDispenser cd = new CoinDispenser();
System.out.println("There are "+ cd.numNickles + " nickles in the machine.")
If you did a static variable you could also do:
CoinDispenser.numNickles
To call a method in another class, you have two options.
Option 1:
You can declare the method to be called as static, which means that it doesn't need to be called on an object.
NOTE: If you take this route, (which you shouldn't; it's generally bad to use static methods), you have to declare numNickles as static, meaning that there is only one instance of this field no matter how many CoinDispenser objects you create.
Example:
static void methodToCallName(any arguments it takes) {
//...do some stuff...//
}
Option 2: You can create an instance of the class using the new keyword which contains the method and call the method:
Example:
// in some method in the HW1 class (Which is a horrible class name, see java conventions)
CoinDispenser dispenser = new CoinDispenser(any parameters here);
coinDispenser.whateverYourMethodIsCalled(any arguments it takes);
The whole idea of classes in an object oriented language is to keep separate things separate. When you reference a variable defined in another class, you have to tell the program where it is.
I get the sense that you haven't really learned what it means to be object oriented, and you really should look more into it. You can't fake it; there is NO getting around object orientation. You must learn to love it. Sure, it can make simple things hard, but it will make hard things soo simple.
For the second bits of your question...
Please note that numNickles should in fact be private, contrary to what other users are saying.
Java best practices advocate encapsulation, which is basically a principle saying that other parts of your program should only be able to see what they need to and the inner workings of each class should not be exposed to other classes.
How do you achieve this? Simple; use accessor and mutator methods (getters and setters) to access and modify your fields.
// Define your field like usual...
private int numNickles = 0;
// ...and add these two methods...
public void setNumNickles(int value) {
numNickles = value;
}
public int getNumNickles() {
return numNickles;
}
This may seem like a lot of work for a variable, but many IDE's will automate the process for you, and it will save you from many frustrating bugs in the long run. Get used to it, because the rest of the Java world does it.
If numNickes is in another class you can't call it since it is scoped private.
If you want access to private scoped variables you have to write a method to return it. The convention is typically
public int getNumNickles(){
return numNickles;
}
This is by design and allows the protection of variables that you do not want to expose.
Your output would then be
System.out.println("There are "+myclass.getNumNickles()+" nickles in the machine.")
Alternatively you could make the variable public
public int numNickels;
But now it can be read from, and written to, by anyone using the class.
You are trying to access the field named numNickles from your CoinDispenser class (BTW CoinDispenser is the correct name for your java class). You can not directly access the fields and methods in your HW1 class. So, as MadProgrammer has indicated in the comment under your question, follow along as that.
In your HW1.java class have something like:
CoinDispenser cd = new CoinDispenser();
System.out.println("There are "+cd.getNumNickles()+" nickles in the machine.");
The "cd" in above line of code is your handle on the CoinDispenser class. With cd, you can access (by dotting) fields and methods from any class where you use the above lines. Further, you will still not be able to access the fields and methods in your CoinDispenser class if those fields and methods are "private".
The standard way to access a private field in another class is to use a getter method.
This would be like
private int numNickles = 0;
public int getNumNickles () {
return numNickles;
}
Also useful would be a setter method
public void setNumNickles (int numNickles) {
this.numNickles = numNickles;
}
Many IDE's (e.g. Eclipse) will automatically create these methods for you upon a click of a button.
These methods can then be called upon an instance of a CoinDispenser class.
CoinDispenser coinDispenser = new CoinDispenser ();
coinDispenser.setNumNickles (23);
System.out.println("There are "+ coinDispenser.getNumNickles() + " nickles in the machine.");
First of all, there is no variable name numNickels which cause the error to occur.
Second, to access the attribute of the class coinDispenser, you will need to create an object of that class, that is
coinDispenser a=new coinDispenser();
By doing so, you can then access public methods of the class coinDispenser. Considering that the attribute numNickles is private, you have two options, which is:
1. Change numNickles to public, then access it using
a.numNickles
2. Create a public method to get private attribute in class coinDispenser
public int getNumNickles() {return numNickles;}
and access it from HW1 using
a.getNumNickles()
Java is an Object-Oriented Programming language. This means in essence, that everything is based on the concept of objects. These objects are data structures that provide data in the form of fields and methods. Every class that you provide an implementation of, needs a form of an instance, to actually do something with it.
The following example shows that when you want to make an instance of a class, you need to make a call using newCoinDispenser(100). In this case, the constructor of the class CoinDispenser requires one argument, the amount of coins. Now to access any of the fields or methods of your newly made CoinDispenser, you need to call the method using variable.method(), so in this case coinDispenser.getCoins() to retrieve the title of our book.
public class CoinDispenser {
private int coins = 100; // Set the amount of coins
public int getCoins() {
return coins;
}
}
public class HW1 {
public static void main(String[] args) {
CoinDispenser coinDispenser = new CoinDispenser(100);
System.out.println("I have " + coinDispenser.getCoins() + " left.");
}
}
NB: We are using an extra method getCoins(), a getter, to retrieve the contents of the field coins. Read more about access level here.

Accessing methods from / within difference classes, newb

I am still fairly new to java, so please bear with me.
I am having trouble understanding why it is that I can only access certain methods / functions that belong to an instance of an object from certain classes / places/. Once I create an instance of an object and then press the dot "." operator it does not bring up all the methods that I want to use for it, (I want to see all the methods that the objects class inherits and implements.)
For example:
// In a junit test class, I make an instance of the class DailyLog which takes 2
// integers
private DailyLog log; // which seems fine for now, but when I add on the next
// line:
log = new DailyLog (5,500); // It gives me an error on the semicolon on the line
// above saying "- Syntax error on token ";", , expected"
I do not understand why it will not let me create an instance of DailyLog and set it's paramaters...?
Question 2: If I just leave the first line of code in, then set the parameters of log within a method in the same class, it lets me set it's parameters, but when I press the "." operator, It does not show me the size function, which is the function I want to use. - I thought it would inherit size from a superclass, so why does it not let me use it?
Question 3: I have a method within the dailyLog class called variance, and another called numInsertions, I need to use the numInsertions method within the variance method, but when I write below, the only way I can get to the numInsertions method is through another method, and this will not work as i need to access the numInsertions method to directly to assign it's value to b, not through another method as this will change it's value.
public Integer variance() throws SimulationException{
Integer a = log.
I think it might have to do with scope, when I have another class which creates an instance of dailyLog, and when I press the ". operator on it, it gives some methods to use from the daulyLog class and it's superclass, but not all of them. I find this quite confusing, and help would be appreciated, thanks.
UPDATE**
Maybe putting more code here will help to illustrate my problem:
public class dailyLog implements Log{
private Integer userLogSize1;
private Integer maxEnt;
private ArrayList<Integer> log = new ArrayList<Integer>();
public dailyLog (Integer userLogSize, Integer maxEntry) throws SimulationException{
if ((userLogSize<= 0 || maxEntry <= 0)){
throw new SimulationException("message goes here");}
this.log = new ArrayList<Integer>(userLogSize);
for (Integer i = 0; i <= userLogSize; i++){
log.add(null);}
userLogSize1= userLogSize;
maxEnt = maxEntry;
}
public Integer numInsertions(){
Integer total = 0;
for (Integer i = 0; i < log.size(); i++){
if (log.get(i) != null){
total++;}}
return total;}
// *** below I want to write log.numentries but i cannot, why it this? I can only write
// log.get(numentries()) but that gives the wrong answer.
public Integer variance() throws SimulationException{
if (log.size() == 0){
throw new SimulationException ("Put message here");}
Integer a = log.get(0);
Integer b;
Integer d = log.get(1);
if (d == null){
b = log.get(numInsertions()-1);}
else {b = log.get(numInsertions()-2);}
Integer c = log.get(userLogSize1-1);
if ( c == null){
return a - b;}
return a-c;}
}
I think you are seeing the different protection levels in Java. For the members and methods of a class, there are generally four protection levels: private, public, protected, package-private. If a method or object is not prefixed with one the keywords private, public, protected, then it is by default package-private.
A method or class member which is private can only be referenced within the same class in which it is declared.
A method or class member which is public can only be referenced from any class in any package.
A method or class member which is protected can only be referenced from the same class and subclasses.
A method or class member which is package-private can only be referenced from within the same package. If you are developing with the default package (that is, you have not declared a package), then your code will generally treat package-private exactly as it would treat public, since all classes are defaulted to the default package.
Here is a reference and here is another question which explains the same ideas in less words.
if you're trying to pass a method from one class to the other, and you don't want to make it static, meaning it would be shared across all instances, you can create a new instance of the class in a different class. For example say you have class A and class B:
public class A {
private int a;
private void setA(int a) {
this.a = d;
and class B:
public class B {
private int b;
private void setB(int b) {
this.b = b;
so then I can call all of class A's methods by invoking a constructor from it:
public class B {
///Constructor line
private A a = new A();
A.setA(10);
System.out.println(A.a); ///should print 10
You need to understand modifiers (i.e. private, public, protected, and package-level). Every field of a class and method of a class (both static and non-static) has a modifier. If you don't specify one, then it is "package-level". You don't specify modifiers inside a code block (e.g. a method body) because it is assumed that the scope of such variables is the inside block. Just a quick example of a block-scope, the following is legal in Java:
public int foo(){
{
int max = 0;
for(int i = 0; i < 10; ++i)
if(i > max)
max = i;
}
final int max = -10;
return max;
}
In a nutshell you have the following (note that constructors would be considered methods in the following):
public: Anything can access this method or field. For fields, this means any class can set this field unless it's declared final. You should be very aware though that even an object declared final can be modified (such as an array or any other mutable object). For methods, this simply means any class can call this method.
private: Only this class can access this field or method. This means that the only place you can modify these fields or call these methods is within this class file. An instance of this class can access fields from another instance of this class (through some method written inside this class's body that references some other object instance of this class).
protected: Any class that is either in the same package as this class or a subclass of this class (could be in a separate package) has direct access to a protected field or method.
package-level: To specify package-level access, you do not specify any modifier at all (i.e. public, private, or protected...nothing). In this case, any class within this package has access to this field or method.
The better question is when should you use which? Most methods should be public and most fields should be private as a general rule. You should be very weary of people who claim that these things are for "security". The only way to ensure data integrity of an object is to only return primitive values or immutable objects or copies of mutable objects. As a quick example, let's say you implement an ArrayList (a dynamic array). Internally, you probably have an array object such as private int[] arr. If you return this array object in any public method then you run the risk of the calling class modifying the internal array and making your ArrayList inconsistent.
I would follow these guidelines:
Fields
public: Only declare a field public if it is also final and an immutable object or primitive. This should be used for persistent objects who's field never changes (i.e. once it's set in the constructor this public final field will never be changed).
protected: This should primarily be used in abstract classes. That is the abstract class declared a data structure which its subclasses can use and reference (and modify). If this is something like a list it may still be appropriate to declare it final (that is something the sub-class can modify, but not reassign).
package-level: This should primarily be used by auxiliary classes in a package. They generally shouldn't be final (although if they are things like a list that may be appropriate). As a quick example. If you implement a heap, you may want the heap nodes to hold information about what element they are storing and where they are in they heap's array. The heap is really responsible for setting this, so by declaring it package level, your heap implementation can directly access and reassign things like the heap index and heap value for each of its heap nodes.
private: Private fields are most common. Most fields should be private. This means that only methods in this class file can modify or reassign this field. This should be used when you want to guarantee the behavior of a class. If you use any other modifiers, then the behavior of this class's data may be dictated by other classes.
As for methods, it's pretty simple. A public method should be something that any class can call to query the object without disrupting the data integrity of the object (i.e. the method should not be capable of putting the object into an inconsistent state which means public methods should not, in general, return mutable fields). Private, protected, and package-level methods should all be helper methods which are used to improve modularity. Basically it depends on "who" you trust. If the method is private then you only trust this class to call it correctly. If it's package level, then you only trust classes in this package to call the method correctly. And finally if it's protected, then you only trust classes in this package and sub-classes to call this method correctly.

Object Oriented, passing variables or using object state

Hi apologies for the basic question, im sure I've been told the answer before and I've spent some time searching but couldn't find a good answer (probably because its hard to phrase as a search query), I've done a little bit of OO programming before but ive done a lot of procedural stuff recently so that seems to be clouding my thoughts.
I have a program that has to work with strings, part of that program involves sanitising a string, so I have this method:
private void sanitizeString() {
removeEscape();
removePunctuation();
removeCaps();
}
And earlier in the class declared the variable
String x = "... some string ..."
In procedural you would obviously pass all of the functions the string that they need to work on, my question is in OO is it ok to have this string declared at the top of the class and then just do something like
private void removeCaps() {
x = x.toLowerCase();
}
or should it be
private String removeCaps(String y) {
y = y.toLowerCase();
return y;
}
I think this it should be the first way, and I know that that works ok, but im doing something that has to demonstrate good OO so I just want to check I have my basic assumptions right.
Thanks
You have a trade off here:
Declaring the variable as a class variable means that you must create a new object for each String you want to sanitize.
Passing the String variable to each method means that you can reuse the same object to sanitize multiple Strings.
You must weigh the advantages and disadvantages of each approach to decide which is most appropriate for your particular situation.
Since x is declared as class variable, this one is fine:
private void removeCaps() {
x = x.toLowerCase();
}
as class variables are accessible inside class methods and you don't need to pass the class variables as arguments to same class methods
Same class variables are accessed this way only. Very simple example could be POJO classes, where you declare class variables and expose them through getter/setter methods. You don;t need to pass the class variables to these methods and some time, you can't(e.g. in getter methods).
Adding some thoughts around class variable vs. local variable in the method.
If there is a need of a variable which is theoretically associated with the class definition then the variable should be defined as class variable. e.g. employeeId, employeeName.. variables in a employee class should be defined as Employee class variables.
If there are variable needs which are local to a class method only and not required anywhere outside the method/class, then it should be defined as local variable inside the method.
If you are defining some utility methods to respond using some variables then those variables should be passed as argument to the util methods.
Back to your question:
If you are defining a entire class e.g. Sanitising, which has several methods around the string variable e.g. String class itself, then better to define your string as class variable and write the methods using the class variables.
But if you are defining Sanitising as a util/helper class then better to pass the string as method argument as normally you don;t want your util methods to be statefull (associated with the class instance).
To demonstrate good OO, you should definitly use
private String removeCaps(String y) {
return y.toLowerCase();
}
You can pass your Object, in this case your String in the global field x to the method as parameter. The String is then in the local field y and return the modified version.

What's the equivalent of C's "static" keyword in Java?

I want to know what could be the equivalent keyword in java which could perform same function as "Static keyword in C".. I want to do recursion in java, performing same function that a static keyword in C does...
Please help..
C has two entirely different uses of the static keyword, and C++ adds a third use:
// Use 1: declare a variable or function to be local to a given module
// At global scope:
static int global_var;
static void func();
In this case, the global variable global_var and the function void func() can only be accessed inside the file in which they are declared; they cannot be accessed by any other file.
// Use 2: declare a variable inside a function with global scope
void func(void)
{
static int x;
}
In this case, the variable x is effectively a global variable, in that there is only one instance of it -- multiple calls to func() (including recursive calls) will always access the same variable.
// Use 3 (C++ only): declare a global variable with class scope
class Widget
{
public:
static int var;
};
In this case, this declares the variable Widget::var as a global variable, but its scope is different. Outside of class member functions, it has to be named as Widget::var; inside class member functions, it can be named as just var. It can also be made protected or private to limit its scope even more.
Now, what are the analogs of these 3 uses in Java?
Case 1 has no direct analog; the closest is declaring objects with package scope, which is done by omitting a public, protected, or private:
class Widget // Declare a class with package scope
{
int x; // Declare a member variable with package scope
void func() {} // Declare a member function with package scope
}
In this case, the declared objects are only accessible by classes within the same package; they are not accessible to other packages.
Case 2 also does not have an analog in Java. The closest you can get is by declaring a global variable (that is, a static class variable, since Java doesn't have true global variables in the strictest sense):
class Widget
{
private static int func_x;
public static void func()
{
// use func_x here in place of 'static int x' in the C example
}
}
Case 3 is the only case that has a direct analog in Java. In this case, the static keyword serves exactly the same purpose.
The "static" keyword in C actually serves two functions depending on where it's used. Those functions are visibility and duration (these are my terms based on quite a bit of teaching, the standard, if you're interested in that level of detail, uses different terms which I often find confuses new students, hence my reticence in using them).
When used at file level, it marks an item (variable or function) as non-exported so that a linker cannot see it. This is static as in visibility, duration is the same as the program (i.e., until the program exits). This is useful for encapsulating the item within a single compilation unit (a source file, in its simplest definition). The item is available to the whole compilation unit (assuming it's declared before use).
When used within a function, it controls duration (visibility is limited to within the function). In this case, the item is also created once and endures until the program exits. Non-static variables within a function are created and destroyed on function entry and exit.
I gather what you're after is the first type, basically a global variable since I can't immediately see much of a use for the other variant in recursion..
It can't be done since, in Java, everything must belong to a class. The workaround is to create a class holding the "globals" and either:
pass that object around so you can reference its members; or
construct a singleton item so you can access its members.
Java doesn't have global variables, so there isn't a direct equivalent. However, there's a static keyword in Java that shares the state of a field with all instances of a class, which is a good approximation to what you're describing.
I want to do recursion in java, performing same function that a static keyword in C does...
However, if you're looking to do recursion, are you sure that static variables are what you need? Any special state needed for a recursive function call is almost always passed back to itself, not maintained separately.
The concept of static in Java doesn't adhere with the concept of static in C. However, there is a static keyword in Java as well. But its more like a static in C++ then C, with some differences.
You can simulate a static class in java as follows:
/**
* Utility class: this class contains only static methods and behaves as a static class.
*/
public abstract class Utilities
{
// prevent inheritance
private Utilities()
{
}
// ... all your static methods here
public static Person convert(string) {...}
}
This class cannot be inherited (like final because although abstract it has a private constuctor), cannot be instantiated (like static because abstract) so only static methods in it can be called.

Categories

Resources