To define an object in a constructor in Serializable class - java

I have a JSON response like below image, and I have made a serializable class named as Project
In the image, I have two objects (emergency_contact, and secondary_owner) inside my an array of one object. I'm trying to figure out whether what to do in order to define the object, since I want that details to be present inside my constructor.
I have done this so far:
public class Project implements Serializable {
public int id;
public String name;
public String additional_information;
//Now what to do Emergency contact
public Project(int id, String name, String additional_information){
}
}
I have thought of doing this, public EmergencyContact emergency = new EmergencyContact(param1, param2).
And make a new class named as EmergencyContact, and do a getter and setter for the params. But after doing this, I'm still confused, how would I define it my constructor?
I know I'm close, but I need some help on that.

Sure. You need to have a:
public class EmergencyContact implements Serializable {
public String name;
public String number;
public EmergencyContact(String name, String number){
// assign fields
}
}
and one for the owner:
public class EmergencyOwner implements Serializable {
public String name;
public String number;
public EmergencyOwner(String name, String number){
// assign the fields
}
}
then in your Project class you can add fields of these classes:
public class Project implements Serializable {
public int id;
public String name;
public String additional_information;
public EmergencyContact emergency_contact;
public EmergencyOwner emergency_owner;
public Project(int id, String name, String additional_information, EmergencyContact emergency_contact, EmergencyOwner emergency_owner){
// assign the fields here as well
}
}
that's it. If that's an answer to the question consider to delete this question as it is a duplicated on a 100% :)

As a note, to be correctly from the point of clean code parameters, the fields should be private in a class, and use setters / getters to set/retrieve values from/to those fields.
public class Project implements Serializable {
private int id;
private String name;
private String additional_information;
private EmergencyContact emergency_contact;
private SecondaryOwner secondary_owner;
public Project(int id, String name, String additional_information, EmergencyContact emergencyContact, SecondaryOwner secondaryOwner){
this.id = id;
this.name = name;
this.additional_information = additional_information;
this.emergency_contact = emergencyContact;
this.secondary_owner = secondaryOwner;
}
}
You will define the other two classes the same way. Now, you are probably confused about the constructor of EmergencyContact & SecondaryOwner classes.. You can device both default constructors (without parameters) and a custom one(with parameters to it, just as the one above). If you use the default constructor, make sure to set values to the fields in the object, as following :
EmergencyContact emergencyContact = new EmergencyContact();
emergencyContact.setName("the name");
emergencyContact.setNumber("a number");
then you can use this object in the constructor of Project class
I hope it was clear enough, for any other clarifications feel free to ask.
Happy coding <3

Related

UML to Java code: abstract class, simple association, methods

I'm going through some questions from 2019 class on information systems. My own exam is coming this week.
The question is to roughly translate this UML diagram into a Java code, it does not have to be a part of workable code, more of a general idea. Am I on the right track? What have I done wrong in my code sketch?
abstract public class Person {
public String name; // explicit field
private String address; // explicit field
private String phone; //explicit field
// assuming some methods for creating a record
// a getter and setter for name, address and phone
}
public class GeneralPractitioner extends Person {
private String medicalID; //explicit field, either private or protected
private <Arraylist> Patient patient; // GeneralPractitioner – Patient
//getter and setter methods for medicalID
public addPatient(Patient patient) {
//… code implementation
}
}
public class Patient extends Person {
private String patientID; //explict field
private Arraylist <medicalRecord> medicalrecord; //assuming a class for a medical record
private GeneralPractitioner generalPractitioner; // Patiend – GeneralPractitioner 0..* 1..1
// getter and setter for patient id
public addRecord(medicalRecord) {
//…
}
}

Unable to find generated Parcelable class with Realm

I am trying to pass realm object with bundle and I used Parcel library
This is my realm model class.
Album.java
#Parcel
public class Album extends RealmObject implements Serializable {
#PrimaryKey
public String id;
public String upc;
public String albumName;
public String albumArtUrl;
public String artistName;
public String genre_id;
public String genreName;
public String price;
public String releaseYear;
public int explicit;
public RealmList<Song> songs = new RealmList<>();
}
And this is Song.java.
#Parcel
public class Song extends RealmObject implements Serializable {
#PrimaryKey
public String id;
public String isrc;
public String songName;
public String artistName;
public String album_id;
public String albumArtUrl;
public String genre_id;
public String genreName;
public String releaseYear;
public String price;
public String lyrics;
public String demo;
public int explicit;
}
When I try to pass album object in bundle like that,
b.putParcelable("album", Parcels.wrap(album));
I am having that error.
Unable to find generated Parcelable class for com.devhousemyanmar.juketrill.models.Album, verify that your class is configured properly and that the Parcelable class com.devhousemyanmar.juketrill.models.Album$$Parcelable is generated by Parceler.
please help me to solve this.
If you check the documentation, it has a section dedicated to using Parceler.
// All classes that extend RealmObject will have a matching RealmProxy class created
// by the annotation processor. Parceler must be made aware of this class. Note that
// the class is not available until the project has been compiled at least once.
#Parcel(implementations = { PersonRealmProxy.class },
value = Parcel.Serialization.BEAN, // <-- requires getters/setters if set
analyze = { Person.class })
public class Person extends RealmObject {
// ...
}
But what's worth noting is that you don't need to specify implementations = {PersonRealmProxy.class} if you use realm.copyFromRealm(song) before passing it to Parcels.wrap(). You'll need to do that anyways if you want to use field values instead of bean serialization strategy, anyways.
Also, you might need a RealmList parceler configuration.

How to store data in a class with multiple variations

So I'm kinda curious how can I store for example a list of items in my class with prices, code, quantity and so on.
Is there an easy way to have it all related and not creating a function for each variable?
You can define a List object in your class.
For example a person that has credit cards:
public Class Person {
private String name;
private List<CreditCard> creditCards;
// toString, equals, constructor, etc.
public void setCreditCards(List<CreditCard> creditCards) {
this.creditCards = creditCards;
}
public List<Creditcard> getCreditCards() {
return this.creditCards;
}
// more getters and setters
And the Credit Card:
public Class CreditCard {
private String number;
private Date expiryDate;
// getters and setters
}
And then you can make calls like this:
Person person = new Person();
List<CreditCard> cards = person.getCreditCards();
for(CreditCard card: cards) {
String number = card.getNumber();
}
A Java class can be thought of as a collection of fields (variables), and methods (functions).
The way you make a class hold more than one piece of data is to add more fields, and more methods to access those fields.
For example:
public class Cat {
int id;
String name;
double price;
public Integer getId() {
return this.id;
}
//........etc
}
You can then store that in your list and access different bits of data.

Java wrapper class subclass of concrete type

Let's say I have a class person as follows:
public class Person {
String name;
int age;
}
and a number of subclasses such as
public class Student extends Person {
// extra fields and methods
}
public class Teacher extends Person {
// extra fields and methods
}
Now, consider that for some application I need to assign an integer id to each person instance, but I don't want to extend the Person interface to add the getId() there and a field to hold the id. A simple solution would be to use a wrapper like:
public class PersonWrapper extends Person {
public PersonWrapper(Person p, int id) { // assign the id and other fields }
public int getId() { return id; }
}
This way the client code still works with the Person interface and a wrapped person can be
treated as a person.
The problem with this approach is that PersonWrapper is a subclass of Person and not Teacher or Student, and such a code won't work:
Teacher t = new PersonWrapper(teacher, 1);
t.giveGrade();
Of course, it's possible to create concrete wrapper types for all subclasses of Person, but I was wondering if there is a more elegant solution. The ideal solution would be something like this:
public class PersonWrapper<T extends Person> extends T
so that any PersonWrapper is a subclass of the type it wraps, but it's not possible in Java and I
suspect such definition may not be possible in any language.
In any case, how can I assign ids to subclasses without changing my client code that works with person and its subclasses, without creating a concrete wrapper for each subclass?
A wrapper does not necessarily need to extend to the class it's wrapping. So, just use PersonWrapper<T extends Person>:
public class PersonWrapper<T extends Person> {
T person;
int id;
public PersonWrapper(T person, int id) {
this.person = person;
this.id = id;
}
//getters and setters...
}
Also, a class can only extend from another class at compile time, so it's not possible that this PersonWrapper could extend from Student and Teacher at the same time, which makes impossible what you're looking for.
The only solution would be creating proxy classes on the fly using a library like cglib. For example, Spring creates proxies for classes when needs to add functionality on the fly to a class e.g. adding transaction management for methods or whole class.
The common solution to this problem is to make Person an interface.
interface Person {
public String getName();
public int getAge();
}
class ActualPerson implements Person {
private final String name;
private final int age;
ActualPerson(String name, int age) {
this.name = name;
this.age = age;
}
#Override
public String getName() {
return name;
}
#Override
public int getAge() {
return age;
}
}
class PersonWithId implements Person {
private final Person person;
private final int id;
PersonWithId(Person person, int id) {
this.person = person;
this.id = id;
}
#Override
public String getName() {
return person.getName();
}
#Override
public int getAge() {
return person.getAge();
}
}
Do not fear lots of code - the time you take writing code is insignificant compared to the time you spend regretting you didn't do it properly in the first place. Old Curmudgeon 2014
You're right that you can't do what you want to do. Assuming that you can't change the concrete classes to be, say, Student extends Person implements Identifiable, your best bet is to treat your wrapper really as a wrapper, and have a getter that returns its different elements:
public class Wrapper<T> {
private final T item;
private final int id;
...
public int getId() { return id }
public T getItem() { return item; }
}
This is a bit cumbersome to use, because you have to do something like wrapper.getItem().giveGrade() instead of just wrapper.giveGrade(). It also means you can't shove the wrapper into a List<Teacher> and then later downcast it to TeacherWrapper -- but that's a bit fragile, and there are often better ways to accomplish what you want. For most cases, this "pure" wrapper approach will do what you want.
Note that I didn't even have T extends Person. If the wrapper class doesn't need to use any Person methods, there's not much to gain from artificially restrict the generic. The call sites will all have the restriction either way. The one difference is that if a call site has a Wrapper<?>, then my code will only let you get the item as an Object, whereas the more restrictive T extends Person will let you get that item as a Person.
I hope I'm not missing something, but it appears to me that the wrapper pattern solves your problem:
public class Person implements IPerson{
String name;
int age;
public static void main(String[] args)
{
Teacher teacherWithID = new Teacher(new PersonWithID(new Person()));
Teacher teacherWithoutID = new Teacher(new Person());
}
}
interface IPerson{}
class Teacher implements IPerson{
public Teacher(IPerson personToBeWrapped){}
}
class Student implements IPerson{
public Student(IPerson personToBeWrapped){}
}
class PersonWithID implements IPerson{
public PersonWithID(IPerson personToBeWrapped){}
}
Whatever type your variable is should be the last wrapper.
The wrapper pattern can be considered to be a mechanic that allows you to "extend" classes at runtime. It's also called the decorator for that reason. You have competing inheritance mechanics in your code. (the built in one and the pattern) The result is that you cannot type your variable.
If you use the pattern exclusively, it works.

How to print public static final members in mongodb in a Java application?

I'm using Play-Morphia to create my application, and I have a class which has a public static final members, and when I use the find() function on my object, I get the object but only with its public or private members, but not its public static final members.
for example:
public class Person{
public String name;
public int age;
public static final String id;
}
Now, after saving this object to Mongo and then calling Person.find().first() or any Person.find() functions, I get: {"name" : "John", "age" : 30} --> with no ID included.
Does anyone has a solution to this problem?
static variables are at class level, while mongodb entities are corresponding to each object. Therefore static variables will not be saved into mongodb collection. Can you let us know why you want to put a static (and even final) variable into mongodb? What's your business logic?
Firstly, you'd be better off making the id field of type ObjectId. So I'd recommend a setup like this:
public class Person{
private final ObjectId id = new ObjectId();
private String name;
private int age;
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
}
The ObjectId can be generated on the client side and is guaranteed to be unique. Note that you should not have the static flag, but the final indicate that the field should not be changeable.
Make the fields themselves private and just don't provide a setter for id - that way other parts of your code won't be able to affect the id field.

Categories