Java - conditional access to methods of a class - java

I am having to java classes track and Session.
The track class...
package trackmanagement;
public class track {
private String trackName, networkingEventTime;
private Session morningSession, afternoonSession;
track(String name)
{
trackName = name;
}
public void alloteSession()
{
morningSession = new Session("Morning Session", trackName);
afternoonSession = new Session("Afternoon Session", trackName);
}
}
The Session class...
package trackmanagement;
import java.util.ArrayList;
public class Session {
private String sessionName, relatedTrack, startTime, endTime;
private ArrayList<Slot> allotedSlots;
public Session(String name, String track)
{
sessionName = name;
relatedTrack = track;
}
public void morningSlots()
{
}
public String afternoonSlots()
{
return "";
}
}
In the method alloteSession in class track, I am making two objects of class Session with names morningsession and afternoonsession.
The class Session contains two methods namely morningSlots and afternoonSlots.
I want only morningSlots method to be accessed from morningsession object while afternoonSlots is private for morningsession object.
Similarly, afternoonSlots method should be accessed from afternoonsession object while morningSlots is private for afternoonsession object.
Thus there should be a conditional privacy for the methods. The method morningSlots should be public for morningsession object while it should be private for afternoonsession object and vice-versa.
Is it possible to do this, if not please suggest some other way to implement this kind of design.

Instead of trying to change the method visibility from one class or another, you could create 2 classes morningSession & afternoonSession which would extend session.
session could be an abstract class with the method slots() which would need to be implemented in morningSession & afternoonSession.
From the implementation point of view when you create sessions it is either morningSession or afternoonSession but in both case you can call the slots() method which will invoke the correct method

You should change your design instead of trying something that's not possible in Java :)
public abstract class Session {
public abstract String getSlots();{//try to have methods that describes a verb/action
}
public class MorningSession extends Session{
public abstract String getSlots(){
return "Morning slot received";
}
}
public class AfternoonSession extends Session{
public abstract String getSlots(){
return "Afternoon slot received";
}
}
By doing this, you wrap the implementation and let your Child Classes Morning/AfternoonSession to get the required slots.

Related

Read only objects produced by a factory in Java

In previous C++ code I've used friend classes when creating a factory that can output "read only" objects which means that as the objects are consumed throughout the code there is no risk that they can be inadvertently changed/corrupted.
Is there is there a similar way to implement this in Java or am I being overly defensive?
Make use of the final keyword. This keyword can mark a class/methods as non-extendable, and mark fields/variables as non-mutable.
You will hide the default constructor of the object using the private constructor, and force parameterised constructors which will initialise all necessary final fields.
Your only problem is that the factory is kind of redundant. Since all fields of the object are final, you will have to use all factory methods at object build-time.
Example:
public final class DataObject
{
protected final String name;
protected final String payload;
private DataObject()
{
}
public DataObject(final String name, final String payload)
{
this.name = name;
this.payload = payload;
}
}
// Using the factory
DataObject factory = new Factory().setName("Name").setPayload("Payload").build();
// As opposed to
DataObject dao = new DataObject("Name", "Payload");
// ==> Factory becomes redundant, only adding extra code
Solution without final:
I'm afraid you will have to forget about the immutability mechanism of C++. The factory pattern is never a bad choice if you have huge data objects (i.e. with a lot of setters), but you can't really avoid mutability of the constructed object. What you could do, is make the data object an inner class of the factory, and make the setters private. That way, ONLY the factory can access the setters. This would be the best approach for you (i.e. simulate immutability).
Example:
public class Factory
{
private String name;
private String payload;
public Factory setName(final String name)
{
this.name = name;
}
public Factory setPayload(final String payload)
{
this.payload = payload;
}
public DataObject build()
{
DataObject newObj = new DataObject();
newObj.setName( this.name );
newObj.setPayload( this.payload );
return newObj;
}
public class DataObject
{
// fields and setters, ALL PRIVATE
}
}
You can either put the object class and factory in the same package, and make the mutable methods package-scoped (this is the default visibility in Java, simply don't declare the methods to be public, private or protected), or make the class truly immutable and do all the work in the constructor. If you find that there are too many arguments in the constructor and it is difficult to understand, consider the Builder Pattern.
There is no direct equal to friend classes in Java. However have a look at http://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html.
If your object implements an interface and the factory returns interface type rather than the concrete type (which is better) then you can use java.lang.reflect.Proxy to create dynamic proxy at runtime that intercepts all method calls to the target object. As in the following code example FooFactory class creates a Foo instance (every time its createFoo method is called) but does not directly return instance but instead returns a dynamic proxy that implements the same interface as Foo and dynamic proxy intercepts and delegates all method calls to the Foo instance. This mechanism can be helpful to control access to a class when you dont have class code.
public class FooFactory {
public static IF createFoo() {
//Create Foo instance
Foo target = new Foo(); // Implements interface IF
//Create a dynamic proxy that intercepts method calls to the Foo instance
IF fooProxy = (IF) Proxy.newProxyInstance(IF.class.getClassLoader(),
new Class[] { IF.class }, new IFInvocationHandler(target));
return fooProxy;
}
}
class IFInvocationHandler implements InvocationHandler {
private Foo foo;
IFInvocationHandler(Foo foo) {
this.foo = foo;
}
#Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
if (method.getName().equals("setMethod")) {
// Block call
throw new IllegalAccessException();
} else {
// Allow call
method.invoke(proxy, args);
}
return null;
}
}
class Foo implements IF {
public void setMethod() {
} // method that is not allowed to call
public void getMethod() {
}
}
interface IF {
void setMethod(); // method that is not allowed to call
void getMethod(); // method that is allowed to call
}
The closest thing to a C++ friend class in Java is package-private access.
SomeObject.java:
package somewhere.someobjandfriends;
public class SomeObject {
Object aField; // field and constructor
SomeObject() {} // are package-only access
public void aMethod() {
System.out.println(this);
}
}
SomeObjFactory.java:
package somewhere.someobjandfriends;
public class SomeObjFactory {
public SomeObject newHelloWorld() {
return new SomeObject() {
{
aField = "hello world!";
}
#Override
public String toString() {
return aField.toString();
}
};
}
}
Anywhere outside of the package can see SomeObject and aMethod but can only create new instances through the factory.

How do I make variables in a Main accessible to other classes?

For example I have a MovieDatabase class that contains a list of Movie objects. In my main code, I initialize all the objects in the MovieDatabase. However I wish to call this MovieDatabase in another class to access the library. How would I do this?
Do I add in get methods in my main code and return it? Or is there another way (eg. changing the list of objects to protected/public?)
Thanks!
Code's supposed to be 3 seperate classes, Main, MovieDatabase & Movie.
An instance of movieDatabase is initialized in Main. Upon construction, it calls loadMovieList() and populates the list from a text file. However I wish to call the same instantiation of movieDatabase from another class in order to access the movies, so that I do not have to repeat the loading.
public class Main {
public static void main(String[] args) {
MovieDatabase movieDatabase = new MovieDatabase();
}
public class MovieDatabase {
ArrayList<Movie>movieList = new ArrayList<Movie>();
String fileAddress = "D:/Users/Mine/School/Java/CZ2002_Assignment/src/MovieDatabase/movieDatabase.txt";
public MovieDatabase()
{
numOfMovie=0;
loadMovieList();
}
public int getNumOfMovie() {
return numOfMovie;
}
public void addMovieToList(Movie movie) {
movieList.add(movie);
numOfMovie++;
}
public Movie selMovieByID(int movieID) {
int index=-1;
for (Movie m : movieList) {
index++;
if (m.getMovieID() == movieID)
break;
}
return selMovieByIndex(index);
}
public Movie selMovieByIndex(int index) {
return movieList.get(index);
}
public void loadMovieList()
{
//loads through text file
addMovieToList(new Movie(tempMovie));
System.out.println("Movie Database loaded");
}
public class Movie{
private int movieID;
private String movieName;
private int movieDuration; //in minutes;
private String movieRating; //G; PG; PG13; NC16; M18; R21;
private boolean has3D;
private boolean status;
}
If you have a class that depends on a NameLibrary, you should inject it via the constructor or a set method.
Firstly, its difficult to assess what issues you truly have without any code to show us.
However you mention main method, as in
public static void main(String args[]){};
this main method is designed specifically to run the application, your compiler needs that specific method, it is not designed to be used as an accessor method
e.g.
public int getValue(){
return value;}
this is not the only reason you can't access the main method variable. main doesn't have a return type (due to the use of void) plus the idea of SCOPE (each method has a scope, any method that contains a variable can see that variable, but nothing outside of it can directly see it without a return type) you use scope to limit what can be accessed or what cannot be accessed outside of the methods or classes (thats why class variables usually will have private, in order to limit accessibility)
Create a getter-method which returns the list inside your NameLibrary. if your other class extends from NameLibrary you can call this getter-method with the object reference to your NameLibrary class.
If you want int x to be accessible from other classes, you write:
public class myClass{
public int x = 0;
}
To access it from other classes, you simply write:
myClass.x ... (do something)

Change value from another form java

I have a main form (RandomSend) and another form called (_user)
in the randomsend form I declare a public static variable:
public class RandomSend extends javax.swing.JFrame {
......
public static String userGender; // this variable I want to change from another form (_user)
....
}
and in the RandomSend class I declared _user instance that try to change userGender value
_user setGender = new _user();
setGender.setModalExclusionType(ModalExclusionType.APPLICATION_EXCLUDE);
setGender.setAlwaysOnTop(true);
setGender.setVisible(true);
In the _user form (class) I trying to change userGender vale:
public class _user extends javax.swing.JFrame {......
....
RandomSend.userGender="male";
....}
when I check the value from within _user , the value of RandomSend.userGender is "male"
but from my main form the value is null...
new new
My attempt According to answer number 1
public class RandomSend extends javax.swing.JFrame {
/**
*
*/
private static String userGender;
.....
.....
// show dialogbox to select gender...
_user setGender = new _user();
setGender.setModalExclusionType(ModalExclusionType.APPLICATION_EXCLUDE);
setGender.setAlwaysOnTop(true);
setGender.setVisible(true);
....
....
// setter
public static void setUserGender(String gender)
{
if(gender.toLowerCase().equals("female") ||gender.toLowerCase().equals("male"))
userGender = gender;
else userGender= "Unknown!!";
}
//getter
public static String getUserGender()
{
return userGender;
}
and in the other class (frame) :
public class _user extends javax.swing.JFrame {
....
....
RandomSend.setUserGender("male");
..
..
..
}
but the Randomsend.userGender doesn't change!
You make changes to an objects member values via the use of getter and setter functions that you define on that object. To use your example you'd end up with something like:
public class RandomSend extend javax.swing.JFrame {
// This should be preferred for values that can mutate (non-final) to prevent
// modification without the owning class being alerted the value is changing
private static String userGender;
public static void setUserGender(String value) {
userGender = value;
}
public static String getUserGender() {
return userGender;
}
}
Using this example you would change the value by calling RandomSend.setUserGender("male") and you would read this value by calling RandomSend.getUserGender().
Some Additional Notes
I just wanted to point out some additional things that I noticed about your sample. Using static values in the manner that you are is not necessarily the best idea. You're locking the use of the class down in the wrong way. You should maintain an instance of a User class or some other kind of class that manages information specific to a user, such as gender. By managing an instance instead of static values on a class you're making it easier for you to handle other users within the application if that need ever rose up. If you are sure you never need to support more than the current user, then you can still use instances but implement it with a singleton pattern.
That would look something like:
public class SingletonExample {
private static SingletonExample instance = null;
// Declared private to prevent new SingletonExample
// outside of this class
private SingletonExample {}
public static SingletonExample getInstance() {
if (instance == null) {
instance = new SingletonExample();
}
return instance;
}
}
You would use this class by fetching an instance like SingletonExample.getInstance() and then operate on that instance. Using this methods guarantees that in all points in your project you're accessing the same instance of the same object making "global" in a sense.
Another note I would like to make is try and use final values or better yet, an enum instead of strings for things like gender which you will most likely use as values. I say this because in order to properly compare genders you have to do:
if (RandomSend.userGender.equals("male")) {
// ...
}
If you instead created a Gender class with constants like:
public Gender {
public static final int MALE = 1;
public static final int FEMALE = 2;
}
And comparisons (provided value changes in the proper classes)
if (RandomSend.userGender == Gender.MALE) {
// ...
}
And no more wasted string literals being passed around. This is such a good idea that Java has an entire construct unique to providing this solution called enums. You would define a Gender enum like so:
public enum Gender {
MALE,
FEMALE;
}
And then you declare you userGender as a Gender value and your comparisons are the same as if you built the enum yourself from a class with constant values. These changes can, in the long run, make your projects more manageable and easier to maintain.

How to organize an OO design with two different types of users

I've two different type of users, and I've mapped them to two Java classes UserWheel and UserSea and they have a common abstract superclass called User. The data saved for these user types is about the same, but the behavior is different.
Then I created an abstract class called UserCollection with derived classes UserWheelCollection and UserSeaCollection to search for subusers or load a subuser.
Then I've added an abstract method to UserCollection class with signature
public abstract List<User> listAllSubusers()
this is because the implementation will differ. Each User created will be a UserWheel or a UserSea, depending on which method was called, but also all the rest of the implementation is quite different.
Then I want to add a new method to UserCollection with signature public User loadById(int idUser). In this case the implementation would be the same except for the fact that the User returned would be an instance of either UserWheel or UserSea. I'm reluctant in this case to use an abstract method in the base class because of code duplication.
I could check the concrete class of UserCollection with instanceof and create an appropriate subclass, but it doesn't seem object oriented and breaks the open-close principle.
Another idea would be to add an abstract method createNewUser() to UserCollection and concrete implementations in the subclasses to return a new instance, so the base class would just call this createNewUser() method.
Do you think this second path makes sense? Or you would organize things in a different way and how?
UPDATE. The current situation is:
abstract class User
public String getAddress()
public void setAddress()
...
class UserSea extends User
class UserWheel extends User
abstract class UserCollection
protected abstract User createNewUser();
public abstract List<User> listAllSubUsers();
public User loadById(int idUser) {
User newUser = createNewUser();
//populate it
return newUser;
}
class UserSeaCollection
protected User createNewUser() {
return new UserSea();
}
public List<User> listAllSubusers()
class UserWheelCollection
protected User createNewUser() {
return new UserWheel();
}
public List<User> listAllSubusers()
I tried to understand the strategy pattern, as suggested by trashgod, and here is my first attempt:
interface SubuserManagement
List<User> listAllSubUsers();
...
interface UserCrud
void create();
User readById(int idUser);
void update();
void delete();
class UserSeaCollection implements SubUserManagement, UserCrud
private SubUserManagement subuserBehavior = new SubUserManagementSeaImplementation();
private UserCrud userCrudBehavior = new UserCrud();
void create {
subUserBehavior.create();
}
...
class UserWheelCollection implements SubUserManagement, UserCrud
...
class SubUserManagementWheelImplementation implements SubUserManagement
List<User> listAllSubUsers();
class SubUserManagementSeaImplementation implements SubUserManagement
List<User> listAllSubUsers();
class UserCrudImplementation implements UserCrud //only 1 implementation
void create();
User readById(int idUser);
void update();
void delete();
In this first attempt, I've created UserCollectionWheel and UserCollectionSea that don't share anymore a common superclass, but implement the same interfaces. The actual implementation is in external classes.
Now UserCollectionWheel and UserCollectionSea are really the same class, with the only difference of the behavior that I assign to them. Alternatively I could write just one class with setters:
UserCollection userColl = new UserCollection();
userColl.setSubUserBehavior(new SubUserManagementSeaImplementation());
userColl.setCrudBehavior(new UserCrud());
But the initialization would be cumbersome, especially if I had more behavior classes. So what am I doing wrong? How to organize this properly?
UPDATE 2: I wrote a blog post with the design that I've implemented.
Instead of inheriting behavior, consider encapsulating it using interfaces in a strategy pattern. Users would differ in having either of two concrete implementations of an interface ListSubUsersStrategy, interface CreateUserStrategy, etc.
See also the related bridge pattern.
Addendum: In the example below, every user has a concrete strategy for finding sub-users. In particular, listAllSubUsers() invokes the interface method, automatically dispatching to the right concrete implementation. The pattern doesn't relieve you of writing concrete implementations of the interface, but it does de-couple them, ensuring that changing one won't break another.
Console:
A has wheel users.
B has sea users.
C has wheel users.
Code:
import java.util.ArrayList;
import java.util.List;
/** #see http://stackoverflow.com/questions/6006323 */
public class UserMain {
private static final List<User> users = new ArrayList<User>();
public static void main(String[] args) {
users.add(new User("A", new WheelStrategy()));
users.add(new User("B", new SeaStrategy()));
users.add(new User("C", new WheelStrategy()));
for (User user : users) {
user.listAllSubUsers();
}
}
private static class User {
private String name;
private SubUsersStrategy suStrategy;
public User(String name, SubUsersStrategy suStrategy) {
this.name = name;
this.suStrategy = suStrategy;
}
public void listAllSubUsers() {
System.out.print(name + " manages ");
List<User> subUsers = suStrategy.getList();
}
}
private interface SubUsersStrategy {
List<User> getList();
}
private static class WheelStrategy implements SubUsersStrategy {
#Override
public List<User> getList() {
System.out.println("wheel users.");
return null;
}
}
private static class SeaStrategy implements SubUsersStrategy {
#Override
public List<User> getList() {
System.out.println("sea users.");
return null;
}
}
}
FWIW, here's my take on Trashgod's Strategy pattern approach. This is not an answer, just a supporting explanation of Trashgod's answer.
public interface UserStore<T extends User> {
public T create(int id);
public List<T> listAll();
}
public class SeaUserStore implements UserStore<SeaUser> {
public SeaUser create(int id) { return new SeaUser(id); }
public List<SeaUser> listAll() { whatever }
}
// the dry counterpart of 'sea' is either 'land' or 'road', not 'wheel' :)
public class RoadUserStore implements UserStore<RoadUser> {
public RoadUser create(int id) { return new RoadUser(id); }
public List<RoadUser> listAll() { whatever }
}
public class UserCollection<T extends User> {
private UserStore<T> store;
public UserCollection(UserStore<T> store) {
this.store = store;
}
public List<T> listAll() {
return store.listAll();
}
public T getById(int id) {
T user = store.create(id);
// populate
return user;
}
}
This leaves it up to the client to create the UserCollection. You could wrap that; make the UserCollection constructor private, and add:
public class UserCollection<T extends User> {
public static UserCollection<SeaUser> createSeaUserCollection() {
return new UserCollection<SeaUser>(new SeaUserStore());
}
public static UserCollection<RoadUser> createRoadUserCollection() {
return new UserCollection<RoadUser>(new RoadUserStore());
}
}
I could check the concrete class of UserCollection with instanceof and create an appropriate subclass, but it doesn't seem object oriented and breaks the open-close principle.
This would break Liskovs Substitution Principle, which really is a rule to check that one has a sound object hierarchy. The rule says that if a method expects a User as an argument, it should not matter if the user is a CompledUser, DirtyUseror any other user. (Hence you may not have any ifs checking instanceof etc).
Inheritance is all about "is-a" relationships, which basically means that you should be able to take any derived object and pass it to a method which expects the base class. If you can't do that, you are in a lot of trouble. Problems like this is because you have failed with your classes.
Another idea would be to add an abstract method createNewUser() to UserCollection and concrete implementations in the subclasses to return a new instance, so the base class would just call this createNewUser() method
This is a a better approach, since the caller if createNewUser doesn't care about which kind of user it get. All it knows is that it is a user.
The approach is called factory method pattern.

Usage of inner class

I can understand what inner class is and how to write program. My question is in what situation do programmers really need inner class?
Sometimes there is some functionality which is best represented as an object, but which is only meaningful within the context of another object, which does not necessarily need to be exposed to the outside world, and which can benefit from having access to the parent classes data (so as to not violate encapsulation).
The best example that I can think of is putting a Node class inside of a LinkedList. Nodes are only meaningful to the LinkedList, so they only exist within one. No one outside of the LinkedList cares about nodes or should have access to them.
An inner class allows us to remove that logic and place it into its own class. So from an object-oriented point of view, we've taken functionality out of where it doesn't belong and have put it into its own class.
Please go through this link....
http://www.javaworld.com/javaworld/javaqa/2000-03/02-qa-innerclass.html
Also as you know in Java exists nested classes, which is static inner clasess.
From previous posts becomes clear when we need to use an inner class but I think you also interested in the question "Why we need nested classes (static inner class)".
The answer is simply, there is the same purpose as for the inner class except few things.
1) The nested class (static inner) is required when we whant to exclude some logic that concerns another object but this logic might be used in outworld.
The simpliest examples is a builders or editors of some object. For example we have class Foo
which may have a lot of optional fields, to construct such object we may decide to introduce a builder class which will do this work.
public class Foo {
private int param1;
private int param2;
private int param3;
private Foo(FooBuilder builder) {
this.param1 = builder.param1;
this.param2 = builder.param2;
this.param3 = builder.param3;
}
public int getParam1() {
return param1;
}
public void setParam1(int param1) {
this.param1 = param1;
}
public int getParam2() {
return param2;
}
public void setParam2(int param2) {
this.param2 = param2;
}
public int getParam3() {
return param3;
}
public void setParam3(int param3) {
this.param3 = param3;
}
public static class FooBuilder {
private int param1;
private int param2;
private int param3;
public FooBuilder() {
}
public FooBuilder withParameter1(int param1) {
this.param1 = param1;
return this;
}
public FooBuilder withParameter2(int param2) {
this.param2 = param2;
return this;
}
public FooBuilder withParameter3(int param3) {
this.param3 = param3;
return this;
}
public Foo build() {
return new Foo(this);
}
}
}
This example illustrates at leas one reason why we need such classes
2) The second difference between inner and static inner classes is that the first one always has pointer to the parent class. Actully compiler creates synthetic field member for the non static inner class of the type of it's parent, exectly of this reason we can access private members of the parent class. The static inner clasess doesn't has such generated field member. For instance we has just simple parent class with declared non static inner class:
public class Foo {
public class FooBuilder {
}
}
but in fact if take into account the byte code it looks like:
public class Foo {
public class FooBuilder {
private Foo generatedNameHere;
}
}
if you want you can figure out this throught generated byte code.
One of the use of inner class is :
Inner class helps in multiple-inheritance. Inner class allows you to inherit from more than one non-interface.
//first case; can implement if two classes are interface
interface A { }
interface B { }
class X implements A, B { }
//second case; you can extend only one class. This case inner class can help to inherit other class as well
class D { }
abstract class E { }
class Z extends D {
void method() {
return new E() { }; //Anonymous inner class
}
}
When you want to specify a class that has sence only in context with the bounded one.
For example you write a MathOperations class that can execute four operations. So the operations can be represented as inner enum MathOps.
When the inner class is not used anywhere except the inbounded one.
You use anonymous inner classes to specify only the operation, for exmple if you want to sort a collection, you specify a Comparable class just for one method compare.
Collections.sort(employments, new Comparator<Employment>() {
#Override
public int compare(Employment o1, Employment o2) {
return o1.getStartDate().before(o2.getStartDate()) ? 1 : -1 ;
}
});
With inner classes you can access private members of the enclosing class.
They are useful for interface implementations that are only used by the enclosing class (event handlers in a application).
They are useful for providing fine grained access and creation control over an interface implementation that is retrieved externally (maybe something like an Iterator implementation).

Categories