I have studied data hiding in java theoretically but don't know what is happening inside. Every tutorial, states that unauthorized persons cant access the data of others.
Can anyone please give an example of what will happen without and with data hiding with two or three users programmatically?
Data Hiding is hiding internal data from outside users. This is achieved by making the attributes of your class private and not letting the objects of the class access it directly, instead we create getters and setters to access the private attributes.
Example:
//Without Data Hiding
public class Model{
public String name;
}
public class JavaApp{
public static void main(String args[]){
Model mObj = new Model();
mObj.name="abc"; // name = "abc"
}
}
//With Data Hiding
public class Model{
private String name; //private name
}
public class JavaApp{
public static void main(String args[]){
Model mObj = new Model();
mObj.name="abc"; // Error
}
}
Related
So, I have a program where many objects of several different classes need to read some (many) variables from an object of 'class X', to give it a name. A quick and simple way of doing this would be to make a singleton, which wouldn't be X itself but a class it access to. I've done this, and later on it started feeling dirty, and many seem to agree, so I'd like to change my design for this. I haven't found any ideas to replace this pattern, though, just "don't do it" and "pass the data around." I'd like my data to be read-only, though. I haven't found mention of any other patterns.
The best I've got to share these read-only variables, which seems perfectly fine to me, is to have a class SharedVars for the data to share, but in the form of an inner class. It's inside Data, which is an outer class that is able to modify SharedVars, encapsulating what's meant to be read-only for the other classes. Basically, any class that wants to read these variables needs a Data.SharedVars object:
public class Data {
public static class SharedVars {
private int encapsulatedData;
public int getData() {
return encapsulatedData;
}
}
// no one should touch this but Data:
static private SharedVars sharedData;
Data() {
sharedData = new SharedVars();
}
public SharedVars getDataRef() {
return sharedData;
}
// here's where this class (and only this class, whenever it's told)
// modifies the encapsulated data:
void manipulateData() {
sharedData.encapsulatedData = 5;
}
}
One of the classes that depends on this would take this form:
public class Client {
// This class can't access the data directly
// so it'll use Data's getter:
Data.SharedVars vars;
public Client(Data.SharedVars vars) {
this.vars = vars;
// vars.encapsulatedData = 5; // is not allowed, since the field is private (which is what I want)
}
public void go() {
// the proper way to get its hand on the data:
int data = vars.getData();
System.out.println("The data is " + data);
}
}
Main is not needed in this example, but I'll leave it here anyway:
public class Main {
static Data dataControl;
static Client client;
public static void main(String[] args) {
dataControl = new Data();
client = new Client(dataControl.getDataRef());
dataControl.manipulateData();
client.go();
}
}
Is this proper? Or, what are the risks here? Notice I don't want the objects to copy them for themselves, since they'll be changing all the time, and I don't entirely like the idea of having a reference to the 'class X' I've mentioned before.
Hey guys I have a class called UserData consisting of static fields, which is as follows:
public class UserData {
private static JSONObject fbProfilePicture;
private static boolean loggedOut=false;
private static Integer commonFriendID;
private static Integer userID1;
private static Integer UserID2;
private static JSONObject stolenTrio=null;
}
Actually the class contains alot more fields but I decided to show you a small version of my class.
In my app, I've a feature to delete account and create a new one, when I choose to do that, my app goes back to the sign up process, but there's a problem, I want to clear all fields of that class after deleting user.
How can I do that?
If you think you need a static / singleton kind of instance of UserData, I suggest doing it like this:
public class UserDataSingleton {
public static UserData userdata;
}
and make your UserData a simple Pojo with non-static fields.
This way you can reset your data with
UserDataSingleton.userData = new UserData()
Create a method that reset your values. You might want later to do more things into that method. Ex inform a listener that your object has been cleared.
I have a very stupid and elementary questions, however I can't seem to get around it. I am trying to pass data between 3 classes, so this is the approach I took:
Class A
public class GroupChat {
public String message;
public String myId;
public String otherID;
public GroupChat() {
}
public String getOtherID() {
return otherID;
}
public void setOtherID(String otherID) {
this.otherID = otherID;
}
public String getMyId() {
return myId;
}
public void setMyId(String myId) {
this.myId = myId;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
Class B - which generates the data on button click
GroupChat chat = new GroupChat();
chat.setParticipants(participants);
chat.setMyId(userId);
chat.setOtherID(id);
chat.setMessage(message);
When I print out the log of these variables in the GroupChat class, all is perfect.
However, when I attempt to use the getters to get data to class C, which is where I need them, they are returning a null value.
Class C
GroupChat chat = new GroupChat();
chat.getMessage(),
chat.getItemView(),
chat.getMyId(),
chat.getOtherID());
I even tried to log the data in the GroupChat class. When I enter the data, using the setters, everything is fine, however when logging the data on the getters, these are returning null. There must be something in the GroupChat class which is nullifying the variables.
Can someone please point me to the right direction?
Thanks a million.
Each time you call:
GroupChat chat = new GroupChat();
you are creating new object with default values (e.g. 0, nulls).
If you want to use your object "B" you have to return it from the function where you call setters.
E.g.
public GroupChat getDataAfterButtonPress() {
GroupChat chat = new GroupChat();
chat.setParticipants(participants);
chat.setMyId(userId);
chat.setOtherID(id);
chat.setMessage(message);
return chat;
}
Then, you can use this object later in your code:
GroupChat result = getDataAfterButtonPress();
It is hard to conclude without full code. The only problem I can see is that you use different instances in both case. When in class C, you create a new GroupChat instead of passing the one you create in class B.
A Piece of important information: The classes are all separate files and there are about 10 beans in total .
I am working on a project with multiple classes through which data must be passed.
I.e. a couple strings from say Class1 must be able to be used in Class2.
My program uses JavaBeans with set and get methods but if I set a bean in one class and try to get that data in another class I just get a null value returned.
I am unsure as to what the best method is, I have the beans nicely defined and would like to keep using them but I do not know how.
Could someone point me in the correct direction or give an example.
Thanks
Edit
Bean class snippet;
public class beans implements java.io.Serializable {
private String string1;
public String getstring1() {
return this.string1;
}
public void setstring1(String string1) {
this.string1 = string1;
}
And the setter code in say class1:
beans bean = new beans();
bean.setstring1("test");
And the class where the bet is "got", class2
beans bean = new beans();
String text = bean.getstring1();
That is pretty much how I am using the beans and they are not working as I want them to.
In your example you are creating a new bean in each class. The first and the second class have references to two different objects, that's why they can't access the same values.
There are multiple ways to solve this and it really depends on your application. But let me suggest one generic solution.
You can create a BeanRepository which is responsible for having references to all bean objects. Other classes then need to know the id of the bean and they can get a reference.
BeanRepository (notice the static methods):
public class BeanRepository {
private static Map<Integer, Bean> beanMap = new HashMap<Integer, Bean>();
public static void putBean(int id, Bean bean) {
beanMap.put(id, bean);
}
public static Bean getBean(int id) {
return beanMap.get(id);
}
}
The bean:
public class Bean {
private String name;
public Bean(String name) {
this.name = name;
}
public String whoAmI() {
return name;
}
}
Classes A and B:
public class ClassA {
private Bean bean;
public ClassA(int beanId) {
this.bean = BeanRepository.getBean(beanId);
}
public void test() {
System.out.println("I am ClassA. You are " + bean.whoAmI());
}
}
public class ClassB {
private Bean bean;
public ClassB(int beanId) {
this.bean = BeanRepository.getBean(beanId);
}
public void test() {
System.out.println("I am ClassB. You are " + bean.whoAmI());
}
}
Test method:
public class Main {
public static void main(String[] args) {
BeanRepository.putBean(1, new Bean("one"));
ClassA a = new ClassA(1);
ClassB b = new ClassB(1);
a.test();
b.test();
}
}
container I am very puzzled by your question. Are you referring to Enterprise Java Beans?
If you just mean ordinary JavaBeans just featuring get and set methods, the first thing I would advise is to learn how to use jUnit. Test your data bean first inorder to ensure it is working as intended.
Beside that if your class live within the same JVA (you only start a single java.exe / run a single application) everything should just work fine.
public class Data {
private String value;
public void set(String value) { this.value = value; }
public String get() { return this.value; }
}
public class ClassA {
Data data = new Data();
ClassA() { data.set("From ClassA"); }
}
public class ClassB {
Data data;
ClassB(Data data) { this.data = data; }
public void print() {
System.out.println(data.get());
}
}
public static void main(String args []) {
new ClassB(new ClassA().data).println();
}
This is a simple example using a data object to pass informations around.
Hope this is what you want to know.
[Update]
After you add some code I see the problem. As other users already wrote you are creating new objects (instances) every time. Since the string1 is a property of that class ever instance of it will have their own value.
The default example is a person. Creating a Person class with a property name (similar to your string1) you can create two persons (instances of class Person). You can now name every person individual.
Thats what Class mean. You specify the properties (instance variables) and behavior (methods) of instances (actual object) of that class.
If you want to share information you need a way to pass(!) an instance (object) of a Class to other instances. In Java different way exist. You can use static variables which are global (bound to the Class instead of an instance of a class), you can use singleton pattern (which employes the static variable), you can use ThreadLocal (a global store limited to the current thread), you may use managers / repositories storing objects and you pass the manager / repository objects along, you can use databases or you can use a dependency injector which is like a transparent object manager. Those are basically it.
For your use case I would use Singleton first.
public class MySingleton {
private static Bean myBean;
public static void setBean(Bean myBean) { MySingleton.myBean = myBean; }
public static Bean getBean() { return myBean; }
}
Using the class is straight forward:
Bean bean = new Bean();
bean.setString1("test");
MySingleton.setBean(bean);
Bean bean2 = MySingleton.getBean();
System.out.println(bean2.getString1()); //prints test
But beware this is the lazy way of doing things. Using static has some draw backs if you have a complex project especially when it comes to serialization, concurrency and reuse.
If you'se serializing/deserializing your classes, make sure that
string fields themselves are not marked as transient.
you're not using custom writeObject(ObjectOutputStream ) methods in your object where you forgot your string fields.
you're not cloning your class with custom clone() methods where you forgot your string field
you wrote setter and getter properly in the first place.
and things shoud work ;)
I want to build Data main class with subclasses DataClass1(with own subclass Item) and DataClass2 (with own subclass Item1).
public class Data{
public List<DataClass1> dataClass1List = new ArrayList<DataClass1>();
public List<DataClass2> dataClass2List = new ArrayList<DataClass2>();
public class DataClass1{
public String name;
public List<Item> itemList = new ArrayList<Item>();
public class Item{
public String n1;
public String n2;
public String n3;
}
}
public class DataClass2{
public String name;
public List<Item1> item1List = new ArrayList<Item1>();
public class Item1{
public String n5;
public String n6;
}
}
}
When I want to fill main class Data I use this code:
Data data = new Data();
Item itm = new Item;
itm.n1="1";
itm.n2="2";
itm.n3="3";
data.dataClass1List.itemList.add(itm);
and same for dataClass2List
All sub classes must be public
Is there better way to declare and filling up my class Data
Thanks!!!
p.s. Data class and its sub classes contain only variables not methods!
You seem to be confusing some concepts here.
There are no subclasses in your code. DataClass1 and DataClass2 are inner classes of Data, Item is an inner class of DataClass1 and Item1 is an inner class of DataClass2.
There's no visible need for them to be inner classes, and you're best off avoiding inner classes until you're sure you need them and likely until you know Java a bit better.
With these as inner classes, your proposed usage of them will not work, as they're non-static inner classes, and can only be created within the context of an instance of the outer class.
With the class definitions as they are, a translation of your posted usage would be approximately
Data data = new Data();
DataClass1 dc1 = data.new DataClass1();
Item itm = dc1.new Item();
itm.n1="1";
itm.n2="2";
itm.n3="3";
dc1.itemList.add(itm);
data.dataClass1List.add(dc1);
But this is really quite bad (and it may contain mistakes - I have bothered trying to compile it). Having classes with only fields and no methods, and adding data in this way is not a very object-oriented approach at all.
As WirthLuce noted in a comment, you should change the names to represent something in your domain, and create methods to make them do something appropriate rather than just holding data that is manipulated from outside.
Some suggesions:
You should use getter and setter to access the different fields.
public class SomeClass {
private String name;
[...]
public void setName(String name) {this.name = name;}
public String getName() {return name;}
[...]
}
Since the Data classes are public, do they need to be inner class?
To fix this you would need to move the different public class to different files.
All internal lists could be made `final`.
public final List<Item> itemList = new ArrayList<Item>();
You could make a constructor for the class Item.
public class Item {
public Item(String n1,String n2,String n3) {
this.n1 = n1;
this.n2 = n2;
this.n3 = n3;
}
[...]
}