Preferred way of declaring methods in a class - java

I am having a doubt with method creations in a class for setting information.
creating separate methods for setting each attribute
class Address{
private String name;
private String city;
public setName(String name) { ... }
public setCity(String name) { ... }
}
creating single method for setting all attributes
class Address{
private String name;
private String city;
public setAddress(String name,String city) { ... }
}
from above two ways which is preferable in memory point of view?

Common practice is to use JavaBean style
class Address {
private String name;
private String city;
public setName(String name){
this.name = name;
}
public String getName() {
return name;
}
public setCity(String city){
this.city = city;
}
public getCity() {
return city;
}
}
Another common practise, which is quite similar to you second approach is to create immutable object. Parameters are passed to constructor instead of big setter method.
class Address {
private final String name;
private final String city;
public Address(String name, String city) {
this.name = name;
this.city = city;
}
public String getName() {
return name;
}
public getCity() {
return city;
}
}
From memory point of view, difference would be that second example is setting all attributes in constructor and all those attributes are immutable. In general, object constructed this way are safer when used by multiple threads.
In second example, there is no need for synchronization. You'd need to handle synchronization/memory issues when multiple threads using standard JavaBean object.

I can't see how the two approaches would be any different memory-wise.
Choose the approach that makes most sense to have in the interface of the class.
I would recommend to go with approach 2 only if both properties are logically strongly related, or if there is some class invariant that you don't want to temporarily break (even temporarily).
In your Address example, I would definitely go with two setter methods, since when talking about addresses, the name and city are quite unrelated.
For methods in general I'd say that whether or not you split a method up in two has little effect on memory consumption. Each object doesn't get its own set of methods allocated. The memory containing the methods is shared between all instances of a class.
Rule of thumb: Strive to make the interface of your class clean and logical.

Why not to use method #2
Your second example is not recommended because if you added a new field to the Address class, then do you add it into the existing setter method or do you create a new setter method? If you add it into the existing setter method, then any classes that called that method would be broken. And if you created a new setter method, then it is confusing for anyone who wants to use that class why certain fields are grouped together that way while others are not.
Using a separate setter method for each field that you wish to expose
The common practice is to have a single setter method for each field in your class that you wish to expose (i.e. your first example). Whether or not this is a good practice is debatable because it forces a class to be mutable. It is best to make an object immutable, if possible, for a number of reasons.
Initializing your fields using a constructor
One way to make a class immutable is by getting rid of the setter methods and instead making your fields settable via your class constructor, as below. The downside to implementing it this way is that if your class has a lot of fields, it may potentially lead to large, unreadable constructor calls.
public class Address {
public String name;
public String city;
private Address(String name, String city) {
this.name = name;
this.city = city;
}
}
Initializing your fields using the Builder pattern
Below is a completely alternative implementation (inspired by this article) that is a variation of the Builder pattern. It simulates object mutability without sacrificing readability.
public class Address {
public String name;
public String city;
private Address() {}
private void setName(String name) {
this.name = name;
}
private void setCity(String city) {
this.city = city;
}
static class Builder {
private Address address = new Address();
public Builder name(String name) {
address.setName(name);
return this;
}
public Builder city(String city) {
address.setCity(city);
return this;
}
public Address build() {
return address;
}
}
}
With the above class, you could create an immutable instance of the Address class as follows:
Address address = new Address.Builder()
.name("Mansoor's address")
.city("Toronto")
.build();
Which approach uses more memory?
From a memory point of view, there shouldn't be any difference since the size of a class in memory is dependent on the fields in the class. Since all three implementations have the same fields, they should take the same amount of space in memory, regardless of which approach you use.

This is not a clear question. Do you mean, would you rather have two methods like setFoo(String) and setBar(int), or one method like setFooBar(String, int)? It really depends on whether these are logically different properties, in which case you want individual methods, or whether it often (or only) makes sense to set them together. You could provide both.
Neither has any impact on memory, no.

The JavaBean standard is to have getters and setters for each property: http://en.wikibooks.org/wiki/Java_Programming/Java_Beans. If you don't want to follow that standard convention, its what makes the most sense for your shop. As per other answers on this thread, there probably is a minimal memory delta, if any.

Nb.1 without a doubt.
And you don't write that code by hand, only declare your fields.
Then you let Eclipse do the rest for you.
In Eclipse use Source --> generate getters and setters.
A very similar construct as #2 is done in the objects constructor.
The updated question with regards to memory. Don't worry one second in production code for the memory difference between those two ways.

You generally write a setter and a getter method for each attribute.
I don't really see the case when one method is enough for setting all the attributes. In this case, all attributes should have the same value? Or you always would have to pass parameters for all attributes. Both cases are not really what you want. So you should clearly prefer your first approach.

Related

Is it a good practice to create methods inside an abstract class and not override them inside the class which extends it?

I have got a question.
Should I create getter and setter methods inside abstract class? The below example contains these methods inside abstract class which is extended by Individual class. Is it a good practice to have different variety on methods inside abstract class? Should I be overriding those methods inside Individual class? However it doesn't make sense for me to override those as these will not do anything different, just set and get different attributes. Any advice?
public abstract class Human {
private String name;
private String surname;
public Human(String name, String surname) {
this.name = name;
this.surname = 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;
}
}
public class Individual extends Human{
private String dob;
public Individual(String name, String surname, String dob) {
super(name, surname);
this.dob = dob;
}
public String getDob() {
return dob;
}
public void setDob(String dob) {
this.dob = dob;
}
public void viewIndividual(){
System.out.println("First name of individual is: " + getName());
System.out.println("Surname of individual is: " + getSurname());
System.out.println("Date of birth of individual is: " + getDob());
}
}
Should I create getter and setter methods inside abstract class?
Yes, if a method is common to most expected implementations of an abstract class, it's perfectly fine to implement those methods in the abstract class. If it's really good to have getters and setters for the properties of your Human, it hard to say. The way you're currently using it, it doesn't make much sense, as you're mixing behavior aspects (viewIndividual) with data aspects (getters and setters) in one class. Given the code above you would be fine with protected members in the abstract class, and potentially setters to avoid code duplication in the implementations. But if you want to use your objects as Java-Beans, it's fine.
Is it a good practice to have different variety on methods inside abstract class?
You mean both, abstract and non-abstract methods? Yes, this is pretty standard. Take this example:
public abstract class Example {
public final void publicMethod() {
// do some preparations
internalMethod();
// do some cleanup
}
protected abstract void internalMethod();
}
Consumers of implementations of Example will only be able to access publicMethod and it is guaranteed that all needed preparations and cleanup tasks are executed without repeating this code over and over again in the implementations of Example as only internalMethod needs to be overridden.
Should I be overriding those methods inside Individual class?
No, definitively not. At least as long as you don't add additional functionality to the methods, abstract methods should not be overridden just for implementing them inside the instantiatable class.
In general you should be careful with inheritance as code tends to become very hard to understand, if you implement something in a deep type hierarchy. IMHO hierarchies start to become hard to use with a hierarchy level of 4-5 already, but this is probably heavily opinion based. There is the rule to prefer composition over inheritance to avoid over-exhaustive use of inheritance for simple utility stuff.

How can we create immutable class object using setter instead constructor.As I want to use its setter method .Does it Possible to make immutable?

Creating immutable class using setter method from outside class.As i have a POJO Class Object creation may be done using setter method.How come it possible to make immutable using setter
Setters are mutators.
https://en.wikipedia.org/wiki/Mutator_method
I think you might be referring to a factory method?
https://www.tutorialspoint.com/design_pattern/factory_pattern.htm
Or maybe you have some hybrid thingo going on.
People more experienced then me would have better answers.
You can use the Builder Pattern. There you have a separate builder class with a kind of setter for each field. The final build() eventually creates the immutable object.
public final class Person {
private final String forename;
private final String surename;
private final int age;
private Person(String forename, String surename, int age) {
this.forename = forename;
this.surename = surename;
this.age = age;
}
public String getForename() {
return forename;
}
public String getSurename() {
return surename;
}
public int getAge() {
return age;
}
public static PersonBuilder createBuilder() {
return new PersonBuilder();
}
public static class PersonBuilder {
private String forename;
private String surename;
private int age;
private PersonBuilder() {
}
public PersonBuilder withForename(String forename) {
this.forename = forename;
return this;
}
public PersonBuilder withSurename(String surename) {
this.surename = surename;
return this;
}
public PersonBuilder withAge(int age) {
this.age = age;
return this;
}
public Person build() {
return new Person(forename, surename, age);
}
}
You can then create a Person instance like so:
Person person = Person.createBuilder().withSurename("Krueger")
.withForename("Freddy").withAge(47).build();
With a builder you have the best of both worlds. The flexibility of setters (including fluent API) and immutable objects at the end.
Edit:
Joshua Bloch stated in Item 15: "Minimize Mutability" in his book "Effective Java":
To make a class immutable, follow these five rules:
Don’t provide any methods that modify the object’s state (known as mutators).
Ensure that the class can’t be extended. [...]
Make all fields final. [...]
Make all fields private. [...]
Ensure exclusive access to any mutable components. [...]
To fulfill point 2 I added the final keyword to the above Person class.
According to this widely accepted definition of immutability a class with setters is per se not immutable because it violates point 1.
If think the intention to ask this question in an interview is to see wether the candidate is able to recognize the discrepancy in the question itself and how far goes the knowledge about immutability and the various alternatives to create instances of immutable classes (per constructor, per static factory methods, per factory classes, per builder pattern, ...).

Java class storing static data

I have a large amount of static data that I want to store in my code, and I'm not sure the best way to do this. As an example, I want to store some fields like first name, last name, address, and phone number. I want to store this for several different users.
My initial thoughts were that I'd create a class with the fields I want, and then I'd make that class a nested class. I would make the outer class singleton and have an ArrayList of the inner class. I'd then instantiate several copies of the inner class. I feel like this is going to be awful though, because I don't want to instantiate several copies of a class. I want to just have one class with all the information.
Anyone know how I should go about this?
I hope I got you right. It seems that you want to have a set of constant (immutable) Person objects. If it is true, enumeration is the thing you are looking for. You can have something like:
enum Person {
Kent("myLast","Kfirst","kfoo"),
Someone("sLast", "sFirst", "sfoo");
private String lastname;
private String firstname;
private String foo;
Person(String lastname, String firstname, String foo) {
this.lastname = lastname;
this.firstname = firstname;
this.foo = foo;
}
public String getLastname() {
return lastname;
}
public String getFirstname() {
return firstname;
}
public String getFoo() {
return foo;
}
}
you can get field value by:
Person.Kent.getFirstname();
I am not sure if I understand you right.
What you are looking for is inheritance. You can have a class called Person which contains all the fields you want (along with appropriate methods). Then you can have other specialized persons like a Manager or what not by extending that class (If you want to, that is. Or else, you can just instantiate a Person).
You use static when your data is to be shared among objects of the class. If you have the name and age, say, as static then you will be in hot water. You need them to be non-statics. That way every object will have their own copy of the fields.
Have a look : http://docs.oracle.com/javase/tutorial/java/javaOO/classvars.html
What about making an interface with all needed constants?
Then every class you want to contain those static values will implement that interface?

Eclipse formatter for getter/setter to single line?

How can I tell (if ever) Eclipse to make a single line for a getter or setter when using auto formatting?
public User getUser() {
return user;
}
to:
public User getUser() { return user; }
If you don't like all the boilerplate which Java forces you to write, you might be interested in Project Lombok as an alternative solution.
Instead of trying to format your code to minimize the visual impact of getters and setters, Project Lombok allows them to be added by the compiler behind the scenes, guided by annotations on your class's fields.
Instead of writing a class like this:
public class GetterSetterExample {
private int age = 10;
private String name;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
protected void setName(String name) {
this.name = name;
}
}
You would write:
import lombok.AccessLevel;
import lombok.Getter;
import lombok.Setter;
public class GetterSetterExample {
#Getter #Setter private int age = 10;
#Setter(AccessLevel.PROTECTED) private String name;
}
(example from: http://projectlombok.org/features/GetterSetter.html)
Java code formatting in Eclipse does not differentiate between getters/setters and any other methods in a class. So this cannot be done by built-in eclipse formatting.
As other posters have stated, Eclipse cannot currently do this. There is a feature request at https://bugs.eclipse.org/bugs/show_bug.cgi?id=205973 however, and if it gets enough upvotes there's a chance somebody might implement it...
How about using formatter on/off tags:
//#formatter:off
#override public final String getName() {return this.name;}
//#formatter:on
You will need to make sure that the on/off tags are enabled (preferences/java/code style/formatter/edit/on off tags). This may be the default.
For just one method it will be just as ugly as a three line getter method, but if you have more than four or five then it will look neater.
It also allows you to group the getters and setters for a property together rather than all the getters and then all the setters.
That is my solution, anyway.

What's the most object-oriented way to design an address book?

I am asking myself how to design an object-oriented address book in Java.
Let's say a contact can have several contact details, like addresses, phone numbers and e-mail addresses.
One way to implement this would be to give every contact an ArrayList for every type. But there must be a better and more object-oriented solution. What is it?
The most OOP suggestion I can give you is to create a class for every item/piece of information. For example:
public abstract class ContactInfo { /* ... */ }
public class Address extends ContactInfo { /* ... */ }
public class PhoneNumber extends ContactInfo { /* ... */ }
public class EmailAddress extends ContactInfo { /* ... */ }
public class Contact {
private String name;
private Set<ContactInfo> info;
// ...
}
and finally,
public class AddressBook {
List<Contact> contacts;
// ...
}
This may or may not be overkill for your specific case, but as a thought experiment, it's the way to go. It obviously takes care of the literal part of OOP — using objects — but also lays groundwork for encapsulation, abstraction and inheritance, which are closely related principles.
You're on the right track. The only thing I would do differently would be to use a List interface instead of an ArrayList collection to reference the contacts' attribute collections. This is advice based on the code-to-interfaces rule-of-thumb as described in this article and many others.
I don't think that's particularly un-object oriented. If your domain is such that a Person can have zero or more EmailAddresses, then you've almost exactly described the situation to use a list.
The only alternative approach I can think of would be to have fields such as
WorkEmail
PersonalEmail
OtherEmail1
OtherEmail2
OtherEmail3
but in my opinion that's worse, because:
You simply cannot support more than five email addresses (well, you could add more fields, but that increases the pain of the latter points and still imposes some finite limit.)
You're implying some extra semantics than may be present (what if the same address is used for work and personal? What if neither applies, can you just fill the Other ones? What if you don't know the purpose?)
You now have to test each field manually to see which is null, which is going to involve a non-trivial amount of duplication in Java. You can't use nice features like the enhanced-for loop to apply the same block to every email address, and you can't trivially count how many addresses there are
The list of properties that a Person has is now much less clean. I suppose you could package these properties into an EmailContactDetails class or something, but now you've got an extra level of indirection (more conceptual complexity) for no real gain.
So, if a person has a possibly-empty, unbounded list of email addresses, what's wrong with representing that as a list?
You can also use a Map, and then get specific values e.g. via myMap.get("emailAdress1") or iterate over the whole map like you would do with a list via myMap.entrySet().
One simple way to handle most of the use cases can be like this
public class AddressBook {
private Map<String, Contact> contacts;
AddressBook(){
contacts = new HashMap<String, Contact>();
}
public boolean addContact(Contact contact) {
if(contacts.containsKey(contact.getName())) {
System.out.println("Already exists");
return false;
}
contacts.put(contact.getName(), contact);
return true;
}
public boolean updateContact(Contact contact) {
contacts.put(contact.getName(), contact);
return true;
}
}
class Contact{
private String name;
private String email;
private String phone;
private Address address;
public Contact(String name) {
this.name = name;
}
public Contact(String name, String email, String phone, Address address) {
this.name = name;
this.email = email;
this.phone = phone;
this.address = address;
}
// getters and setters
#Override
public String toString() {
return "name is "+name+" and address is "+address;
}
}
class Address{
private String street1;
private String street2;
private String city;
private int zipcode;
public Address() {}
// getters and setters
#Override
public String toString() {
return "street1 is "+street1+" and zipcode is "+zipcode;
}
}

Categories