how to flatten an inherited class? - java

Is there a way to flatten inherited classes to discover which functions belong to what class?
if you have a class like:
public class Person
{
public String name;
public void setName(String name){
this.name = name;
}
public String getName(){
return this.name;
}
}
and an inherited class like
public class Worker extends Person
{
public String job;
public void setJob(String job){
this.job = job;
}
public String getJob(){
return this.job;
}
}
When you instantiate Worker, is there a way to find out that Set/GetName belongs to the Person class?
I've seen suggestions of using an interface to find this information out but i'm not sure how an interface would be best used to show the kind of function relationships here. Are there any cheats to being able to reference particular classes within an inherited class?
EDIT:
To answer why I wish to do this: I basically want to be able to loop over the methods in an object and ignore ones that come from a certain class, in this instance I want to ignore the Person class.
My real world example isn't quite as simple as this, but i couldn't think of a better way of working out which methods belong to what class without "flattening" them.

The isBridge method in Method class can be used to check whether the method is declared in the Person or Worker class.
public static void main(String[] args)
{
Worker worker = new Worker();
Class clazz = worker.getClass();
Method[] methods = clazz.getDeclaredMethods();
for(Method method :methods)
{
System.out.println(method.getName()+ " is in Worker: "+ !method.isBridge());
}
}
The above code will produce the output as:
setName is in Worker: false
getName is in Worker: false
setJob is in Worker: true
getJob is in Worker: true

You can use Reflection API to check whether a method exists within an object, but I don't see why would you do this. Remembering how polymorphism works, we should treat your instance of Worker either as Worker or as Person, but why would you treat it as a Worker as "not quite a Person"?
Worker w = new Worker();
Class c = w.getClass();
Class noparams[] = {};
boolean hasSetJob = false;
try{
c.getDeclaredMethod("setJob", noparams);
hasSetJob = true;
} catch (NoSuchMethodException e) {
hasSetJob = false;
}
Anyway any uses of Reflection API in applicative (and not framework) code considered as a hack and a sign that you want to do weird things (which are usually wrong).

If I understand your problem, you could try this way:
Class c = new Worker().getClass();
Method[] ma = c.getMethods();
for (Method m : ma) {
String methodClass = m.getDeclaringClass().getName();
if(methodClass.equals("net.yourpackage.Person")){
// do something...
}
else if(methodClass.equals("net.yourpackage.Worker")){
// do something...
}
// ... other classes
else if(methodClass.equals("java.lang.Object")){
// do something else...
}
}

Related

Can a Java object factory be used as a constructor?

I'm pretty new to Java so hopefully this question isn't too stupid.
According to the Java documentation: "An object factory is a producer of objects. It accepts some information about how to create an object, such as a reference, and then returns an instance of that object."
How can that instance be the result of a constructor?
Here is some (totally pointless) example code that illustrates the class hierarchy I'm trying to construct (invoking it with simple integer arguments like "1 2 3" will get the point across):
package number;
public class Factory {
public static void main(String[] args) {
for (String arg : args) {
// This is how I want to instantiate and use the Outer class:
Outer outer = new Outer(arg);
// But I don't know how to create Outer from the factory, and the results are wrong:
System.out.println("yields: " + outer.value + ", class: " + outer.Class());
// This is a workaround (that I can't use) that gives the correct results:
Number number = outer.Workaround(arg);
System.out.println("yields: " + number.value + ", class " + number.Class());
}
}
}
class Outer extends Inner {
Outer(String arg) {
super(arg);
}
}
class Inner extends Number {
Inner(String arg) {
// I don't want to do this:
super(arg);
// I want some way of doing this:
// return NumberFactory.getNumber(arg);
}
// Workaround method that I can't really use:
Number Workaround(String arg) {
return NumberFactory.getNumber(arg);
}
}
class NumberFactory {
static Number getNumber(String selection) {
switch (selection) {
case "1": return new First(selection);
case "2": return new Second(selection);
default: return new Other(selection);
}
}
}
class First extends Number {
First(String arg) { super(arg); value = "first"; }
String Class() { return "First"; }
}
class Second extends Number {
Second(String arg) { super(arg); value = "second"; }
String Class() { return "Second"; }
}
class Other extends Number {
Other(String arg) { super(arg); value = "other"; }
String Class() { return "Other"; }
}
class Number {
String arg;
String value = "default";
Number(String arg) {
this.arg = arg;
System.out.print("Number(" + arg + "), ");
}
String Class() { return "Number"; }
}
please explain what you are trying to do.
but here's my attempt to answer your question.
Constructor is used when ever a new Java Object is created. When you use new SomeObject() compiler uses the constructor
SomeObject(){
// some logic here
}
to create an object using the SomeObject.class. How the object is created and maintained through its life-cycle is up to the JVM. you can find more info here. https://en.wikibooks.org/wiki/Java_Programming/Object_Lifecycle
Also object factories are used to create objects, but in turn they use object constructors to instantiate the object inside them (as you have already done so).
Object factories are used to delegate the logic of object creation to a central location, so that the code is not repeated and well organized.
Read more about object factories here https://github.com/iluwatar/java-design-patterns/tree/master/abstract-factory
another thing you dont have to implement String Class() method inside every class you implement. SomeObject.class.toString() will do it for you.
I couldn't understand your main question because java object factory is java's business and I don't think we can do anything with it, although I can try to answer your question regarding instances and constructor.....
Constructors in java are the way you talk to a class, even when you don't define a constructor of a class, a default constructor with default values(i.e., false for boolean etc.) is created for your class by the compiler.....So, I guess when you want specific way of creating a connection with your class then you make specific constructors otherwise a default is always made available by the compiler.
Maybe you want to ask why do we have to use super() before anything in a subclass constructor and the reason for that is again same i.e., The parent class' constructor needs to be called before the subclass' constructor. This will ensure that if you call any methods on the parent class in your constructor, the parent class has already been set up correctly.

use java.util.function.Function to implement Factory Design Pattern

Is it correct to use java.util.function.Function to implement Factory Design Pattern
In the following example, I've used Function reference to instantiated a Person type object.
import java.util.function.Function;
public class Main {
public static void main(String[] args) {
Function<String , Person> myFunc = (String s) -> new Person(s);
Person p = myFunc.apply("John");
System.out.println(p.getName());
}
}
class Person{
private String name;
public Person(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
The factory design pattern is used to hide implementation logic behind an object factory and its power is to use inheritance to achieve this. Say you would have more than one type of person, e.g. a SmartPerson and a DumbPerson (implementing the same Person base class). One could ask the factory to create either a smart or a dumb person without ever knowing about the implementation differences, since all it ever returns is a Person object.
You can instantiate a person with a function referring to the constructor, but this pattern is about the location of the object creation, allowing you to hide certain implementation logic.
This hiding of logic behind a factory saves you a lot of time in the future where different classes may use the factory to create persons, because a change to the way you create a person would only require you to modify the creation methods in the factory and does not affect each individual class using the factory.
#Test
public void testSimpleFactory() {
PersonFactory personFactory = new PersonFactory();
Person person = personFactory.createPerson("dumb");
person.doMath(); // prints 1 + 1 = 3
}
public class PersonFactory {
public Person createPerson(String characteristic) {
switch (characteristic) {
case "smart":
return new SmartPerson();
case "dumb":
return new DumbPerson();
default:
return null;
}
}
}
public interface Person {
void doMath();
}
public class SmartPerson implements Person {
#Override
public void doMath() {
System.out.println("1 + 1 = 2");
}
}
public class DumbPerson implements Person {
#Override
public void doMath() {
System.out.println("1 + 1 = 3");
}
}

Java function on function [duplicate]

I want to achieve method chaining in Java.
How can I achieve it?
Also let me know when to use it.
public class Dialog {
public Dialog() {
}
public void setTitle(String title) {
//Logic to set title in dialog
}
public void setMessage(String message) {
//Logic to set message
}
public void setPositiveButton() {
//Logic to send button
}
}
I want to create method chaining that I can use as follows:
new Dialog().setTitle("Title1").setMessage("sample message").setPositiveButton();
or like
new Dialog().setTitle("Title1").setMessage("sample message");
or like
new Dialog().setTitle("Title1").setPositiveButton();
Have your methods return this like:
public Dialog setMessage(String message)
{
//logic to set message
return this;
}
This way, after each call to one of the methods, you'll get the same object returned so that you can call another method on.
This technique is useful when you want to call a series of methods on an object: it reduces the amount of code required to achieve that and allows you to have a single returned value after the chain of methods.
An example of reducing the amount of code required to show a dialog would be:
// Your Dialog has a method show()
// You could show a dialog like this:
new Dialog().setMessage("some message").setTitle("some title")).show();
An example of using the single returned value would be:
// In another class, you have a method showDialog(Dialog)
// Thus you can do:
showDialog(new Dialog().setMessage("some message").setTitle("some title"));
An example of using the Builder pattern that Dennis mentioned in the comment on your question:
new DialogBuilder().setMessage("some message").setTitle("some title").build().show();
The builder pattern allows you to set all parameters for a new instance of a class before the object is being built (consider classes that have final fields or objects for which setting a value after it's been built is more costly than setting it when it's constructed).
In the example above: setMessage(String), setTitle(String) belong to the DialogBuilder class and return the same instance of DialogBuilder that they're called upon; the build() method belongs to the DialogBuilder class, but returns a Dialog object the show() method belongs to the Dialog class.
Extra
This might not be related to your question, but it might help you and others that come across this question.
This works well for most use cases: all use cases that don't involve inheritance and some particular cases involving inheritance when the derived class doesn't add new methods that you want to chain together and you're not interested in using (without casting) the result of the chain of methods as an object of the derived.
If you want to have method chaining for objects of derived classes that don't have a method in their base class or you want the chain of methods to return the object as a reference of the derived class, you can have a look at the answers for this question.
Just add a static builder method, and create another set of the setter methods.
For example
class Model {
private Object FieldA;
private Object FieldB;
public static Model create() {
return new Model();
}
public Model withFieldA(Object value) {
setFieldA(value);
return this;
}
public Model withFieldB(Object value) {
setFieldB(value);
return this;
}
}
...
And use it like
Model m = Model.create().withFieldA("AAAA").withFieldB(1234);
example of reducing the amount of code required to show a dialog would be:
package com.rsa.arraytesting;
public class ExampleJavaArray {
String age;
String name;
public ExampleJavaArray getAge() {
this.age = "25";
return this;
}
public ExampleJavaArray setName(String name) {
this.name = name;
return this;
}
public void displayValue() {
System.out.println("Name:" + name + "\n\n" + "Age:" + age);
}
}
another class
package com.rsa.arraytesting;
public class MethodChaining {
public static void main(String[] args) {
ExampleJavaArray mExampleJavaArray = new ExampleJavaArray();
mExampleJavaArray.setName("chandru").getAge().displayValue();
}
}
In case if you are using lombok, you can use parameter in your lombok.config:
lombok.accessors.chain = true
Or for particular data classes you can declare #Accessors(chain = true) annotation:
import lombok.experimental.Accessors;
#Accessors(chain = true)
#Data
public class DataType {
private int value;
// will generate setter:
public DataType setValue(int value) {
this.value = value;
return this;
}
}

Use actual type of the class when using inheritance

Let's say we have a class with the following method:
public class Entry {
private String name;
public static Entry getOrCreate(String name) {
// ...
return new Entry(name);
}
}
This class may be subclassed (e.g. SubEntry), and the logic behind "getOrCreate" does not change. But the subclasses should not return a new object of the type Entry, but of the type of the respective subclass (e.g. return SubEntry(name))
How can I realize this without reimplementing the method getOrCreate for every subclass of Entry? Is there a term for this kind of technique?
Subclassing Entry does not affect the getOrCreate method because static methods are not part of a class instance; they do not logically belong in any class.
If you instead move getOrCreate into a non-static Factory class, you can use some Generics magic to determine the returned type:
public class Entry {
private String name;
}
abstract class AbstractEntryFactory<T extends Entry>
public abstract T getOrCreate(String name);
}
public class EntryFactory extends AbstractEntryFactory<Entry>
#Override
public Entry getOrCreate(String name) {
// ...
return new Entry(name);
}
}
public class SubEntryFactory extends AbstractEntryFactory<SubEntry>
#Override
public SubEntry getOrCreate(String name) {
// ...
return new SubEntry(name);
}
}
Actually calling the getOrCreate would look different from what it would look like with your code. Instead of this:
Entry myEntry = Entry.getOrCreate("my name");
It would instead look like this:
Entry myEntry = new EntryFactory().getOrCreate("my name");
Or this:
SubEntry myEntry = new SubEntryFactory().getOrCreate("my name");
Assuming you wanted to be able to call Entry.getOrCreate() to create a type of SubEntry, you'll have to pass along some extra information. The reason is that the getOrCreate() method is not inherited by SubEntry, since it is a static method. So if you want to call it the way I mentioned, you'll have to pass along the class name that you want to create. In the code below there are no checks to validate that Class clazz is an Entry or a subtype, but this gives you a start.
import java.lang.reflect.Constructor;
public class TestClass {
public static void main(String[] args) {
Entry entry = (Entry)Entry.getOrCreate("entry", Entry.class);
SubEntry subEntry = (SubEntry)SubEntry.getOrCreate("subEntry", SubEntry.class);
System.out.println("entry class: " + entry.getClass().getName());
System.out.println("subEntry class: " + subEntry.getClass().getName());
}
}
class Entry {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public static Object getOrCreate(String name, Class clazz) {
// If a constructor is created that takes a String, such as "public Entry(String name)",
// then each sub class will need to implement that method. Instead I used a getter and
// setter for the name attribute.
try {
Entry entry = (Entry)clazz.newInstance();
entry.setName(name);
return entry;
}
catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
class SubEntry extends Entry {
}
The end result is this output:
entry class: Entry
subEntry class: SubEntry
There are two questions you are asking:
How do I do this?
What is this technique called?
The second one is much more important than the first.
It seems to me like what you are trying to achieve is similar to the concept of cloning (link) or virtual constructor. But you would like this to be a static method, which raises the question as to why? Since a static method is tied to a certain class, not an instance, you should call it through that class in which case you may just as well explicitly be calling new. But having searched for "retrive class in static context" I would say it is not possible to do exactly what you wrote in the question.
If you convert the static method to a normal method, this can be done by using reflection:
class Entry {
private String name;
public Entry(String name) {
this.name = name;
}
public Entry() {
this.name = null;
}
public Entry getOrCreate(String name) {
try {
return getClass().getConstructor(String.class).newInstance(name);
} catch (Exception e) {
return new Entry(name);
}
}
}
class BetterEntry extends Entry {
public BetterEntry(String name) {
super(name);
}
public BetterEntry() {
super();
}
}
You would then be calling the function from an instance, like so:
Entry a = new Entry().getOrCreate("First");
Entry b = new BetterEntry().getOrCreate("Second");
Entry c = b.getOrCreate("Third");
The dynamic types of a, b, c are Entry, BetterEntry and BetterEntry. You could leave out the default constructors, but I added them to make calling getOrCreate feel more like a static method.
If you really want the method to be static, the simplest way would be to just reimplement this function in every subclass.

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.

Categories