extending an instantiation of a non-static class to a static class - java

I am trying to build a static class structure, and I want to convert an object instantiation of a non-static class to a static class of this static class structure, not as an object but as a class
I've tried things like
public final class Client {
public final static Widget FundSummary = new Widget("url")
{
public class FundSummary extends Widget{
public final static Field FUNDNAMELIST = new Field("xpath", this)
}
}
}
or
public final class Client {
public class FundSummary extends new Widget("xpath")//this is not the right syntax, but it's what I want to achieve
{
}
}
but havent been able to get my end goal of calling this static class using
Client.FundSummary.FUNDNAMELIST.getPermissions() //works
and
Client.FundSummary.getPermissions() //does not work
Here are the non-static classes
public class Element {
public final Integer id
public final String xpath
public final String nameUI
public Element(xpath, nameUI=null, id=null) {
this.xpath = xpath
this.id = id
this.nameUI = nameUI
}
}
public class Widget extends Element {
public final permissions
public Widget(xpath, nameUI=null, id=null, def permissions= null) {
super(xpath, nameUI, id)
this.permissions = permissions
}
public String getURL() {
}
public String getPermissions(User user, int entityID = GlobalVariable.clientID) {
}
}
public class Field extends Element{
public final Widget widget
public final permissions
public Field(xpath, Widget, nameUI=null, id=null, def permissions=null) {
super(xpath, nameUI, id)
this.permissions = permissions
this.widget = Widget
}
public String getPermissions(User user, int entityID = GlobalVariable.clientID) {
}
}

Related

Java Serializable and lambda expressions

I need to save an object on file, then retrieve it later. The object itself implements the interface Serializable, but one of its fields contains lambda expressions. Apparently this counts as a field that does not implements the Serializable interface and I get a java.io.NotSerializableException.
I do not want to drastically change my code, but I do not know what to do in such a situation. Someone has a suggestion?
Here is a sample code that replicates this problem:
public class SerObject implements Serializable {
/**
*
*/
private static final long serialVersionUID = -2691834780794406081L;
public SerField field;
public SerObject(SerField field) {
this.field = field;
}
public String stringRepresentation() {
return this.field.name() + "\t" + field.lambda.apply(field);
}
static final String pathname = "D:\\JavaData\\file.obj";
public static void main(String[] args) {
SerObject obj = new SerObject(new SerField("Field", (field) -> "Class is " + field.getClass().getName() ));
SerializableUtilities.saveObject(new File(pathname), obj);
SerObject loadedObj = SerializableUtilities.loadObject(new File(pathname));
System.out.println(loadedObj.stringRepresentation());
}
}
public class SerField implements Serializable {
/**
*
*/
private static final long serialVersionUID = -5058433150929459799L;
protected String name;
protected Function<SerField, String> lambda;
public SerField(String name, Function<SerField, String> lambda) {
this.name = name;
this.lambda = lambda;
}
public abstract String name() {
return this.name;
}
}

Java: Calling a parent's method with child's member variable

Let's say I have an abstract parent class that has member variables which are used in a method.
public abstract class Person{
public String jobTitle;
public void printJob(){
System.out.println(jobTitle);
}
}
If I now have two child classes
public class Teacher extends Person{
public String jobTitle = "Teacher";
}
public class Janitor extends Person{
public String jobTitle = "Janitor";
}
and I want to avoid code cloning, i.e. implementing the same printJob()-method in both classes, I now have a problem, since the printJob()-method is unable to access member variables of the child classes.
Is there any way that i can call a parent classes' method but have the method use the child classes' member variables?
You can use abstract methods like this
public abstract class Person {
public void printJob() {
System.out.println(getJobTitle());
}
protected abstract String getJobTitle();
public static void main(String[] args) {
Person teacher = new Teacher();
Person janitor = new Janitor();
System.out.println(teacher.getJobTitle());
System.out.println(janitor.getJobTitle());
}
}
class Teacher extends Person {
#Override
protected String getJobTitle() {
return "Teacher";
}
}
class Janitor extends Person {
#Override
protected String getJobTitle() {
return "Janitor";
}
}
Updated after op's comment for code cloning...
public class Person {
public static void main(String[] args) {
System.out.println(new Teacher().job);
System.out.println(new Janitor().job);
}
private static class Teacher extends Person {
private String job = "Teacher";
}
private static class Janitor extends Person {
private String job = "Janitor";
}
}

How to assign a value to a final static variable from a child inside java?

Suppose we have a hierarchy like this:
class Parent {
public static final String BASE_NAME = "parent";
public static final String X_URL = BASE_NAME + "/x";
public static final String Y_URL = BASE_NAME + "/y";
}
class ChildA extends Parent {
public static final String BASE_NAME = "childA";
public static final String X_URL = BASE_NAME + "/x";
public static final String Y_URL = BASE_NAME + "/y";
#RequestMapping(value= X_URL)
public String renderXPage(){...}
}
as you can see the X_URL and Y_URL are repeating both in parent and child, if the child can feed in its own BASE_NAME to the parent, we can eliminate redundant repetition of those constants and then we can use them for the annotation value. How to do this in Java ?
There is no way to reliable achieve this.
You can have #RequestMapping annotation on class and put base part of URL there.
Example:
#RequestMapping("ChildA")
class ChildA {
#RequestMapping(value= "x")
public String renderXPage(){...}
}
renderXPage will handle "ChildA/x" URL.
Using the solution of #talex I came up with this neat solution:
public interface CommonRelativeUrls {
String X_URL = "/x";
String Y_URL = "/y";
}
public interface Entities {
String CLASS_A = "class-a";
String CLASS_B = "class-b";
...
}
#RequestMapping(value = Entities.CLASS_A)
public class ClassA implements CommonRelativeUrls {
#RequestMapping(value= X_URL)
public String renderXPage(){...}
}

Java Interface containing an empty Enum

I'm trying to prepare an interface i want to implement for Datamodel-Classes.Therefor i want to use an enum inside the interface so i know i need to implement it later.
Example:
public interface MyModelInterface {
public enum Field;
public Object get(Field field);
public void set(Field field, Object value);
}
The expected implementation:
public class MyModel implements MyModelInterface {
public enum Field {
ID("id"),
Name1("Name1"),
Name2("Name2");
private String field;
private Field(String field) {
this.field = field;
}
}
public Object get(Field field) {
//...
}
public void set(Field field, Object value){
//...
}
public static void main(String[] args) {
MyModel myModel = new MyModel();
System.out.println(myModel.get(MyModel.Field.ID));
System.out.println(myModel.get(MyModel.Field.Name1));
}
}
Since I don't know which fields the model will contain until I implement it.
I did some research and figured that enum can't be extended, so i am aware of that.
is there any way to archive this or any kind of workaround?
i don't want to use String Parameters on the getter/setter Methods to avoid using wrong values.
Thanks in advance for any suggestion.
Update:
So this is what worked for me: Splitting the interface/class in three parts, including an abstract class:
Interface:
public interface MyModelInterface<E extends Enum<E>> {
public Object get(E field);
public void set(E field, Object value);
}
Abstract Class:
public abstract class MyAbstractModel<E extends Enum<E>> implements MyModelInterface<E>{
protected final EnumMap<E, Object> fields;
public MyAbstractModel(Class<E> enumKlazz) {
fields = new EnumMap<>(enumKlazz);
}
#Override
public Object get(E field) {
return fields.get(field);
}
#Override
public void set(E field, Object value) {
this.fields.put(field, value);
}
}
Class(where i actually archive my goal):
public class MyModel extends MyAbstractModel<MyModel.Field> {
public MyModel() {
super(MyModel.Field.class);
}
public enum Field {
ID("ID"),
Name1("NAME1"),
Name2("NAME2"),
Age("AGE"),
;
private final String field;
private Field(String field) {
this.field = field;
}
public String getName() {
return field;
}
}
public static void main(String[] args) {
MyModel myModel = new MyModel();
System.out.println(myModel.get(Field.Name1));
}
}
Interface fields are static and final implicitly.
What you could do is to have an interface method returning Enum<?>, and your classes implementing it.
For instance:
interface Foo {
public Enum<?> getEnum();
}
class Bar implements Foo {
enum Blah {
INSTANCE;
}
public Enum<?> getEnum() {
return Blah.INSTANCE;
}
}
Edit
Not completely sure I understand your question update, but here's a solution that will de-couple returning a specific enum instance from an enum, by means of two interfaces.
The example is self-contained in a Main class.
public class Main {
public static void main(String[] args) {
System.out.println(new Bar().getEnumField().name());
}
static interface IHasEnum {
public Enum<? extends IMyEnum> getEnumField();
}
static interface IMyEnum {
public Enum<? extends IMyEnum> getField();
}
static class Bar implements IHasEnum {
enum Blah implements IMyEnum {
DEFAULT_INSTANCE,
THE_FIELD;
public Enum<? extends IMyEnum> getField() {
return THE_FIELD;
}
}
public Enum<? extends IMyEnum> getEnumField() {
return Blah.DEFAULT_INSTANCE.getField();
}
}
}
Output
THE_FIELD
Note
The trick here is to add a "default" instance to the enum (DEFAULT_INSTANCE), so the getField method is an instance method, hence overriding the one declared in the IMyEnum interface.
Again, not entirely sure this addresses your issue.
What you are describing is an EnumMap<E, T> - which functions like an array, with that same get-
public class MyModelBase<E extends Enum<E>> {
private final Class<E> enumKlazz;
private final EnumMap<E, Object> fields;
public MyModelBase(Class<E> enumKlazz) {
this.enumKlazz = enumKlazz;
fields = new EnumMpa<>(enumKlazz);
}
public Object get(E field) {
return fields.get(field);
}
public void set(E field, Object value) {
fields.put(field, value);
}
}
enum UserField { id, surname, name, age };
MyModelBase<UserField> userModel = new MyModelBase<>(UserField.class);
userModel.set(UserField.surname, "X");
Because of type erasure the enum map needs the class. Above the enum class is also stored as field, as some static Enum methods need the enum class. For iterating, and so on.
Java generics will be the best solution.
Lets assume, you don't know the contents of the Field as mentioned.
Create a generic interface like this:
public interface MyModelInterface<T> {
public T get();
}
Then create a class Field like this:
public class Field {
private String id;
private String name1;
private String name2;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName1() {
return name1;
}
public void setName1(String name1) {
this.name1 = name1;
}
public String getName2() {
return name2;
}
public void setName2(String name2) {
this.name2 = name2;
}
}
and then your model class will look like
public class MyModel implements MyModelInterface<Field> {
#Override
public Field get() {
Field field = new Field();
field.setId("ID");
field.setName1("Name1");
field.setName2("Name2");
return field;
}
public static void main(String[] args) {
MyModel myModel = new MyModel();
System.out.println(myModel.get().getId());
System.out.println(myModel.get().getName1());
System.out.println(myModel.get().getName2());
}
}

How to reference adding objects to ArrayLists inside of objects

In JavaFX I am creating a sports tracking system.
My Object User has many Foods and many Exercises, these are stored as ArrayLists.
public class User {
private ArrayList<Food> listofFood = new ArrayList<Food>();
private ArrayList<Exercise> listofExercise = new ArrayList<Exercise>();
private String um;
public User(String u) {
this.um = u;
}
public void addNewFood(Food f) {
listofFood.add(f);
}
public void addNewExercise(Exercise ex) {
listofExercise.add(ex);
}
}
Food and exercise are similar in structure.
public class Food {
private String name;
public Food(String n) {
this.name = n;
}
public void setNameFood(String n) {
this.name = n;
}
}
In my MainApp class I create a user.
public class MainApp {
public User UserLoggedIn;
}
and I pass in an instance of this class using the controller.
public class MainApp {
MyController c = loader.getController();
c.setDialogStage(dialogStage);
c.setApp(this);
}
And in MyController class I set the application ...
public class MyController {
public void setApp(MainApp app) {
this.mainApp = app;
}
}
... which I then reference in MyController.
public class MyController {
mainApp.UserLoggedIn.addNewFood((new Food(nameField.getText())));
}
This gives a Null Pointer exception
UserLoggedIn is never instantiated and it will therefore always be null. Make a default constructor for MainApp() that just creates the User object. Then create a getter method called getUser() that returns the user object. Also, it is Java convention to use camel case instead. So, UserLoggedIn should be userLoggedIn.
public class MainApp
{
private User userLoggedIn;
public MainApp()
{
userLoggedIn = new User("john doe");
}
public User getUserLoggedIn()
{
return userLoggedIn;
}
}
public class MyController
{
MainApp mainApp = new MainApp();
mainApp.getUserLoggedIn().addNewFood(new Food(//enter datum here));
}

Categories