How can I approximate having a static variable in an Inner class? - java

I am working on a series of classes that all inherit from a single, base, abstract class.
In order to keep track of all of these child classes, I'd like to implement something like a GUID -- for my purposes, it doesn't have to be an actual GUID, just an int that is unique to each instance of a child class. An incremented int is what I'd been hoping to use.
What I'd have liked to do, is implement the following in my abstract class:
abstract class ParentObject{
static int GUID = 0;
//other stuff
}
whereafter each child class, in its constructor, would have myGUID = GUID++;
However, whenever I try this, I get the following error from the Processing IDE:
The field GUID cannot be declared static; static fields can only be
declared in static or top-level types.
Because of how Processing handles class files (everything is an inner class), I can't have static class members. What are my options to duplicate this functionality in other ways?
Edit: This is being done in Processing and the Processing IDE. The ParentObject class is in its own processing file.
Edite2: I have learned that the reason Processing is different from Java is that all Processing classes are Inner Classes. Because of this, I have re-added the Java tag and reformulated the question.

Well, then face it. You can't do it. If you REALLY need it, declare an outer class for handling this piece of code, and call it in the top-level class's constructor.
If you MUST use this hierarchy of innerclass, then you can't do it. Java won't accept it in the way you wan't. You could declare your abstract class as static.
static abstract class ParentObject {
private static int GUID = 0;
}
But I'm almost sure this won't work for you either. So, I suggest to create a new outer class somewhere else to handle it.
public class GUID {
private static int GUID = 0;
public synchronized static void increment() {
GUID++;
}
}
abstract class ParentObject {
ParentObject() {
GUID.increment();
// constructor's stuff
}
}
This may speed down your app (depending on how often you instantiate a class), but not in a significant way.

a static protected method getNextGUID() would work
public abstract class ParentObject{
private static int GUID = 0;
protected static int getNextGUID(){
return GUID++;
}
//other stuff
}
don't forget to synchronize it/use AtomicInteger when you have multiple threads

Related

How to inherit fields properly without making them open to the package?

Say, I have a package Pack containing classes A and B. A is self-contained and no one (even in the Pack) should see A's insides, so most of the fields and methods are private.
Now I want to extend A to change one of its private methods keeping the rest - let it be class AMod. Doing it requires most of A's fields and the method to override to be protected, but protected gives access to the package.
So how do I create AMod inside Pack so that AMod has an access to A's fields and methods while no one else does? Make a nested/separate package?
UPD:
UPD2:
UPD3:
As Jacob G. suggested, my code needed redesigning, and I managed to remove the derived class from the architecture. Thanks for help!
The one answer I find missing: don't be so focused on using inheritance in order to avoid code duplication.
If you only need a subtle variation of behavior of A then you should first consider to "wrap" around A (for example via decorator) instead of extending A - the good old FCoI!
If that isn't possible: have a very close look at the common behavior of A and Amod and extract those parts in a common base class.
Finally: don't get too energetic about java access modifiers in the first place. In the end, they help you to communicate a certain thought or idea. "Evil-willing" people will always find a way to work around your intentions. What I am saying is: if you are concerned that your team members use your class in the wrong way ... that is a social problem; and you will never be able to solve that on the technical layer. You have to solve it on the social layer, too (by educating people to ensure that they understand what to do; instead of hoping that private here or protected there will prevent them from doing the wrong thing).
In other words: establish a simple policy such as "only what is marked public is meant to be public; anything else is not" might be able to table such discussions for all times. Versus spending hours and hours to find a perfect private-protected solution within source code.
Thanks for posting code.
My advice would be to first move B#stepBMod into A.java. Then, you can pass a boolean parameter to A#build; with this, you can rewrite A#build:
public Result build(boolean mod) {
stepA();
if (mod) {
stepBMod();
} else {
stepB();
}
stepC();
return result;
}
Now, B.java isn't needed anymore.
Your question is two parts. 1)Accessing fields and 2)Accessing methods.
Case1), you should make class A's fields protected. This means no one can access it by name, except derived classes.
Case2), you cannot access a protected method by name, unless in a derived class. But still you can access a protected method by name using an object of A. In order to prevent other classes making objects, your A class should be abstract.
Here is an example
public abstract class A{
protected int n;
protected void display(){
System.out.println(n);
}
}
public class B extends A{
public void demo(){
B object = new B();
object.display();
}
public void modify(){
n = 0;
}
}
Update
class A
{
public A(Args args){...}
public Result build() {
stepA();
stepB();
stepC();
return result;
}
protected void stepA() {...}
private void stepB() {...}
protected void stepC() {...}
protected T field;
}
class AMod extends A
{
public AMod(Args args){
super(args);
...
}
public Result build() {
stepA();
stepBMod();
stepC();
return result;
}
private void stepBMod() {...}
}

Singleton or static class?

I have the following class :
public class EnteredValues {
private HashMap<String, String> mEnteredValues;
public boolean change = false;
public boolean submit = false;
private static final EnteredValues instance = new EnteredValues();
// Singleton
private EnteredValues() {
mEnteredValues = new HashMap<String, String>();
}
public static EnteredValues getInstance() {
return instance;
}
public void addValue(String id, String value) {
if (mEnteredValues.put(id, value) != null) {
// A change has happened
change = true;
}
}
public String getValueForIdentifier(String identifier) {
return mEnteredValues.get(identifier);
}
public HashMap<String, String> getEnteredValues() {
return mEnteredValues;
}
public void clean() {
mEnteredValues.clear();
change = false;
submit = false;
}
}
This class is used to manage the values that a user has already entered, and the class should be accessible to all classes across the application.
When the activity changes I 'reset' the singleton by calling the clear method.
I chose the singleton pattern without really considering the option of a static class.
But now I was wondering if I shouldn't just use a static class..
What is the common way to handle a class that just manages values?
Is a static class faster as a singleton?
thx
The very fact that you are providing a clear method to reset the state of your Singleton dictates that you should not use Singleton. This is risky behavior as the state is global. This also means that unit testing is going to be a big pain.
One more thing. Never ever declare instance variables as public. Declare them as private or protected and provide getters and setters. Also, there is no need to initialize instance variables with a value that is their default value.
The main difference between a static class and the singleton pattern is that singleton may be used if you need to implement an interface or such. For this particular case I think you might be better off with a static class since you are not implementing any interface. Relating your question if its one faster to the other, I'd say is negligible the difference but using a static class will remove a small overhead of dynamic instantiation of the class.
What is bad in using singleton if you need such a design? If you need exactly one instance of some object designed to do specified things singleton is not a bad choice for sure.
#see Are Java static calls more or less expensive than non-static calls?
Read
http://docs.oracle.com/javase/tutorial/java/javaOO/nested.html
From there:
Note: A static nested class interacts with the instance members of its outer class (and other classes) just like any other top-level class. In effect, a static nested class is behaviorally a top-level class that has been nested in another top-level class for packaging convenience.
Just for style
I prefer not to rely on Singleton if I don't need to. Why? Less cohesion. If it's a property you can set from outside, then you can test your Activity (or whatever) with unit testing. You can change your mind to use diferent instances if you like, and so on.
My humble advise is to have a property in each of your Activities (maybe you can define a common base class?), and set it at activity initialization with a new fresh instance.
Your code will not know nothing about how to get it (except the init code and maybe you can change it in the future).
But as I've said... just a matter of taste! :)

Call a child class method from a parent class object

I have the following classes
class Person {
private String name;
void getName(){...}}
class Student extends Person{
String class;
void getClass(){...}
}
class Teacher extends Person{
String experience;
void getExperience(){...}
}
This is just a simplified version of my actual schema. Initially I don't know the type of person that needs to be created, so the function that handles the creation of these objects takes the general Person object as a parameter.
void calculate(Person p){...}
Now I want to access the methods of the child classes using this parent class object. I also need to access parent class methods from time to time so I CANNOT MAKE IT ABSTRACT.
I guess I simplified too much in the above example, so here goes , this is the actual structure.
class Question {
// private attributes
:
private QuestionOption option;
// getters and setters for private attributes
:
public QuestionOption getOption(){...}
}
class QuestionOption{
....
}
class ChoiceQuestionOption extends QuestionOption{
private boolean allowMultiple;
public boolean getMultiple(){...}
}
class Survey{
void renderSurvey(Question q) {
/*
Depending on the type of question (choice, dropdwn or other, I have to render
the question on the UI. The class that calls this doesnt have compile time
knowledge of the type of question that is going to be rendered. Each question
type has its own rendering function. If this is for choice , I need to access
its functions using q.
*/
if(q.getOption().getMultiple())
{...}
}
}
The if statement says "cannot find getMultiple for QuestionOption." OuestionOption has many more child classes that have different types of methods that are not common among the children (getMultiple is not common among the children)
NOTE: Though this is possible, it is not at all recommended as it kind of destroys the reason for inheritance. The best way would be to restructure your application design so that there are NO parent to child dependencies. A parent should not ever need to know its children or their capabilities.
However.. you should be able to do it like:
void calculate(Person p) {
((Student)p).method();
}
a safe way would be:
void calculate(Person p) {
if(p instanceof Student) ((Student)p).method();
}
A parent class should not have knowledge of child classes. You can implement a method calculate() and override it in every subclass:
class Person {
String name;
void getName(){...}
void calculate();
}
and then
class Student extends Person{
String class;
void getClass(){...}
#Override
void calculate() {
// do something with a Student
}
}
and
class Teacher extends Person{
String experience;
void getExperience(){...}
#Override
void calculate() {
// do something with a Teacher
}
}
By the way. Your statement about abstract classes is confusing. You can call methods defined in an abstract class, but of course only of instances of subclasses.
In your example you can make Person abstract and the use getName() on instanced of Student and Teacher.
Many of the answers here are suggesting implementing variant types using "Classical Object-Oriented Decomposition". That is, anything which might be needed on one of the variants has to be declared at the base of the hierarchy. I submit that this is a type-safe, but often very bad, approach. You either end up exposing all internal properties of all the different variants (most of which are "invalid" for each particular variant) or you end up cluttering the API of the hierarchy with tons of procedural methods (which means you have to recompile every time a new procedure is dreamed up).
I hesitate to do this, but here is a shameless plug for a blog post I wrote that outlines about 8 ways to do variant types in Java. They all suck, because Java sucks at variant types. So far the only JVM language that gets it right is Scala.
http://jazzjuice.blogspot.com/2010/10/6-things-i-hate-about-java-or-scala-is.html
The Scala creators actually wrote a paper about three of the eight ways. If I can track it down, I'll update this answer with a link.
UPDATE: found it here.
Why don't you just write an empty method in Person and override it in the children classes? And call it, when it needs to be:
void caluculate(Person p){
p.dotheCalculate();
}
This would mean you have to have the same method in both children classes, but i don't see why this would be a problem at all.
I had the same situation and I found a way around with a bit of engineering as follows - -
You have to have your method in parent class without any parameter and use - -
Class<? extends Person> cl = this.getClass(); // inside parent class
Now, with 'cl' you can access all child class fields with their name and initialized values by using - -
cl.getDeclaredFields(); cl.getField("myfield"); // and many more
In this situation your 'this' pointer will reference your child class object if you are calling parent method through your child class object.
Another thing you might need to use is Object obj = cl.newInstance();
Let me know if still you got stucked somewhere.
class Car extends Vehicle {
protected int numberOfSeats = 1;
public int getNumberOfSeats() {
return this.numberOfSeats;
}
public void printNumberOfSeats() {
// return this.numberOfSeats;
System.out.println(numberOfSeats);
}
}
//Parent class
class Vehicle {
protected String licensePlate = null;
public void setLicensePlate(String license) {
this.licensePlate = license;
System.out.println(licensePlate);
}
public static void main(String []args) {
Vehicle c = new Vehicle();
c.setLicensePlate("LASKF12341");
//Used downcasting to call the child method from the parent class.
//Downcasting = It’s the casting from a superclass to a subclass.
Vehicle d = new Car();
((Car) d).printNumberOfSeats();
}
}
One possible solution can be
class Survey{
void renderSurvey(Question q) {
/*
Depending on the type of question (choice, dropdwn or other, I have to render
the question on the UI. The class that calls this doesnt have compile time
knowledge of the type of question that is going to be rendered. Each question
type has its own rendering function. If this is for choice , I need to access
its functions using q.
*/
if(q.getOption() instanceof ChoiceQuestionOption)
{
ChoiceQuestionOption choiceQuestion = (ChoiceQuestionOption)q.getOption();
boolean result = choiceQuestion.getMultiple();
//do something with result......
}
}
}

Simulate static abstract and dynamic linking on static method call in Java

Introduction
As a disclaimer, I'v read Why can't static methods be abstract in Java and, even if I respectfully disagree with the accepted answer about a "logical contradiction", I don't want any answer about the usefulness of static abstract just an answer to my question ;)
I have a class hierarchy representing some tables from a database. Each class inherits the Entity class which contains a lot of utility methods for accessing the database, creating queries, escaping characters, etc.
Each instance of a class is a row from the database.
The problem
Now, in order to factorize as much code as possible, I want to add information about related columns and table name for each class. These informations must be accessible without a class instance and will be used in Entity to build queries among other things.
The obvious way to store these data are static fields returned by static methods in each class. Problem is you can't force the class to implement these static methods and you can't do dynamic linking on static methods call in Java.
My Solutions
Use a HashMap, or any similar data structure, to hold the informations. Problem : if informations are missing error will be at runtime not compile time.
Use a parallel class hierarchy for the utility function where each corresponding class can be instantiated and dynamic linking used. Problem : code heavy, runtime error if the class don't exist
The question
How will you cope with the absence of abstract static and dynamic linking on abstract method ?
In a perfect world, the given solution should generate a compile error if the informations for a class are missing and data should be easily accessible from withing the Entity class.
The answer doesn't need to be in Java, C# is also ok and any insight on how to do this without some specific code in any language will be welcomed.
Just to be clear, I don't have any requirement at all besides simplicity. Nothing have to be static. I only want to retrieve table and columns name from Entity to build a query.
Some code
class Entity {
public static function afunction(Class clazz) { // this parameter is an option
// here I need to have access to table name of any children of Entity
}
}
class A extends Entity {
static String table = "a";
}
class B extends Entity {
static String table = "b";
}
You should use the Java annotation coupled with the javac annotation processor, as it's the most efficient solution. It's however a bit more complicated than the usual annotation paradigm.
This link shows you how you can implement an annotation processor that will be used at the compile time.
If I reuse your example, I'd go this way:
#Target(ElementType.TYPE)
#Retention(RetentionType.SOURCE)
#interface MetaData {
String table();
}
abstract class Entity {}
#MetaData(table="a")
class A extends Entity {}
#MetaData(table="b")
class B extends Entity {}
class EntityGetter {
public <E extends Entity> E getEntity(Class<E> type) {
MetaData metaData = type.getAnnotation(MetaData.class);
if (metaData == null) {
throw new Error("Should have been compiled with the preprocessor.");
// Yes, do throw an Error. It's a compile-time error, not a simple exceptional condition.
}
String table = metaData.table();
// do whatever you need.
}
}
In your annotation processing, you then should check whether the annotation is set, whether the values are correct, and make the compilation fail.
The complete documentation is available in the documentation for the package javax.annotation.processing.
Also, a few tutorials are available on the Internet if you search for "java annotation processing".
I will not go deeper in the subject as I never used the technology myself before.
I have run into the same problems as you, and am using the following approach now. Store Metadata about columns as annotations and parse them at runtime. Store this information in a map. If you really want compile time errors to appear, most IDEs (Eclipse e.g.) support custom builder types, that can validate the classes during build time.
You could also use the compile time annotation processing tool which comes with java, which can also be integrated into the IDE builds. Read into it and give it a try.
In Java the most similar approach to "static classes" are the static enums.
The enum elements are handed as static constants, so they can be accesed from any static context.
The enum can define one or more private constructors, accepting some intialization parameters (as it could be a table name, a set of columns, etc).
The enum class can define abstract methods, which must be implemented by the concrete elements, in order to compile.
public enum EntityMetadata {
TABLE_A("TableA", new String[]{"ID", "DESC"}) {
#Override
public void doSomethingWeirdAndExclusive() {
Logger.getLogger(getTableName()).info("I'm positively TableA Metadata");
}
},
TABLE_B("TableB", new String[]{"ID", "AMOUNT", "CURRENCY"}) {
#Override
public void doSomethingWeirdAndExclusive() {
Logger.getLogger(getTableName()).info("FOO BAR message, or whatever");
}
};
private String tableName;
private String[] columnNames;
private EntityMetadata(String aTableName, String[] someColumnNames) {
tableName=aTableName;
columnNames=someColumnNames;
}
public String getTableName() {
return tableName;
}
public String[] getColumnNames() {
return columnNames;
}
public abstract void doSomethingWeirdAndExclusive();
}
Then to access a concrete entity metadata this would be enough:
EntityMetadata.TABLE_B.doSomethingWeirdAndExclusive();
You could also reference them from an Entity implemetation, forcing each to refer an EntityMetadata element:
abstract class Entity {
public abstract EntityMetadata getMetadata();
}
class A extends Entity {
public EntityMetadata getMetadata() {
return EntityMetadata.TABLE_A;
}
}
class B extends Entity {
public EntityMetadata getMetadata() {
return EntityMetadata.TABLE_B;
}
}
IMO, this approach will be fast and light-weight.
The dark side of it is that if your enum type needs to be really complex, with lot of different params, or a few different complex overriden methods, the source code for the enum can become a little messy.
Mi idea, is to skip the tables stuff, and relate to the "There are not abstract static methods". Use "pseudo-abstract-static" methods.
First define an exception that will ocurr when an abstract static method is executed:
public class StaticAbstractCallException extends Exception {
StaticAbstractCallException (String strMessage){
super(strMessage);
}
public String toString(){
return "StaticAbstractCallException";
}
} // class
An "abstract" method means it will be overriden in subclasses, so you may want to define a base class, with static methods that are suppouse to be "abstract".
abstract class MyDynamicDevice {
public static void start() {
throw new StaticAbstractCallException("MyDynamicDevice.start()");
}
public static void doSomething() {
throw new StaticAbstractCallException("MyDynamicDevice.doSomething()");
}
public static void finish() {
throw new StaticAbstractCallException("MyDynamicDevice.finish()");
}
// other "abstract" static methods
} // class
...
And finally, define the subclasses that override the "pseudo-abstract" methods.
class myPrinterBrandDevice extends MyDynamicDevice {
public static void start() {
// override MyStaticLibrary.start()
}
/*
// ops, we forgot to override this method !!!
public static void doSomething() {
// ...
}
*/
public static void finish() {
// override MyStaticLibrary.finish()
}
// other abstract static methods
} // class
When the static myStringLibrary doSomething is called, an exception will be generated.
I do know of a solution providing all you want, but it's a huge hack I wouldn't want in my own code nowadays:
If Entity may be abstract, simply add your methods providing the meta data to that base class and declare them abstract.
Otherwise create an interface, with methods providing all your data like this
public interface EntityMetaData{
public String getTableName();
...
}
All subclasses of Entity would have to implement this interface though.
Now your problem is to call these methods from your static utility method, since you don't have an instance there. So you need to create an instance. Using Class.newInstance() is not feasable, since you'd need a nullary constructor, and there might be expensive initialization or initialization with side-effects happening in the constructor, you don't want to trigger.
The hack I propose is to use Objenesis to instantiate your Class. This library allows instatiating any class, without calling the constructor. There's no need for a nullary constructor either. They do this with some huge hacks internally, which are adapted for all major JVMs.
So your code would look like this:
public static function afunction(Class clazz) {
Objenesis objenesis = new ObjenesisStd();
ObjectInstantiator instantiator = objenesis.getInstantiatorOf(clazz);
Entity entity = (Entity)instantiator.newInstance();
// use it
String tableName = entity.getTableName();
...
}
Obviously you should cache your instances using a Map<Class,Entity>, which reduces the runtime cost to practically nothing (a single lookup in your caching map).
I am using Objenesis in one project of my own, where it enabled me to create a beautiful, fluent API. That was such a big win for me, that I put up with this hack. So I can tell you, that it really works. I used my library in many environments with many different JVM versions.
But this is not good design! I advise against using such a hack, even if it works for now, it might stop in the next JVM. And then you'll have to pray for an update of Objenesis...
If I were you, I'd rethink my design leading to the whole requirement. Or give up compile time checking and use annotations.
Your requirement to have static method doesn't leave much space for clean solution. One of the possible ways is to mix static and dynamic, and lose some CPU for a price of saving on RAM:
class Entity {
private static final ConcurrentMap<Class, EntityMetadata> metadataMap = new ...;
Entity(EntityMetadata entityMetadata) {
metadataMap.putIfAbsent(getClass(), entityMetadata);
}
public static EntityMetadata getMetadata(Class clazz) {
return metadataMap.get(clazz);
}
}
The way I would like more would be to waste a reference but have it dynamic:
class Entity {
protected final EntityMetadata entityMetadata;
public Entity(EntityMetadata entityMetadata) {
this.entityMetadata=entityMetadata;
}
}
class A extends Entity {
static {
MetadataFactory.setMetadataFor(A.class, ...);
}
public A() {
super(MetadataFactory.getMetadataFor(A.class));
}
}
class MetadataFactory {
public static EntityMetadata getMetadataFor(Class clazz) {
return ...;
}
public static void setMetadataFor(Class clazz, EntityMetadata metadata) {
...;
}
}
You could get even get rid of EntityMetadata in Entity completely and leave it factory only. Yes, it would not force to provide it for each class in compile-time, but you can easily enforce that in the runtime. Compile-time errors are great but they aren't holy cows after all as you'd always get an error immediately if a class hasn't provided a relevant metadata part.
I would have abstracted away all meta data for the entities (table names, column names) to a service not known by the entities them selfs. Would be much cleaner than having that information inside the entities
MetaData md = metadataProvider.GetMetaData<T>();
String tableName = md.getTableName();
First, let me tell you I agree with you I would like to have a way to enforce static method to be present in classes.
As a solution you can "extend" compile time by using a custom ANT task that checks for the presence of such methods, and get error in compilation time. Of course it won't help you inside you IDE, but you can use a customizable static code analyzer like PMD and create a custom rule to check for the same thing.
And there you java compile (well, almost compile) and edit time error checking.
The dynamic linking emulation...well, this is harder. I'm not sure I understand what you mean. Can you write an example of what you expect to happen?

How to implement individual access of one class by two other classes, in Java? [duplicate]

This question already has answers here:
Closed 12 years ago.
Possible Duplicates:
‘Friends’ equivalent for Java?
Is there a way to simulate the C++ ‘friend’ concept in Java?
In C++ there is a concept of a "friend", which has access to a class's private variables and functions. So if you have:
class Foo {
friend class Bar;
private:
int x;
}
then any instance of the class Bar can modify any Foo instance's x member, despite it being private, because Bar is a friend of Foo.
Now I have a situation in Java where this functionality would come in handy, but of course it doesn't exist in Java.
There are three classes: Database, Modifier, Viewer. The Database is just a collection of variables (like a struct). Modifier should be "friends" with Database; that is, it should be able to read and write its variables directly. But Viewer should only be able to read Database's variables.
How is this best implemented? Is there a good way to enforce Viewer's read-only access of Database?
There are varying opinions on how pure you should be, but to me you shouldn't give anyone access to any fields. Use getters and setters.
If you need to segregate who can read and who can write, you can throw interfaces into the mix. Define an interface with just the getters and you can restrict your viewer to read only.
Robert Harvey added a comment that points to other options, like using a different access modifier for class or package level access.
I don't think this is a good way to implement such a thing.
You should have a data access layer that hides the database. It should expose CRUD operations.
Start with interfaces. Create a ReaderDao that only has finder methods. Then create a GenericDao that extends the ReaderDao and adds the save, insert, and delete methods.
Implementation classes should implement one interface or the other as needed.
Neither one needs to expose the fact that it's a relational database behind the scenes.
An inner class has access to all the private members of its container class. Make your getters public and your setters private, make Modifer an inner class of Database. Also make it only creatable from inside of Database through a Factory Method pattern. Probably needs to be a Singleton as well.
A package local class is about as close to a "friend" in C++. Make all your getters public, make your setters package local. Make Modifier be in the same package as Database. The first example is cleaner.
The other idiom is applicable is the Memento pattern.
Are you sure this is a good pattern? It directly circumvents encapsulation, one of the main tennets of OO design.
You could create a nested class.
Imagine you have the ViewClass like this:
class Viewer {
Database db;
Viewer( Database db ){
this.db = db;
}
public void whatIsX(){
System.out.println( db.x() );
}
}
And define a modifier with a method to modify that database.
abstract class Modifier {
public void manipulate();
}
You can create the Database with an nested class which have access to the private member, pretty much like friend.
class Database {
private int x;
class DatabaseModifier extends Modifier {
public void manipulate(){
x++;
}
}
public int x(){
return x;
}
}
// To see if works:
class Main{
public static void main( String [] args ) {
Database database = new Database();
Modifier modifier = database.new DatabaseModifier();
Viewer viewer = new Viewer( database );
viewer.whatIsX();
modifier.manipulate();
viewer.whatIsX();
}
}
You can also opt for a static inner class. It could be like this:
class Viewer {
Database db;
public Viewer( Database db ){
this.db = db;
}
public void whatIsX(){
System.out.println( db.x() );
}
}
class Modifier {
Database db;
public Modifier( Database db ){
this.db = db;
}
public void manipulate(){
//db.x++; doesn't work because db.x is private
}
}
class Database {
private int x;
static class DatabaseModifier extends Modifier {
public DatabaseModifier( Database db ){
super(db);
}
#Override
public void manipulate(){
db.x++;
}
}
// public accessor to attribute X
public int x(){// should be getX()
return x;
}
}
class Main{
public static void main( String [] args ) {
Database database = new Database();
Modifier modifier = new Database.DatabaseModifier( database );
Viewer viewer = new Viewer( database );
viewer.whatIsX();
modifier.manipulate();
viewer.whatIsX();
}
}
If you want this kind of access, create an interface to the class that encapsulates the methods you intend to allow only a select few to call. Then create a method where the class passes a private instance of the interface only if the requesting class meets whatever criteria you impose.
A simple example, written with tongue firmly in cheek:
public class Husband {
private Spouse wife;
private int cashInWallet;
public Husband(Wife wife) {
this.cashInWallet = 20;
this.wife = wife;
}
public WalletAccess getWalletAccess(Object other) {
if (other instanceof Wife) {
return new WalletAccessImpl(this);
}
return null;
}
public interface WalletAccess {
public int withdrawCash(int requested);
}
private WalletAccessImpl implements WalletAccess {
private Husband hubby;
private WalletAccessImpl(Husband hubby) {
this.hubby = hubby;
}
public int withdrawCach(int requested) {
if (this.hubby.wallet > requested) {
this.hubby.wallet -= requested;
return requested;
} else {
int allCash = this.hubby.wallet;
this.hubby.wallet = 0;
return allCash;
}
}
}
public class Wife {
private Husband husband;
public Wife(Husband husband) {
this.husband = husband;
}
public void consumeCash() {
Husband.WalletAccess access = husband.getWalletAccess(this);
int cash = access.withdrawCash(20);
}
}
More complex examples are possible, but this improves on the friend access pattern, as even individual instances of the "would-be" friend class could be singled out for access (or refusal). For example, it would be trivial to check that the Wife was actually married to this particular husband in this case by rewriting getWalletAccess(...) like so:
public WalletAccess getWalletAccess(Object other) {
if (other instanceof Wife) {
Wife someone = (Wife)other;
if (someone.getHusband() == this) {
return new WalletAccessImpl(this);
}
}
return null;
}
I'd say interfaces are definitely the solution for your problem.
To start with, don't allow anything else to have access to the actual fields of Database. Create methods that each return one of its fields. Then, make DatabaseView an interface that declares each of these methods for reading. Then have Database implement DatabaseView. Finally, you can add methods for writing (setting) the fields that should be settable to Database.
When you have some class that needs to be able to read from the database, such as your Viewer, have it take a DatabaseView. You can then pass in the Database instance itself, but that class will not know about the methods for writing to it. If something else needs to both read and write, such as your Modifier, you can just give it the Database itself. Better yet, Database itself could be an interface that extends DatabaseView and your actual implementation object could be some class that nothing needs to know about.
You should rethink how much seperation you really want, this "Modifier should be "friends" with Database; that is, it should be able to read and write its variables directly." is impossible in Java - there can't be different access privileges for direct field accesses.
I assume what you really want is to strongly discourage undesirable access patterns. There are a few ways how this can be achieved:
1.) Put Modifier and Database in the same package and make the "Setters" package protected, thus the set-methods become invisible to your Viewer (as long as Viewer is not in the same package). This is more or less impractical for larger designs.
2.) Seperate the concerns into completely different Projects. Then you can set the projects dependencies that only Modifier gets access to Database at all. This implies that you change your design somewhat, either Database becomes two projects (one with the public-readonly interface and one with the full-access interface), or remove the dependency between Viewer and Database completely and make Viewer access Database only through Modifier. This solution has the advantage that its physically impossible to violate access boundaries (It will not compile in the build).
3.) A solution closer to the actual "friend" class concept would be to have two interfaces, one for read, one for write and Database implements those interfaces using inner classes. Then you can "guard" access to the inner class instances with getters that take the client as an argument like this:
public class Database {
public DatabaseReadAccess getReadAccess(Viewer viewer) { ... }
public DatabaseWriteAccess getWriteAccess(Modifier modifier) { ... }
}
This will not prevent a malicious access, but somewhat discourage them. If you want to go one step further, define "Token" classes for Viewer and Modifier and require the token instance for the access getters in Database (then the compiler will enforce the restrictions):
public class ModifierToken {
ModifierToken(Modifier modifier) {
// constructor is package protected, so no outsiders can create tokens!
}
}
I personally would go with the "separate projects" approach, it makes undesirable accesses obvious and violations pop up at latest in the build. I've never tried the "token" approach myself.

Categories

Resources