I have a doubt regarding setters and getters in Java when it gets to using composition instead of inheritance.
This doubt came when I was solving a college assignment.
Let's say that I have 2 classes: car and battery. Battery has 3 variables (var1, var2, var3) with the getters and setters.
The car class is something like this:
public class Car {
private String color;
private String model;
private Battery battery;
public Car(String color, String model, Battery battery) {
this.color = color;
this.model = model;
this.Battery = new Battery(battery);
}
public getBattery() {
return new Battery(battery);
}
public void setBattery(Battery battery) {
this.battery = new Battery(battery.getVar1(), battery.getVar2(), battery.getVar3());
//or this.battery = battery;
}
I know the reasoning for the getter method (since it's related with the references for the object), but what about the setter method?
I tried looking up in the web along with a Java course at Udemy (from Tim Buchalka), but I haven't seen this addressed.
Can someone help me, please? Thanks!
Each of the three methods in the Car class is making a defensive copy of the Battery. This prevents any other object outside of the Car from changing the Battery that is inside the Car, because no other object will have a reference to that specific Battery instance (since it is always copied).
The idiom new Battery(battery) is known as a copy constructor because it utilizes a constructor to clone an object. It is a common attribute of defensive copying.
In terms of the way it’s implemented, I disagree with the format. Better practice is to write this.battery = battery and leave it at that (rather than create a new object and assign its variables as done in the question).
Your code looks odd, in places, and I've changed it to what I'd expect it to look like:
public class Car {
private String color;
private String model;
private Battery battery;
public Car(String color, String model, Battery battery) {
this.color = color;
this.model = model;
//Now, we're setting Car.battery to the battery that you passed in.
//Previously, you were passing the battery instance back into the Battery constructor.
this.battery = battery;
//this.battery = new Battery(battery);
}
public getBattery() {
//We want to return the battery we have above, not a new battery
return battery;
//return new Battery(battery);
}
public void setBattery(Battery battery) {
//You wouldn't do this. Just use the line you've commented out.
//No need to remake a new Battery object when you already have one passed in.
this.battery = new Battery(battery.getVar1(), battery.getVar2(), battery.getVar3());
//or this.battery = battery;
}
What is the point of the setter method? Its to set/change the value of battery in the car instance, after you have already constructed the car. Whereas you'd use the constructor to set the battery DURING construction.
When you create a copy of battery and store it then you are making the car class immune to mutation.
Mutation means, suppose you store the battery object given as input in setter method and then somewhere down the line you make a change to the same battery object then you are inadvertently changing the battery object in the previously created car class as well which may not be intended as part of that change, hence to avoid such issues you can use this approach so that the value of battery object in car is going to change only through the setter method or through the constructor.
I hope this helps you understand why they want that extra object creation in setter method
In my opinion, if you are intend to exhibit composition in Java you should not have a getter to the component. Let's explain with an example. Say class A is composed of B. Class A (the composed) will have a private field of type B (the component). There will not be a getter to get B . If you need to access any property/ functionality of B, there should be a method of A which wraps a call to the component B's property/method.
The general rule of thumb when you have private objects (in this case, Battery) as attributes in your class, is that you need getters and setters. The getters and setters need to return a copy of the private object, so that you don't violate information hiding. Otherwise, you could do something like this:
Car c1 = new Car(...);
...
Battery b1 = new Battery(var1, var2, var3);
c1.setBattery(b1); // if setBattery doesn't make a copy,
// then the private variable battery in c1
// is the same reference as b1
b1.changeOneOfTheValues(); // I change b1, and now my private variable
// in c1 is also changed!
Related
This is a question I always had, but now is the time to solve it:
I'm trying to implement the composition of objects using public attributes like:
Person {
public Car car;
}
Owner {
public Person person;
public Car car;
}
Car {
public Person person;
}
Really my question is: Is a good practice to set that composition properties public or private?
The difference:
a) Public: doing public, the access is fast and not complicated, because I only need to reference the property directly with the instance like:
$instancePerson.car.getNumberOfGearsGood()
The problem: the car propertie is available to be modified by anybody from anywhere.
b) Private: doing private, the access if slow and is necessary to use methods to get these properties like:
$instancePerson.getCar().getNumberOfGearsGood()
When I say slow is because you need to do a method two method call, while in the Public solution only you need to do one.
I know many developers and software engineers here will prefer Private solution, but can you explain the performance there?
If you are doing OO, there should be no such thing as a "public" attribute. All the attributes are implementation details of the object, therefore are hidden from everybody. Only the methods associated with the object's responsibility are public.
So to answer the question:
All "attributes" should be private
And there should be no getter on a private attribute
Yes, there should be no
person.getCar().getNumberOfGears();
This is sometimes called the Law of Demeter. The person should have methods that do stuff connected to the responsibility of the Person class, therefore there is no performance penalty accessing attributes, because this access is always internal to the class and direct.
the short answer is that, except for very few cases, you want those variables to be private, and often technologies in the JVM will make access faster than you think it would be (and sometimes even faster than in C/C++).
For a bit more detailed answer:
The main question is: who should be able to modify those variables? for example, you may want Car to be created passing a Person to its constructor, and never allow the person to change (in a world where there is no market for used vehicles). In this case, if the field is public another object can modify it and change the owner of the car. But if you make the field private, and provide a getOwner() method, nobody can modify it. If the get method is final, and therefore can't be overridden in a subclass, the JVM might even transform internally any invocation of x.getOwner() in the equivalent of x.owner. In your example however it's not possible to pass all elements in the constructor, as they reference each other. In fact, it seems to me your model has one too many classes. Let's try to write it a bit differently:
Person {
public Car car;
}
Car {
public Person owner;
}
Now, with assuming that every car has an owner, and every person own a car, this model is dangerous, because you could do something like this:
Person p = new Person()
Car c = new Car();
p.car = c;
As you can see, I forgot to set c.owner = p.
Let's see how we can fix this:
Person {
private Car car;
public void setCar(Car c) {
if (car == c)
return;
car = c;
c.setOwner(this);
}
}
Car {
private Person owner;
public void setOwner(Person o) {
if (o == owner)
return;
owner = o;
o.setCar(this);
}
}
I can now do :
Person p = new Person();
Car c = new Car();
p.setCar(c);
or
Person p = new Person();
Car c = new Car();
c.setOwner(p);
and either way both relationship will be set correctly.
In other words, being forced to go through accessors allows to set more than just a simple field, which is useful to establish coherent state across model elements involved in a relationship.
Imagine that I have some classes that looks like this:
class Car {
private Image carImage;
public Car(int imageIndex) {
switch (imageIndex) {
case 1: carImage = generateCarImage(1); break;
# and so forth
}
}
}
class Audi extends Car {
private int numberOfSeats;
public Audi(int imageIndex, int numberOfSeats) {
super(imageIndex);
this.numberOfSeats = numberOfSeats;
}
}
Now imagine that I create multiple Audi's using the same image:
Audi car1 = new Audi(1,2);
Audi car2 = new Audi(1,3);
Will car1 and car2 extend the same object? I assume not, but is there a way I can make it so? I'm asking because I want to avoid generating and storing the same image twice.
EDIT:
Will these two audi's reference the same car, e.g. the image is generated and stored only once, and any changes to one affects the other?
class Car {
private Image carImage;
public Car(int imageIndex) {
switch (imageIndex) {
case 1: # carImage = readfile(1.jpeg)
# and so forth
}
}
}
class Audi{
private int numberOfSeats;
private Car car;
public Audi(Car car, int numberOfSeats) {
this.car = car;
this.numberOfSeats = numberOfSeats;
}
}
Car car = new Car(1);
Audi audi1 = new Audi(car,2);
Audi audi2 = new Audi(car,2);
EDIT 2:
There are a lot of good answers here, and I ended up using a combination of them to create a decent solution. My initial problem was not very well defined, mainly because I didn't know myself exactly what it was.
Anyway, for this problem it is not possible to generate all the data (PartsInfo in the example below) beforehand, nor can I generate the data explicitly (as implied by the switch-case example above). The biggest problem with the solution below is that I can't access individual fields in PartsInfo without retrieving the whole thing (as is done in the solution when Car.getPartsInfo() is called) or creating multiple instances of the same object (in which case the Car class would get its own PartsInfo variable).
A weak hashmap would also do, but not optimal because the problem is not garbage collection, but huge amount of identical data stored in separate instances.
The solution is applicable if the ID is something like "audi-a4-2003" and PartsInfo is identical for all "audi-a4-2003" independent of color, owner, age, number of seats etc, but completely different for "audi-a4-2004".
Thanks
Class PartsInfo {
// lots of stuff I'd rather not create nor save multiple times
}
Class PartsInfoFactory {
private static HashMap<String, PartsInfo> partsInfoMap = new HashMap<String, PartsInfo>();
public static getPartsInfo(String id) {
if (!partsInfoMap.containsKey(id)) {
generatePartsInfo(id);
}
return partsInfoMap(id)
}
private static generatePartsInfo(String id) {
// Do stuff I don't want to do twice for same ID
partsInfoMap.put(id)
}
}
Class Car {
private Color color;
private String id;
// Notice that PartsInfo is not stored here
public Car(Color color, String id) {
this.color = color;
this.id = id;
}
public PartsInfo getPartsInfo() {
return PartsInfoFactory.getPartsInfo(id);
}
}
Will car1 and car2 extend the same object?
A class can extend from another class.. Objects do not extend anything. In Java, inheritance is just for classes and interfaces. What you're doing here is creating two instances of the same class, Audi, and Audi extends from Car.
is there a way I can make it so?
No.
I'm asking because I want to avoid generating and storing the same image twice.
This is the proper question to answer. Your real problem is dealing with avoiding to create the same object instance multiple times. For this, it will be better to use an object pool by making use of a WeakHashMap. Here's an explanation on why to use this structure: When would you use a WeakHashMap or a WeakReference?
A good way to avoid creating the same image multiple times is to use dependency injection: inject the image as a constructor parameter, rather than passing in the parameter to generateCarImage:
class Car {
private final Image image;
Car(Image image) {
this.image = image;
}
}
class Audi extends Car {
Audi(Image image, int numDoors) {
super(image);
// ...
}
}
This means that image can come from anywhere - giving you more explicit control over the lifecycle of the images. So, if you want to use the same image over and over, you can, and it's obvious that you are:
Image image = generateCarImage(1);
Audi car1 = new Audi(image, 4);
Audi car2 = new Audi(image, 2);
Also, by removing static coupling to your generateCarImage method, it makes the class more testable, since you can create different images for testing, e.g. that are simpler to generate.
You never extend objects, you extend the class. And of course you will be extending the same class all the time.
Everytime you're using the new clause you will be creating a new instance of the object, a complete separate representation of the class; so answering to the direct question: no, you're not extending the object.
The underlying question is that you may not want to repeat the creation of to equal images: Then you must make a different approach. I recomend first to do another read to the OO aspect of Java, then think on (maybe) the factory patter which could be a class that will take care of not repeating the creation of to equal images if another was already created.
In Java there is no such thing as extending an object (other languages have this kind of inheritance, called prototypal. However, Java does not have prototypal inheritance; only a class inheritance).
Extending in Java means extending a class, not an object, which is an instance of a class.
Therefore, although the classes of car1 and car2 extend the same class, the two objects are unrelated to each other.
I want to avoid generating and storing the same image twice
There is no problem with multiple objects sharing a third object, which in your case could be an image. One way to deal with this would be creating an image cache common to all instances of Car, generate the image the first time that it is requested, and then re-using the same image object as needed to save space:
Is it possible to, instead of searching a cache of images, searching through a cache of all instances of Car, and then choose which one to instantiate in the Audi class?
You cannot instantiate an object for a second time. However, you can make a cache of Car objects, and implement a factory method on the Car that searches its cache for a suitable car before making a new instance.
My solution is using static references to be used as constant values. This is the easiest solution, given that enum won't work with objects, since it has to be evaluated at compile-time.
But we want to get both a run-time constants, and the benefit of using an enum like using single-instance and can be used in a switch statement.
So we are going to implement the enum to return constant static attributes of another class which is available at compile-time, and return a constant reference to an object created on run-time.
class CarImageDirectory
{
// Created at Run-time
public static final Image Audi = new Image("Audi");
public static final Image Toyota = new Image("Toyota");
// ..etc
}
enum CarImage
{
// Created at Compile-time
Audi
{
#Override public Image image () { return CarImageDirectory.Audi; }
},
Toyota
{
#Override public Image image () { return CarImageDirectory.Toyota; }
}; // ..etc
public abstract Image image ();
}
CarImage will work like this:
CarImage A = CarImage.Audi;
CarImage B = CarImage.Audi;
if (A == B) System.out.println("A and B are both Audi");
Then we just define our Car class using it:
class Car
{
private CarImage carImg;
public Car (CarImage carImg) { this.carImg = carImg; }
public Image getImage () { return carImg.image(); }
public CarImage getCarImage () { return carImg; }
}
class AudiCar extends Car
{
private int numOfSeats;
public AudiCar (int numOfSeats)
{
super(CarImage.Audi);
this.numOfSeats = numOfSeats;
}
}
class ToyotaCar extends Car
{
private int numOfSeats;
public ToyotaCar (int numOfSeats)
{
super(CarImage.Toyota);
this.numOfSeats = numOfSeats;
}
}
Also CarImage itself can be used in switch statement too:
CarImage A = CarImage.Audi;
switch(A)
{
case CarImage.Audi:
System.out.println("This car is Audi");
break;
case CarImage.Toyota:
System.out.println("This car is Toyota");
break;
default:
}
Have you looked into "flyweight" pattern? That might reduce object creation for you.
Technically, it's for reducing memory footprint, but if object creation is expensive and there is high reuse, you can use it in situations where startup time is not an issue, such as with application-server startups.
In any event only optimize if you know it's a performance problem.
Hope this helps!
I am experienced in JavaScript, but new to Java. In JavaScript there are "object" data types where a given variable essentially has sub-variables with their own unique values, for example:
var car = {type:"Fiat", model:500, color:"white"};
It is almost like an array, but not quite (JavaScript has arrays too). I am wondering if the same type of thing exists in Java? If so, how would I declare the same thing in Java? Based on my searches I can't find an object data type, but thought maybe there was something similar?
While Java has a type called object, it's not what you want. Almost everything in Java is an object, and there are two ways to handle this:
Define a strongly-typed object with the correct properties, as a class. Javascript has a similar concept, implemented differently, but it should be recognizable:
public class Car {
private String type;
private int model;
private String color;
public Car(final String type, final int model, final String color) {
this.type = type;
this.model = model;
this.color = color;
}
public String getType() { return this.type; }
public int getModel() { return this.model; }
public String getColor() { return this.color; }
}
final Car car = new Car("Fiat", 500, "white");
// To get the color, you must:
car.getColor();
Add methods to get and set attributes as appropriate, methods to start, stop, drive, etc.
If you want a loose collection of properties without behavior or restriction, use a Map. Again, there exists a Javascript equivalent (the {x: 1, y: 2} construct without using the new keyword).
final Map<String, Object> car = new HashMap<>();
car.put("type", "Fiat");
car.put("model", 500);
car.put("color", "white");
// To get the color, you:
car.get("color");
The disadvantage with this approach is that the compiler cannot enforce the types of those objects (nearly as well), and the map cannot have custom behaviors (in any reasonable way). In your example, model was a number, but this will allow you to assign anything regardless of whether it makes sense (perhaps someone keeps the data on a server and uses an HttpConnection, all of your code expecting a number explodes).
In Java, the first method is recommended if you know you'll have multiple cars, all with the same (or similar) properties. It allows the compiler to both enforce and optimize for the properties that you know will exist, and inheritance allows you to add additional properties later. The class also allow you to define methods which operate on that instance, which can help create abstraction between parts of the system (you don't need to know how a car starts, you just tell the car to start itself).
For reference, the Javascript equivalents are:
// #1
var Car = function(type, model, color) {
this.type = type;
this.model = model;
this.color = color;
}
var car = new Car("Fiat", 500, "white");
// #2
var car = {type: "Fiat", model: 500, color: "white"};
// For either option, to get the color you can simply:
console.log(car.color);
What should stand out most obviously is that Java keeps track of what type each variable is. Not visible is that Java will prevent you from assigning to unknown properties, say car.mileage, where Javascript will happily add a new property. Finally, Java has a concept of visibility, and makes things private (invisible to outside viewers) by default. Replicating that in Javascript would look something like:
var Car = function(type, model, color) {
var _type = type;
var _model = model;
var _color = color;
this.getType = function() { return _type; }
this.getModel = function() { return _model; }
this.getColor = function() { return _color; }
}
console.log(car.getColor());
In Javascript, you take advantage of closure to hide data. Java defaults to hidden, and requires you to expose data when you need to. It's an interesting choice, very relevant when comparing code-bases, and can help keep classes independent of one another. It's also very easy (and tempting) to violate when you start writing in OO languages, so something to keep in mind (using simple structs will come back to haunt you).
Yes, they are called Objects and defined by Classes. It's basically the first thing you learn when learning Java
//The definition of an object and it's members
public class Car {
String type, model, color;
}
You can then make them public to access and change them external to the class
public class Car {
public String type, model, color;
}
And access them like so
//Create an instance of a Car, point to it with variable c and set one of it's properties/members
Car c = new Car();
c.type = "Fiesta";
But allowing variables of a class to be edited externally is considered bad form in Java, generally you would add methods to access each, called accessors
public class Car {
private String type, model, color;
//Return the type of this object
public String getType(){
return type;
}
//Set the type of this object
public void setType(String type){
this.type = type;
}
//etc
}
Then access them like so
Car c = new Car();
c.setType("Fiesta");
A class is the template you write to create objects, which are run time instances of classes.
Most nice object for this purpose it's a LinkedHashMap. You can use it like map, but on iteration it will keep keys order.
If you want some JS-syntax in JVM you can try to use Groovy instead of Java
How can I use the set and get methods, and why should I use them? Are they really helpful? And also can you give me examples of set and get methods?
Set and Get methods are a pattern of data encapsulation. Instead of accessing class member variables directly, you define get methods to access these variables, and set methods to modify them. By encapsulating them in this manner, you have control over the public interface, should you need to change the inner workings of the class in the future.
For example, for a member variable:
Integer x;
You might have methods:
Integer getX(){ return x; }
void setX(Integer x){ this.x = x; }
chiccodoro also mentioned an important point. If you only want to allow read access to the field for any foreign classes, you can do that by only providing a public get method and keeping the set private or not providing a set at all.
I want to add to other answers that setters can be used to prevent putting the object in an invalid state.
For instance let's suppose that I've to set a TaxId, modelled as a String. The first version of the setter can be as follows:
private String taxId;
public void setTaxId(String taxId) {
this.taxId = taxId;
}
However we'd better prevent the use to set the object with an invalid taxId, so we can introduce a check:
private String taxId;
public void setTaxId(String taxId) throws IllegalArgumentException {
if (isTaxIdValid(taxId)) {
throw new IllegalArgumentException("Tax Id '" + taxId + "' is invalid");
}
this.taxId = taxId;
}
The next step, to improve the modularity of the program, is to make the TaxId itself as an Object, able to check itself.
private final TaxId taxId = new TaxId()
public void setTaxId(String taxIdString) throws IllegalArgumentException {
taxId.set(taxIdString); //will throw exception if not valid
}
Similarly for the getter, what if we don't have a value yet? Maybe we want to have a different path, we could say:
public String getTaxId() throws IllegalStateException {
return taxId.get(); //will throw exception if not set
}
I think you want something like this:
public class Person {
private int age;
//public method to get the age variable
public int getAge(){
return this.age
}
//public method to set the age variable
public void setAge(int age){
this.age = age;
}
}
You're simply calling such a method on an object instance. Such methods are useful especially if setting something is supposed to have side effects. E.g. if you want to react to certain events like:
public void setAge(int age){
this.age = age;
double averageCigarettesPerYear = this.smokedCigarettes * 1.0 / age;
if(averageCigarettesPerYear >= 7300.0) {
this.eventBus.fire(new PersonSmokesTooMuchEvent(this));
}
}
Of course this can be dangerous if somebody forgets to call setAge(int) where he should and sets age directly using this.age.
Setters and getters are used to replace directly accessing member variables from external classes. if you use a setter and getter in accessing a property, you can include initialization, error checking, complex transformations, etc. Some examples:
private String x;
public void setX(String newX) {
if (newX == null) {
x = "";
} else {
x = newX;
}
}
public String getX() {
if (x == null) {
return "";
} else {
return x;
}
}
Having accessor methods is preferred to accessing fields directly, because it controls how fields are accessed (may impose data checking etc) and fits with interfaces (interfaces can not requires fields to be present, only methods).
Some benefits of using getters and setters (known as encapsulation or data-hiding):
(originally answered here)
1. The fields of a class can be made read-only (by only providing the getter) or write-only (by only providing the setter). This gives the class a total control of who gets to access/modify its fields.
Example:
class EncapsulationExample {
private int readOnly = -1; // this value can only be read, not altered
private int writeOnly = 0; // this value can only be changed, not viewed
public int getReadOnly() {
return readOnly;
}
public int setWriteOnly(int w) {
writeOnly = w;
}
}
2. The users of a class do not need to know how the class actually stores the data. This means data is separated and exists independently from the users thus allowing the code to be more easily modified and maintained. This allows the maintainers to make frequent changes like bug fixes, design and performance enhancements, all while not impacting users.
Furthermore, encapsulated resources are uniformly accessible to each user and have identical behavior independent of the user since this behavior is internally defined in the class.
Example (getting a value):
class EncapsulationExample {
private int value;
public int getValue() {
return value; // return the value
}
}
Now what if I wanted to return twice the value instead? I can just alter my getter and all the code that is using my example doesn't need to change and will get twice the value:
class EncapsulationExample {
private int value;
public int getValue() {
return value*2; // return twice the value
}
}
3. Makes the code cleaner, more readable and easier to comprehend.
Here is an example:
No encapsulation:
class Box {
int widthS; // width of the side
int widthT; // width of the top
// other stuff
}
// ...
Box b = new Box();
int w1 = b.widthS; // Hm... what is widthS again?
int w2 = b.widthT; // Don't mistake the names. I should make sure I use the proper variable here!
With encapsulation:
class Box {
private int widthS; // width of the side
private int widthT; // width of the top
public int getSideWidth() {
return widthS;
}
public int getTopWIdth() {
return widthT;
}
// other stuff
}
// ...
Box b = new Box();
int w1 = b.getSideWidth(); // Ok, this one gives me the width of the side
int w2 = b.getTopWidth(); // and this one gives me the width of the top. No confusion, whew!
Look how much more control you have on which information you are getting and how much clearer this is in the second example. Mind you, this example is trivial and in real-life the classes you would be dealing with a lot of resources being accessed by many different components. Thus, encapsulating the resources makes it clearer which ones we are accessing and in what way (getting or setting).
Here is good SO thread on this topic.
Here is good read on data encapsulation.
The above answers summarize the role of getters and setters better than I could, however I did want to add that your code should ideally be structured to reduce the use of pure getters and setters, i.e. those without complex constructions, validation, and so forth, as they break encapsulation. This doesn't mean you can't ever use them (stivlo's answer shows an example of a good use of getters and setters), just try to minimize how often you use them.
The problem is that getters and setters can act as a workaround for direct access of private data. Private data is called private because it's not meant to be shared with other objects; it's meant as a representation of the object's state. Allowing other objects to access an object's private fields defeats the entire purpose of setting it private in the first place. Moreover, you introduce coupling for every getter or setter you write. Consider this, for example:
private String foo;
public void setFoo(String bar) {
this.foo = bar;
}
What happens if, somewhere down the road, you decide you don't need foo anymore, or you want to make it an integer? Every object that uses the setFoo method now needs to be changed along with foo.
just because the OOP rule: Data Hiding and Encapsulation. It is a very bad practice to declare a object's as public and change it on the fly in most situations. Also there are many other reasons , but the root is Encapsulation in OOP. and "buy a book or go read on Object Oriented Programming ", you will understand everything on this after you read any book on OOP.
The benefits of get() set() methods are as follows ..
You can serialize you object easily.
You can create a persistent object from the containing class.
You can convert the properties to JSON easily.
In the DAO layer (Frameworks like Hibernate) you can directly save the object to DB.
Easy understanding of object oriented concept.
Needs in all design pattern except possibly in single tone pattern.
Security for properties protecting direct access.
Polymorphism, Encapsulation can be easily understood and implemented by this type of class.
Example:
private String personName;
private int personId;
public void setPersonName(String name) throws Exception{
if(!(name.equals("")||name=="")){
this.personName = name;
}
}
public String getPersonName(){
return this.personName;
}
public void setPersonId(int id) throws Exception{
this.personId = id;
}
public int getPersonId(){
return this.personId;
}
Above answers all assume that the object in question is an object with behaviour.
An advanced strategy in OOP is to separate data objects (that do zip, only have fields) and behaviour objects.
With data objects, it is perfectly fine to omit getters and instead have public fields. They usually don't have setters, since they most commonly are immutable - their fields are set via the constructors, and never again.
Have a look at Bob Martin's Clean Code or Pryce and Freeman's Growing OO Software... for details.
public class Person{
private int age;
public int getAge(){
return age;
}
public void setAge(int age){
this.age = age;
}
}
i think this is you want..
and this also called pojo
this is the code for set method
public void setAge(int age){
this.age = age;
}
It looks like you trying to do something similar to C# if you want setAge create method setAge(int age){
this.age = age;}
I don't see a simple answer to the second question (why) here. So here goes.
Let's say you have a public field that gets used very often in your code. Whenever you decide you need to do something extra before you give or set this field you have a problem. You have to create a special getter and setter for this field and change your complete code from using the field directly to using the getter and setters.
Now imagine you are developing a library widely used by many people. When you need to make a change like the above and set direct access of the field to private the code of all the people using this field will break.
Using getters and setters is about future planning of the code, it makes it more flexible. Of course you can use public fields, especially for simple classes that just hold some data. But it's always a good idea to just make the field privately and code a get and set method for it.
This answer is merged from another question.
Your getAge() method is called instance method in Java.
To invoke an instance method, you should have a object of the Class in which this method is defined.
For Example, If this method in a Class called Person, then
Create a Person object using new operator
Person p = new Person();
To get the age of a Person object, use this method
p.getAge()
Although still a second year undergraduate student I will say my opinion. I believe that Java and private variables within your class are "RULES". Therefore because the variables in your class are private I think you use getters and setters to be able to define these variables outside the class.
How can I use the set and get methods, and why should I use them? Are they really helpful? And also can you give me examples of set and get methods?
Set and Get methods are a pattern of data encapsulation. Instead of accessing class member variables directly, you define get methods to access these variables, and set methods to modify them. By encapsulating them in this manner, you have control over the public interface, should you need to change the inner workings of the class in the future.
For example, for a member variable:
Integer x;
You might have methods:
Integer getX(){ return x; }
void setX(Integer x){ this.x = x; }
chiccodoro also mentioned an important point. If you only want to allow read access to the field for any foreign classes, you can do that by only providing a public get method and keeping the set private or not providing a set at all.
I want to add to other answers that setters can be used to prevent putting the object in an invalid state.
For instance let's suppose that I've to set a TaxId, modelled as a String. The first version of the setter can be as follows:
private String taxId;
public void setTaxId(String taxId) {
this.taxId = taxId;
}
However we'd better prevent the use to set the object with an invalid taxId, so we can introduce a check:
private String taxId;
public void setTaxId(String taxId) throws IllegalArgumentException {
if (isTaxIdValid(taxId)) {
throw new IllegalArgumentException("Tax Id '" + taxId + "' is invalid");
}
this.taxId = taxId;
}
The next step, to improve the modularity of the program, is to make the TaxId itself as an Object, able to check itself.
private final TaxId taxId = new TaxId()
public void setTaxId(String taxIdString) throws IllegalArgumentException {
taxId.set(taxIdString); //will throw exception if not valid
}
Similarly for the getter, what if we don't have a value yet? Maybe we want to have a different path, we could say:
public String getTaxId() throws IllegalStateException {
return taxId.get(); //will throw exception if not set
}
I think you want something like this:
public class Person {
private int age;
//public method to get the age variable
public int getAge(){
return this.age
}
//public method to set the age variable
public void setAge(int age){
this.age = age;
}
}
You're simply calling such a method on an object instance. Such methods are useful especially if setting something is supposed to have side effects. E.g. if you want to react to certain events like:
public void setAge(int age){
this.age = age;
double averageCigarettesPerYear = this.smokedCigarettes * 1.0 / age;
if(averageCigarettesPerYear >= 7300.0) {
this.eventBus.fire(new PersonSmokesTooMuchEvent(this));
}
}
Of course this can be dangerous if somebody forgets to call setAge(int) where he should and sets age directly using this.age.
Setters and getters are used to replace directly accessing member variables from external classes. if you use a setter and getter in accessing a property, you can include initialization, error checking, complex transformations, etc. Some examples:
private String x;
public void setX(String newX) {
if (newX == null) {
x = "";
} else {
x = newX;
}
}
public String getX() {
if (x == null) {
return "";
} else {
return x;
}
}
Having accessor methods is preferred to accessing fields directly, because it controls how fields are accessed (may impose data checking etc) and fits with interfaces (interfaces can not requires fields to be present, only methods).
Some benefits of using getters and setters (known as encapsulation or data-hiding):
(originally answered here)
1. The fields of a class can be made read-only (by only providing the getter) or write-only (by only providing the setter). This gives the class a total control of who gets to access/modify its fields.
Example:
class EncapsulationExample {
private int readOnly = -1; // this value can only be read, not altered
private int writeOnly = 0; // this value can only be changed, not viewed
public int getReadOnly() {
return readOnly;
}
public int setWriteOnly(int w) {
writeOnly = w;
}
}
2. The users of a class do not need to know how the class actually stores the data. This means data is separated and exists independently from the users thus allowing the code to be more easily modified and maintained. This allows the maintainers to make frequent changes like bug fixes, design and performance enhancements, all while not impacting users.
Furthermore, encapsulated resources are uniformly accessible to each user and have identical behavior independent of the user since this behavior is internally defined in the class.
Example (getting a value):
class EncapsulationExample {
private int value;
public int getValue() {
return value; // return the value
}
}
Now what if I wanted to return twice the value instead? I can just alter my getter and all the code that is using my example doesn't need to change and will get twice the value:
class EncapsulationExample {
private int value;
public int getValue() {
return value*2; // return twice the value
}
}
3. Makes the code cleaner, more readable and easier to comprehend.
Here is an example:
No encapsulation:
class Box {
int widthS; // width of the side
int widthT; // width of the top
// other stuff
}
// ...
Box b = new Box();
int w1 = b.widthS; // Hm... what is widthS again?
int w2 = b.widthT; // Don't mistake the names. I should make sure I use the proper variable here!
With encapsulation:
class Box {
private int widthS; // width of the side
private int widthT; // width of the top
public int getSideWidth() {
return widthS;
}
public int getTopWIdth() {
return widthT;
}
// other stuff
}
// ...
Box b = new Box();
int w1 = b.getSideWidth(); // Ok, this one gives me the width of the side
int w2 = b.getTopWidth(); // and this one gives me the width of the top. No confusion, whew!
Look how much more control you have on which information you are getting and how much clearer this is in the second example. Mind you, this example is trivial and in real-life the classes you would be dealing with a lot of resources being accessed by many different components. Thus, encapsulating the resources makes it clearer which ones we are accessing and in what way (getting or setting).
Here is good SO thread on this topic.
Here is good read on data encapsulation.
The above answers summarize the role of getters and setters better than I could, however I did want to add that your code should ideally be structured to reduce the use of pure getters and setters, i.e. those without complex constructions, validation, and so forth, as they break encapsulation. This doesn't mean you can't ever use them (stivlo's answer shows an example of a good use of getters and setters), just try to minimize how often you use them.
The problem is that getters and setters can act as a workaround for direct access of private data. Private data is called private because it's not meant to be shared with other objects; it's meant as a representation of the object's state. Allowing other objects to access an object's private fields defeats the entire purpose of setting it private in the first place. Moreover, you introduce coupling for every getter or setter you write. Consider this, for example:
private String foo;
public void setFoo(String bar) {
this.foo = bar;
}
What happens if, somewhere down the road, you decide you don't need foo anymore, or you want to make it an integer? Every object that uses the setFoo method now needs to be changed along with foo.
just because the OOP rule: Data Hiding and Encapsulation. It is a very bad practice to declare a object's as public and change it on the fly in most situations. Also there are many other reasons , but the root is Encapsulation in OOP. and "buy a book or go read on Object Oriented Programming ", you will understand everything on this after you read any book on OOP.
The benefits of get() set() methods are as follows ..
You can serialize you object easily.
You can create a persistent object from the containing class.
You can convert the properties to JSON easily.
In the DAO layer (Frameworks like Hibernate) you can directly save the object to DB.
Easy understanding of object oriented concept.
Needs in all design pattern except possibly in single tone pattern.
Security for properties protecting direct access.
Polymorphism, Encapsulation can be easily understood and implemented by this type of class.
Example:
private String personName;
private int personId;
public void setPersonName(String name) throws Exception{
if(!(name.equals("")||name=="")){
this.personName = name;
}
}
public String getPersonName(){
return this.personName;
}
public void setPersonId(int id) throws Exception{
this.personId = id;
}
public int getPersonId(){
return this.personId;
}
Above answers all assume that the object in question is an object with behaviour.
An advanced strategy in OOP is to separate data objects (that do zip, only have fields) and behaviour objects.
With data objects, it is perfectly fine to omit getters and instead have public fields. They usually don't have setters, since they most commonly are immutable - their fields are set via the constructors, and never again.
Have a look at Bob Martin's Clean Code or Pryce and Freeman's Growing OO Software... for details.
public class Person{
private int age;
public int getAge(){
return age;
}
public void setAge(int age){
this.age = age;
}
}
i think this is you want..
and this also called pojo
this is the code for set method
public void setAge(int age){
this.age = age;
}
It looks like you trying to do something similar to C# if you want setAge create method setAge(int age){
this.age = age;}
I don't see a simple answer to the second question (why) here. So here goes.
Let's say you have a public field that gets used very often in your code. Whenever you decide you need to do something extra before you give or set this field you have a problem. You have to create a special getter and setter for this field and change your complete code from using the field directly to using the getter and setters.
Now imagine you are developing a library widely used by many people. When you need to make a change like the above and set direct access of the field to private the code of all the people using this field will break.
Using getters and setters is about future planning of the code, it makes it more flexible. Of course you can use public fields, especially for simple classes that just hold some data. But it's always a good idea to just make the field privately and code a get and set method for it.
This answer is merged from another question.
Your getAge() method is called instance method in Java.
To invoke an instance method, you should have a object of the Class in which this method is defined.
For Example, If this method in a Class called Person, then
Create a Person object using new operator
Person p = new Person();
To get the age of a Person object, use this method
p.getAge()
Although still a second year undergraduate student I will say my opinion. I believe that Java and private variables within your class are "RULES". Therefore because the variables in your class are private I think you use getters and setters to be able to define these variables outside the class.