I have an absract class that describes a general functionality of children classes.
When I initialize a child class I want to set a specific enum class as a member on the parent abstract class.
How can I do that?
Example:
AbstractFunctionality.java
public abstract class AbstractFunctionality {
protected String Name;
protected String Surname;
// specific enum class
public AbstractFunctionality(String Name, String Surname){
this.Name = Name;
this.Surname = Surname;
}
}
Child1.java
public class Child1 extends AbstractFunctionality {
public Child1(){
super("Jane","Austen");
}
}
How can I specify that I want the public enum Writers in my Child1 class?
The simpler approach is just add the enum type as the type of the field parameter of the abstract class:
public abstract class AbstractFunctionality {
protected String Name;
protected String Surname;
Writers writers;
public AbstractFunctionality(String Name, String Surname, Writers writers){
this.Name = Name;
this.Surname = Surname;
this.writers = writers;
}
}
the subclass:
public class Child1 extends AbstractFunctionality {
public Child1(){
super("Jane","Austen", Writers.SOME_FIELD);
}
}
Alternatively, you can make your enum Writers implement a more general interface let us say IWriters
public abstract class AbstractFunctionality {
protected String Name;
protected String Surname;
protected IWriters writers;
public AbstractFunctionality(String Name, String Surname, IWriters writers){
this.Name = Name;
this.Surname = Surname;
this.writers = writers;
}
}
The interface:
public interface IWriters {
...
}
the enum:
public enum Writers implements IWriters{
...
}
The benefit of this approach is that you can have different enums types implementing the same interface, and therefore they can also be used on the abstract class.
Maybe you can set generic in abstract class
public abstract class AbstractFunctionality<T extends Enum<T>> {
protected String Name;
protected String Surname;
T specificEnum
public AbstractFunctionality(String Name, String Surname,T specificEnum){
this.Name = Name;
this.Surname = Surname;
this.specificEnum=specificEnum;
}
In the sub class
public class Child1 extends AbstractFunctionality<Writers> {
public Child1(){
super("Jane","Austen",Writers.POEM);
}
}
}
Related
I'd like to solve such problem. I have some abstract class and a concrete class with setters that return the instance of that class:
#MappedSuperclass
public abstract class BaseEntity implements Serializable {
private Integer id;
public Integer getId() {
return id;
}
public BaseEntity setId(Integer id) {
this.id = id;
return this;
}
}
next abstract:
#MappedSuperclass
public abstract class NamedEntity extends BaseEntity {
private String name;
public String getName() {
return name;
}
public NamedEntity setName(String name) {
this.name = name;
return this;
}
}
and finally a concrete class:
#Entity
public class Person extends NamedEntity {
private String address;
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
I'd like to use this kind of builder but in current setup it's not working due to different return types of parent setters
public Person build() {
Person person = new Person()
.setId(1); //return BaseEntity instead of Person
.setName("name") //returns NamedEntity instead of Person
.setAddress("foo"); //return Person!
return person;
}
of course ther's a workaround with overriden setters but.... can it be done other way using generics?
#Override
public Person setId(Integer id) {
super.setId(id);
return this;
}
#Override
public Person setName(String name) {
super.setName(name);
return this;
}
Thanks for all the sugestions
I know the builder pattern, but in this particular case is the same workaround as overriding the methods setId and setName
The point here is:
it is possible that setId method will return the instance of child class the method is called from
let's say I'd like to put a complex object to my builder (why not?):
public class Person extends NamedEntity {
private String address;
... getters/setters
public Builder builder() {
return new Builder();
}
public final static class Builder {
private final Person person;
private Long id;
private String name;
private String address;
private Builder() {
this.person = new Person();
}
public Builder withId(Long id) {
person.setId(id);
return this;
}
..... other setters
public Builder withDto(PersonDTO dto) {
person
.setId(dto.getId())
.setName(dto.getName())
.setAddress(dto.getAddress()
}
public Person build() {
return person;
}
}
}
as you may guess the person.setId returns instance of BaseEntity
You can use the same trick as enums (Enum), a generic type parameter for the child class.
#MappedSuperclass
public abstract class BaseEntity<E extends BaseEntity<E>> implements Serializable {
private Integer id;
public Integer getId() {
return id;
}
protected final E getThis() {
return this;
}
public E setId(Integer id) {
this.id = id;
return getThis();
}
}
#MappedSuperclass
public abstract class NamedEntity<E extends NamedEntity<E>> extends BaseEntity<E> {
private String name;
public String getName() {
return name;
}
public E setName(String name) {
this.name = name;
return getThis();
}
}
For child classes of Person you need not continue with this pattern.
#Entity
public class Person extends NamedEntity<Person> {
private String address;
public String getAddress() {
return address;
}
public Person setAddress(String address) {
this.address = address;
return this;
}
}
Now you can do_
Person einstein = new Person()
.setId(76)
.setName("Albert")
.setAddress("Princeton, New Jersey");
The alternative is a Builder pattern, however it has the same inheritance problem, and you might end up with *.Builder classes inheriting from parent Builder classes.
I would even say it is not worth this boiler plate code, just for a fluent API (chained calls). The criteria API for instance does hardly need using created objects, and the passed values for the setters must come from some code too.
Also setters implies the classes are mutable. It would be much nicer if most fields were immutable. With entity classes unrealistic, but setters are an ugly initialisation. When possible use constructors/builders without setters.
You can implement the Builder pattern by introducing a nested class Builder with a set of self-returning methods (i.e. returning an instance of Builder) which can be chained in a fluent way.
Method Builder.build() should return an instance of Person.
Note that you setters of your entities can be void.
That's how implementation might look like:
public class Person extends NamedEntity {
private String address;
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public static class Builder {
private Person person;
public Builder() {
this.person = new Person();
}
public Builder name(String name) {
person.setName(name);
return this;
}
public Builder address(String address) {
person.setAddress(address);
return this;
}
public Builder id(Integer id) {
person.setId(id);
return this;
}
public Person build() {
return person;
}
}
}
Usage example:
Person person = new Person.Builder()
.name("Alice")
.address("Wonderland")
.id(1)
.build();
Note:
There could be multiple ways to obtain an instance of Builder. You can introduce in the Person class a static method builder() returning a new Builder, or static methods like withName(String), withId(Integer) might also be handy (for inspiration have a look at User class from Spring Security).
When dialing with immutable objects, Builder class should have all the field of the target class duplicated instead of keeping the reference to the target object. And in such case, method build() would be responsible for constructing an instance of the target type.
I'm creating a reusable property class that I want to base on an abstract class that I will subclass with different variable types in Java.
public abstract class Property{
protected String name;
protected <type> type;
/*
Here is where the problem is, The abstract class won't know what the object type is -- So that if I derive a class of StringProperty whose type is String, how do I implement my setters and getters? in the parent class?*/
public void setName(String n){
name= n;
}
public String getName(){
return name;
}
}//end class
public class StringProperty extends Property{
super.setName("email");
super.setType("String");
}//end class
I want to genericize the abstract parent so it can be derived as StringProperty, IntProperty, BoolProperty, etc. and set the derived type at compile time, but I can't figure it out.
I want each Property Instance to have three properties: Name, type, and Value.
inherited by the child classes? The getter method needs to know the type beforehand
you mean generic type ?
public abstract class Property<T> {
protected String name;
protected T type;
public T getType() {
return type;
}
public void setType(T type) {
this.type = type;
}
}
public class StringProperty extends Property<String> {
...
}
You should use constructor in your subclasses instead of setter like in StrinProperty.
I don't understand why you need the type variable. So use your asked value variable. Because it's a bit obvious that a StringProperty handles strings and has a String value.
public abstract class Property<T> {
private String name;
private T value;
protected Property(String name, T value) {
this.name = name;
this.value = value;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public T getValue() {
return value;
}
public void setValue(T value) {
this.value = value;
}
}
public class StringProperty extends Property<String> {
public StringProperty(String name, String value) {
super(name, value);
}
}
I have an abstract superclass entity which is the following:
#Entity
public abstract class Notification {
#id
private int id;
private Stringname;
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
}
}
Then, I have two class which extends this abstract class
#Entity
public class smsNotifcation extends Notification {
#id
private String name;
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
}
}
#Entity
public class emailNotifcation extends Notification {
#id
private String name;
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
}
}
When I use persistence.xml to auto-create the tables in the PostgreSQL, it only creates the table for the Notification class. I am unable to understand why it wont create tables for the other two. If it is not supposed to create them, then how would I map the information. By mapping information, I meant that how will the name attribute from Notification class know that to which class this name belongs to i.e the name in abstract class's database belongs to smsNotification or emailNotification.
I would like to get E class name in String value with java reflection.
For example, if i create Node typed in Person, getClassName() has to return "Person"
Someone can help me?
public class Node<E extends AbstractNode> {
String getClassName() {
String name = ??
}
private String alias;
public Node() {
}
}
public abstract class AbstractNode {
}
public class Person extends AbstractNode {
private String name;
private String surname;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSurname() {
return surname;
}
public void setSurname(String surname) {
this.surname = surname;
}
}
Add a field to your Node class
private static final Class<T> type;
And add this to your constructor signature
public Node(Class type) {
this.type = type;
}
Lastly, create the getClassName method in your Node class:
public String getClassName(){
return this.type.getName();
}
Edit:
As a sidenote, your AbstractNode class is not really necessary (it doesn't do anything) and therefore neither is the extend in Person.
I have a class which is identical to enum. The only difference is that I create the class so that I can dynamically create the enums. What I want is to override the cast operation of enum so that I can give the enum instance to a method where it gets the class instance.
Example:
public enum SpecialEnum {
FIRST("First"), SECOND("Second");
private String name;
SpecialEnum(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
public class SpecialClass {
private String name;
public SpecialClass(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
public void displayName(SpecialClass specialClass) {
System.out.println(specialClass.getName());
}
Lets say that the SpecialClass instances are coming from a server where I display them. But I also want to use my pre-defined Special enum classes as well. I know that I could create static instances of SpecialClass and use them but not that it looks messy, also using enums are beneficial to my occasion as well. Is there a way to override casting operation of the enum class of a work around maybe?
Extract an interface:
public interface Named {
public String getName();
}
public class SpecialClass implements Named {
private String name;
public SpecialClass(String name) {
this.name = name;
}
#Override
public String getName() {
return name;
}
}
public enum SpecialEnum implements Named {
FIRST("First"), SECOND("Second");
private String name;
SpecialEnum(String name) {
this.name = name;
}
#Override
public String getName() {
return name;
}
}
public void displayName(Named specialClass) {
System.out.println(specialClass.getName());
}