How to inherit a private variable in Processing? - java

[I know the following does not respect OOP rules, this is an early-dev project. I will do all the setters and getters later]
I have a class called 'Item', which contains a private field 'name'.
abstract class Item{
protected PImage texture;
protected int durability;
protected int maxDurability;
private String name;
}
I also have a class called 'Armor', which inherit 'Item'. So it should inherit the private field 'name', right ?
class Armor extends Item{
protected int defense;
Armor(){
//First try to change the value
name = "Armor";
//Second try using 'this' to be sure it doesn't try to change super.name
this.name = "Armor";
}
}
In both cases, I have an error when I try to change the value : "The field Time_Fighter.Item.name is not visible".
After reading some stuff about how 'private' works in Processing, I discovered some people proposed to use 'protected' instead.
The thing is, if I use 'protected', every classes have access to it. But I just want 'Item' and the subclasses of 'Item' to have access to their private fields inherited from 'Item'.
I might have done a pretty obvious error since I'm kinda just a beginner, so if this is not the intended way of doing so, please tell me how I'm supposed to do it...
[Edit.
It seems from answers I've seen that this is not possible this way. So here's there any way to have a variable that would only be accessible for subclasses and not all the package ?]

You can't.
Private variables are just that: private. That means a subclass can't access them.
You might instead add a setter() function that the subclass uses.
Normally you would just make it protected, but Processing doesn't use packages, so it ends up being the same as public.
Honestly, I wouldn't worry too much about this. Processing is designed to make things simple, so it skips over this topic a bit. If you really want this functionality, you might consider writing Java code (which can call Processing code), but that's a lot more involved than just writing Processing directly.
In your case, you might create a constructor in your Item class that takes a name as a parameter. Then you can call that constructor from your Armor class and pass in whatever value you want:
abstract class Item{
private PImage texture;
private int durability;
private int maxDurability;
private String name;
public Item(String name){
this.name = name;
}
}
class Armor extends Item{
private int defense;
Armor(){
super("Armor");
}
}

You can make your name field protected and place your Item and Armor classes to a separate package. Fields declared as protected are available to the classes of the same package and descendant classes.
See Controlling Access to Members of a Class

you can access all class-global variables even private ones via Reflection How do I read a private field in Java? . I use this a lot and it works pretty fine. So if someone really wants to access the variables he can most of the time.

Related

How could private modifier guard the encapsulation of an object, not class?

In Java, I understand why we define the instance field as private in some class, that is for protecting the encapsulation of a class. However, I am confused about the instance of that class. See below:
public class DotaHero {
private String name;
...
}
Till now, any outer class could not use the name directly! Then,
DotaHero zeus = new DotaHero();
zeus.name = "Zeus";
That is legal in Java. However, anyone who hate me would change my code easily, like:
zeus.name = "Chick";
Then, when I use object zeus to invoke the "zeusWrath" skill, it will show a script on screen, "The Chick is Furious!".........
Maybe someone would argue I was supposed to use setter method to define the name, and configure some checking mechanisms inside. However, my opponent still could directly access the name by zeus object.
I am sure I am misunderstanding something, but I can't find it...

How to access a non-static private field in java?

I have a non-static private field in a package and want to access it from another package but I don't know how to do that. I searched but I didn't find anything useful and other questions in this site weren't exacatly my question.
The only way you can do this is via reflection. But it's a hack. You really ought to be finding another way round it.
If you need to do it, then it suggests that the other package has a badly designed structure. If the class you're trying to manipulate is one of your own, you should look at changing that code.
If you really need to do it and you can't change the other class, you do it with something like this:
Field f = BadClass.class.getDeclaredField("privateField");
f.setAccessible(true);
f.set(badClassInstance, newValue);
Probably the best places to start are a tutorial on reflection, and the setAccessible method.
Create getter and setter methods for the private fields.
example:
public void setName ( String name )
{
this.name = name;
}
public String getName ()
{
return this.name;
}
You should import the package where that non-static private field is.
If you want to access this field from subclass which is in a different package you can change "private" modifier to "protected", this will allow all packages in the same project access this field through inheritance.

using a variable in two different java classes

I was wondering if it's possible to use a variable of a java class in another java class.Suppose variable Time is defined and calculated in Class A, how can I use it in Class B?
Other answers have suggested increasing a variable's visibility. Don't do this. It breaks encapsulation: the fact that your class uses a field to store a particular piece of information is an implementation detail; you should expose relevant information via the class's API (its methods) instead. You should make fields private in almost all cases.
Likewise, some other answers have suggested possibly making the variable static. Don't do this arbitrarily. You need to understand what static really means: it's saying that this piece of information is related to the type rather than to any one particular instance of the type. Occasionally that's appropriate, but it's generally a road towards less testable code - and in many cases it's clearly wrong. For example, a Person class may well have a name variable, but that certainly shouldn't be static - it's clearly a piece of information about a single person.
You should think carefully before exposing information anyway - consider whether there's a wider operation which the class in question could expose, instead of just giving away its data piecemeal - but when you do want to expose a field's value, use a property. For example:
public class Person {
private final String name;
public Person(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
By exposing it via a method, you can later change the implementation details without breaking existing clients.
Then from another class, you'd just call the getName() method:
// However you end up getting a reference to an instance of Person
Person person = ...;
String name = person.getName();
If you do have a static field, you can expose the value in the same way, but with a static method, which you'd call using the class name.
Be careful about returning values which are mutable, e.g. java.util.Date. This is another reason for using a getter method instead of allowing direct access to the field - you can make the method return a defensive copy where you need to.
If it is declared as public, you may use ClassA.yourVariable. On the other hand, for private access modifier, include the getter to your ClassA. On the ClassB, call ClassA.getYourVariable().
Also read about access specifiers in Java it might help.
If the variable is static, you can refer to it as A.Time from any code that has access to the variable. There's only one Time value for all of class A. If it is an instance variable, and you have an instance a of class A, you can refer to the variable as a.Time. There's a separate value for each instance of class A.
This is subject to Java's access rules:
if the field is public, any code can access it (this makes public variables kind of dangerous unless they are also declared final)
if the field is protected, only code in the same package or in a subclass of A can access it
if the field has default access, only code in the same package as class A can access it
if the field is private, only code in class A (including inner classes of A) can access it.
Alternatively, you can provide an accessor method in class A:
public class A {
. . .
public class getTime() {
return this.Time; // the "this." is optional
}
}
If you declare your Variable as public or static you will be able to access it from another class.
WHICH IS A VERY VERY BAD IDEA :)

Confused with Java Encapsulation Concept

Good day!
I am reading a Java book about encapsulation and it mentioned the getter and setter method.
I've read that to hide the attributes, I must mark my instance variables as "PRIVATE" and make a "PUBLIC" method of getter and setter to access the data. So I tried making a similar but not the conventional code about it as follows:
public class AddressBookEntry {
private String name;
private String address;
private String telNo;
private String email;
public void getAllInfo() {
name = JOptionPane.showInputDialog("Enter Name: ");
address = JOptionPane.showInputDialog("Enter Address: ");
telNo = JOptionPane.showInputDialog("Enter Tel. No: ");
email = JOptionPane.showInputDialog("Enter Email Address: ");
}
}
Does my code above exposes my variables because I assigned it directly? How can I do this better? Would it be better if I make the conventional getter and setter method instead and assigned the values on the other class? What does "hiding the data" means?
Thank you.
You use setters and getters to make the variables accessible from outside your class. In your example you will have
public class AddressBookEntry {
private String name;
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
You will access the name property from a UI class (it isn't good to mix UI and business logic in the same class):
public class MyPane extends JFrame {
public getAllData() {
String name = JOptionPane.showInputDialog("Enter Name: ");
AddressBookEntry entry = new AddressBookEntry();
entry.setName(name);
// You can't use entry.name = name
}
}
Yes and no. The point of encapsulation is that it prevents other classes from needing to know what your class is doing behind the scenes. If you store your name in a String (as you've done here), read/write it from a file, or do something different, the point of encapsulation is that to the user of your class it doesn't matter because all they see is String getName( ) and void setName (String name).
Since the modification of the data is entirely under the control of your class here, it doesn't break encapsulation. If you did store name to file, then you could potentially do so in getAllInfo without any other user of the class being any the wiser. Since the observable behaviour from the outside of the class still hides what the internals of the class is doing, it's still encapsulated.
That said, this is a very unconventional approach. Like I describe in the first paragraph, use of accessor methods (getters and setters) is a more idiomatic approach, and easier to understand for someone else using your code. You can do what you do, it doesn't break encapsulation, but it's not what I'd call elegant or typical.
The idea of private class members (attributes, fields) is to access them directly inside the declaring class (not instance!) only. All other classes will have to use other accessors, for example getter and setter methods. So the way how the AdressBookEntry stores the name, address, telNo and email values, is perfectly hidden inside the class.
You don't have to use getters or setters, although, sometimes there are good reasons to do so inside the class too. Using getters and setters sometimes makes sense if you do some logging or validating before a value is set.
This doesn't violate encapsulation, as it doesn't expose the internal data to another class. You may wish to look at Model-View-Controller (MVC) though to help separate out your interface from your data.
Traditional you create a single getter and setter for each variable as needed like so:
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
Don't create getters for variables that won't need to be accessed outside of the class, and don't create setters for variables that won't need to be set outside of the class.
If following MVC and using the traditional getters and setters like above, you would have the view code elsewhere and call something like
myAddressBookEntry.setName(JOptionPane.showInputDialog("Enter Name: "));
I agree with all the great answers provided. I would like to add another great benefit about using encapsulation and is the fact that by hiding the data from its clients (just as the examples described above) you can guarantee how to set and get these instance variables making your class easier to maintain and test (i.e if you have many clients manipulating your objects variables you don't need to go class by class writing the new functionality, instead you just modify the getter and setter).
By making usage only of the objects setters and getters, the details of its implementation can be hidden from the outside world. This is a nice advantage so other objects attempting to interact with your class won't be able to break its functionality. This also increases the likelihood that a system will be implemented effectively.
I find the answers above already answering your question. But, I see another issue with your code, which is, a security and data integrity issue. You are filling your class member directly out of the user's input w/o any validations on it. For example, you'd probably want to check that the email address has an xyz#abc.com pattern. A malicious user might also provide a very long string in the input causing unexpected errors.

inheritance: accessing array from super class to search it

I have a superclass Trail that populates an array myList[]. I want a subclass TrailSearch to access myList[] and search it. How can i do this? I know i could simply pass the array to the TrailSearch class as an argument but i'm trying to get to grips with inheritance so i thought i try it the hard way but i need some tips.
PSEUDO CODE
class Main{
new Trail trailObject
new TrailSearch tsearchObject
tsearchObject.methodSearchMyList()
}
class Trail{
constructor Trail(){}
methodPopulateMyList(){
// populate myList[] }
}
class TrailSearch extends Trail{
constructor TrailSearch(){}
methodSearchMyList(){
// search myList[] }
}
that's more or less how i would approach it but what are the rules to make this inheritance idea work?
Inheritance is the wrong way to solve this problem, and this is the wrong problem to use if you are trying to get to grips with inheritance. TrailSearch is not a Trail so shouldn't inherit from it.
A better solution to this problem is the visitor pattern: http://en.wikipedia.org/wiki/Visitor_pattern
Also see
http://msdn.microsoft.com/en-us/library/27db6csx%28v=vs.80%29.aspx for a brief explanation of the "Is A" relationship which implies inheritance.
As long as the myList[] array is not declared private your subclass can access it directly.
Try to define myList[] as a protected variable in class Trail, then you can access the variable from your subclass also
In java, for each field and method, you must declare the visibility. This will determine who can access this field or this method. Visibility is declared with a keyword, which is one of these :
public : The field or method can be accessed from everywhere
private : Only the class where the field / method is declared can access it
protected : Only the class and its subclass can access the field / method.
There's a fourth visibility, called the "package visibility" which takes place when no keyword is specified : the field / method can be accessed within the same package. This visibility isn't used very often.
Here's a little example :
public class A {
public int var2; // this is a public variable
protected int var3; // this is a protected variable
private int var1; // this is a private variable
public void test() { } // this is a public method
protected void test3() { } // this is a protected method
private void test2() { } // this is a private method
}
You can see in my little example, that my class also has a visibility, the exact same rules as for fields and methods are used, only for instantiation instead of accessibility.
In your case, there's two different solution to allow access to your field from the subclass :
declare the field as public, protected or without visibility (ie package visibility)
declare the field as private, and add a setter, getter or others access methods. This is the preferred method and it is called encapsulation.
Since this is probably a homework, I won't provide code to you, it will be a good exercise to write it yourself.
PS: I know that encapsulation is a little more than just what I explained, but dropping the name like that won't hurt the OP ;)

Categories

Resources