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() {...}
}
I have an interface with 6 methods used to manage datasets. The only method that differs between implementations is getSerializedVersion() and the constructor that is able to parse the serialization string.
public interface DataSets {
public void addEntry(...);
public void removeEntry(...);
public void manipulateEntry(...);
public SomeType getEntry(...);
public List<SomeType> getAllEntries();
// This differs:
public String getSerializedVersion()
}
I can't change the Interface.
My first idea was to generate an abstract class and implement the first five methods. For the concrete implementations (e.g. DataSetsXML, DataSetsYAML, ...) I only have to implement getSerializedVersion() and the constructor that that is able to read the String and initialize the object.
To make it more testable a different design might be better (https://stackoverflow.com/a/7569581) but which one?
Answers might be subjective, but I think there are some general rules or a least (objective) advantages and disadvantages of the different approaches,...
From what you explain the difference is something that is not related to the behavior of the class but just how it is serialized and unserialized. What I mean is that the DataSetsXML and DataSetsYAML would have the same identical funcionality but they would be serialized into different formats.
This means that there is no benefit in keeping getSerializedVersion() coupled with the DataSets class. You should totally decouple them.
You could have a serialization interface sort of:
interface DataSetsSerializer
{
public DataSets unserialize(String string);
public String serialize(DataSets sets);
}
and then take care of differente implementations just in this class, eg:
class YAMLDataSetsSerializer implements DataSetsSerializer
{
public DataSets unserialize(String string) {
DataSets sets = new DataSets();
...
}
public String serialize(DataSets sets) {
...
}
}
By elaborating on JB Nizet comment, if you have to keep a DataSetsSerializer inside a DataSets instance (which IMHO makes no sense since they should be decoupled in any case, as a specific way of serialization shouldn't be bound to the data to be serialized) then the approach would be the following:
class DataSets {
final private DataSetsSerializer serializer;
public DataSets(DataSetsSerializer serializer, String data) {
this.serializer = serializer;
serializer.unserialize(this, data);
}
#Override
public String getSerializedVersion() {
return serializer.serialize(this);
}
}
This requires a slight change in the proposed interface and it's not a clever design but it respects your requirements.
I think it is reasonable to use an abstract class. You can test the concrete implementations of the abstract class (which indirectly tests the abstract class as well).
I am trying to get the best practice in Java to solve the following problem :
I want to setup an complex object in one place, so that other clients can then reuse this construction. Here is an example and how I proceed :
My complex object is of type "Ontology", this object contains many parameters, once it is instantiated and filled, it is used in many objects as a kind of configuration by using its getter.
My Ontology.class
abstract class Ontology {
List<Something1> param1;
List<Something2> param2;
...
protected void addParam1(){
...
}
....
abstract protected void setup();
}
A way to hold the complex construction :
public class SpecificOntology extend Ontology{
#Override
protected void setup(){
addParam1(new Something(...));
...
}
}
A client :
protected void something(){
SpecificOntology o = new SpecificOntology();
o.setup();
install(o.getParam1(());
...
}
Another solution could be to make Ontology not abstract, make its Adder public and build the object outside of the class, but I don't know which pattern could be used for that ? I know the builder pattern and the factory pattern but I am not sure this is the right place for that. Any idea ?
If you want to build an object with many parameters, the first thing I would think of is the Builder pattern.
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?
Say you have an API that is not accessible to change:
List<LegacyObject> getImportantThingFromDatabase(Criteria c);
Imaging Legacy Object has a ton of fields and you want to extend it to make getting at certain information easier:
class ImprovedLegacyObject extends LegacyObject {
String getSomeFieldThatUsuallyRequiresIteratorsAndAllSortsOfCrap() {
//cool code that makes things easier goes here
}
}
However, you can't just cast to your ImprovedLegacyObject, even though the fields are all the same and you haven't changed any of the underlying code, you've only added to it so that code that uses LegacyObject still works, but new code is easier to write.
Is it possible to have some easy way to convert LegacyObject to ImprovedLegacyObject without recreating all of the fields, or accessors? It should be a fast opperation too, I konw you could perform something by using reflections to copy all properties, but I don't think that would be fast enough when doing so to masses of LegacyObjects
EDIT: Is there anything you could do with static methods? To decorate an existing object?
You would have to perform the copying yourself. You can either have a constructor that does this (called a copy constructor):
public ImprovedLegacyObject(LegacyObject legacyObject) {
...
//copy stuff over
this.someField = legacyObject.getSomeField();
this.anotherField = legacyObject.getAnotherField();
...
}
or you can have a static factory method that returns an ImprovedLegacyObject
public static ImprovedLegacyObject create(LegacyObject legacyObject) {
...
//copy stuff over
...
return improvedLegacyObject;
}
If you're planning on extending this behavior to other legacy objects, then you should create an interface
public interface CoolNewCodeInterface {
public String getSomeFieldThatUsuallyRequiresIteratorsAndAllSortsOfCrap() {
}
public String getSomeFieldInAReallyCoolWay() {
}
}
Then your ImprovedLegacyObject would look like this:
public ImprovedLegacyObject extends LegacyObject implements CoolNewCodeInterface {
//implement methods from interface
}
How about making a copy constructor for your Improved Legacy Object that takes a Legacy Object as an argument. Then just create new objects from the old ones.