# OOPS II - Access Modifiers & Constructors --- In this tutorial, we will learn about - Access Modifiers - Getters & Setters - Constructors - Shallow & Deep Copy - Java Memory Model - Objects & References - Life & Death on Objects on Heap - Project : Guess Game using OOPS Concepts ## Access Modifiers The access modifiers in Java specifies the accessibility or scope of a field, method, constructor, or class. We can change the access level of fields, constructors, methods, and class by applying the access modifier on it. Let's understand it through an example. ```java public class Player { //Data Members String name; private int guess; public String handle; //Example of private method // can't be called from outside the class private void assignTeam(){ ... } //example of a public method //can be called from anywhere public void setTeam(int teamId){ ... } } ``` In the above class, `guess` is private, `name` is default, `handle` is public. What does't it mean? Let understand the meanings of above acess modifiers. There are four types of access modifiers in Java: ```public``` - The access level of a public modifier is everywhere. It can be accessed from within the class, outside the class, within the package and outside the package ```protected``` - The access level of a protected modifier is within the package and outside the package through child class. If you do not make the child class, it cannot be accessed from outside the package. ```private``` - The access level of a private modifier is only within the class. It cannot be accessed from outside the class. ```default``` - The access level of a default modifier is only within the package. It cannot be accessed from outside the package. If you do not specify any access level, it will be the default. ![](https://camo.githubusercontent.com/5d78da7eb91ae3ef8b046901c1ebd8d38cf4826a80b0b9d1cd4a002664a9301e/687474703a2f2f6e65742d696e666f726d6174696f6e732e636f6d2f6a6176612f6261736963732f696d672f6163636573732d6d6f6469666965722e706e67) **Getters & Setters** If you try to read or write a private data member, outside the class, you will get a compile error. In order to work with private data members, you might need to create special public methods called `getters()` and `setters()` in the class for specific data members as shown below. ```java public class Player { //Data Members String name; private int guess; public String handle; //Setter Method public int setGuess(int guess){ //Setters can have their validation logic before updating class member if(guess>=0){ this.guess = guess; } } // Getter Method public int getGuess(){ return this.guess; } } ``` The advantage of this approach is you can set the value if it satisfies the class specific validation logic. ### Constructors A constructor is a special method that is called when an object is created. It is used to initialize the object. It is called automatically when the object is created. It can be used to set initial values for object attributes. Constructors are the gatekeepers of object-oriented design. Let us create a class for students: **Student.java** ```java public class Student { private String name; private String email; private Integer age; private String address; private String batchName; private Integer psp; public void changeBatch(String batchName) { ... } } ``` The above class can be used to create objects of type Student. This is done by using the new keyword: ```java Student student = new Student(); student.name = "Eklavya"; ``` You can notice that we did not define a constructor for the Student class. This brings us to our first type of constructor ### Default constructor A default constructor is a constructor created by the compiler if we do not define any constructor(s) for a class. A default constructor is a constructor that either has no parameters, or if it has parameters, all the parameters have default values. If no user-defined constructor exists for a class and one is needed, the compiler implicitly declares a default parameterless constructor. A default constructor is also known as a no-argument constructor or a nullary constructor. All fields are left at their initial value of 0 (integer types), 0.0 (floating-point types), false (boolean type), or null (reference types) An example of a no-argument constructor is: ```java public class Student { private String name; private String email; private Integer age; private String address; private String batchName; private Integer psp; public Student() { // no-argument constructor } } ``` Notice a few things about the constructor which we just wrote. First, it's a method, but it has no return type. That's because a constructor implicitly returns the type of the object that it creates. Calling new Student() now will call the constructor above. Secondly, it takes no arguments. This particular kind of constructor is called a no-argument constructor. **Syntax of a constructor** In Java, every class must have a constructor. Its structure looks similar to a method, but it has different purposes. A constructor has the following format ` ` Constructor declarations begin with access modifiers: They can be public, private, protected, or package access, based on other access modifiers. Unlike methods, a constructor can't be abstract, static, final, native, or synchronized. The declarator is the name of the class, followed by a parameter list. The parameter list is a comma-separated list of parameters enclosed in parentheses. The body is a block of code that defines the constructor's behavior. ```Constructor Name (Parameter List)``` ### Parameterised Constructor Now, a real benefit of constructors is that they help us maintain encapsulation when injecting state into the object. The constructor above is a no-argument constructor and hence value have to be set after the instance is created. ```java Student student = new Student(); student.name = "prateek"; student.email = "prateek@gmail.in"; ... ``` The above approach works but requires setting the values of all the fields after the instance is created. Also, we won't be able to validate or sanitize the values. We can add the validation and sanitization logic in the getters and setters but we wont be able to fail instance creation. Hence, we need to add a parameterised constructor. A parameterised constructor has the same syntax as the constructors before, the onl change is that it has a parameter list. ```java public class Student { private String name; private String email; public Student(String name, String email) { this.name = name; this.email = email; } } ``` ```java Student s1 = new Student("prateek", "prateek@gmail.in"); Student s2 = new Student("rahul", "Rahul@gmail.in"); ``` In Java, constructors differ from other methods in that: - Constructors never have an explicit return type. - Constructors cannot be directly invoked (the keyword “new” invokes them). - Constructors should not have non-access modifiers. ### Copy constructor A copy constructor is a member function that initializes an object using another object of the same class. A copy constructor has the following general function prototype: ```java class Student { private String name; private String email; public Student(String name, String email) { this.name = name; this.email = email; } //Copy Constructor public Student(Student student) { this.name = student.name; this.email = student.email; } } ``` ### Shallow & Deep Copy When we do a copy of some entity to create two or more than two entities such that changes in one entity are reflected in the other entities as well, then we can say we have done a shallow copy. In shallow copy, new memory allocation never happens for the other entities, and the only reference is copied to the other entities. The following example demonstrates the same. ```java public class Test { public int n; String name; public int arr[]; Test(int n,String name){ this.n = n; this.name = name; this.arr = new int[n]; for(int i=0;i