Posted by Unknown on 1:39 AM
Labels:

The default behaviour of an object’s clone() method automatically yields a shallow copy. So to achieve a deep copy the classes must be edited or adjusted.

Shallow copy: If a shallow copy is performed on obj-1 then it is copied but its contained objects are not. The contained objects Obj-1 and Obj-2 are affected by changes to cloned Obj-2. Java supports shallow cloning of objects by default when a class implements the java.lang.Cloneable interface.




Deep copy: If a deep copy is performed on obj-1 then not only obj-1 has been copied but the objects contained within it have been copied as well. Serialization can be used to achieve deep cloning. Deep cloning through serialization is faster to develop and easier to maintain but carries a performance overhead.




class A {
int l = 1;
}

class B extends A implements Cloneable {
int m = 2;
}

class CloneDemo4 extends B {
int n = 3;
A a = new A();

public static void main(String[] args) throws CloneNotSupportedException {
CloneDemo4 c = new CloneDemo4();
CloneDemo4 c2 = (CloneDemo4) c.clone();

System.out.println(c.l);
System.out.println(c2.l);
System.out.println(c.m);
System.out.println(c2.m);
System.out.println(c.n);
System.out.println(c2.n);

System.out.println(c.a == c2.a);
}

protected Object clone() throws CloneNotSupportedException {
// First, perform a shallow copy.

CloneDemo4 temp = (CloneDemo4) super.clone();

if (a != null)
temp.a = new A();

return temp;
}
}

Posted by Unknown on 1:09 AM
Labels:

Other languages use pass-by-reference or pass-by-pointer. But in Java no matter what type of argument you pass the corresponding parameter (primitive variable or object reference) will get a copy of that data, which is exactly how pass-by-value (i.e. copy-by-value) works.


In Java, if a calling method passes a reference of an object as an argument to the called method then the passed-in reference gets copied first and then passed to the called method. Both the original reference that was passed-in and the copied reference will be pointing to the same object. So no matter which reference you use, you will be always modifying the same original object, which is how the pass-by-reference works as well.


If call involves inter-process (e.g. between two JVMs) communication, then the reference of the calling method has a different address space to the called method sitting in a separate process (i.e. separate JVM). Hence inter-process communication involves calling method passing objects as arguments to called method by-value in a serialized form, which can adversely affect performance due to marshalling and unmarshalling cost.

P.S: If image is not visible, open this in new window.


Posted by Unknown on 11:24 PM
Labels:

Polymorphism – means the ability of a single variable of a given type to be used to reference objects of different types, and automatically call the method that is specific to the type of object the variable references. In a nutshell, polymorphism is a bottom-up method call. The benefit of polymorphism is that it is very easy to add new classes of derived objects without breaking the calling code (i.e. getTotArea() in the sample code shown below) that uses the polymorphic classes or interfaces. When you send a message to an object even though you don’t know what specific type it is, and the right thing happens, that’s called polymorphism. The process used by object-
oriented programming languages to implement polymorphism is called dynamic binding.
Let us look at some sample code to demonstrate polymorphism

Inheritance – is the inclusion of behavior (i.e. methods) and state (i.e. variables) of a base class in a derived class so that they are accessible in that derived class. The key benefit of Inheritance is that it provides the formal mechanism for code reuse. Any shared piece of business logic can be moved from the derived class into the base class as part of re factoring process to improve maintainability of your code by avoiding code duplication. The existing class is called the superclass and the derived class is called the subclass. Inheritance can also be defined as the process whereby one object acquires characteristics from one or more other objects the same way children acquire characteristics from their parents.

There are two types of inheritances:
1. Implementation inheritance (Class inheritance): You can extend an applications’ functionality by reusing functionality in the parent class by inheriting all or some of the operations already implemented. In Java, you can only inherit from one superclass. Implementation inheritance promotes reusability but improper use of class inheritance can cause programming nightmares by breaking encapsulation and making future changes a problem. With implementation inheritance, the subclass becomes tightly coupled with the superclass. This will make the design fragile because if you want to change the superclass, you must know all the details of the subclasses to avoid breaking them. So when using implementation inheritance, make sure that the subclasses depend only on the behavior of the superclass, not on the actual implementation. For example in the above diagram the subclasses should only be concerned about the behavior known as area() but not how it is implemented.

2. Interface inheritance (Type inheritance): This is also known as subtyping. Interfaces provide a mechanism for specifying a relationship between otherwise unrelated classes, typically by specifying a set of common methods each implementing class must contain. Interface inheritance promotes the design concept of program to interfaces not to implementations. This also reduces the coupling or implementation dependencies between systems. In Java, you can implement any number of interfaces. This is more flexible than implementation inheritance because it won’t lock you into specific implementations which make subclasses difficult to maintain. So care should be taken not to break the implementing classes by modifying the interfaces.


Encapsulation – refers to keeping all the related members (variables and methods) together in an object. Specifying members as private can hide the variables and methods. Objects should hide their inner workings from the outside view. Good encapsulation improves code modularity by preventing objects interacting with each other in an unexpected way, which in turn makes future development and re factoring efforts easy. Being able to encapsulate members of a class is important for security and integrity. We can protect variables from unacceptable values. The sample code below describes how encapsulation can be used to protect the MyMarks object from having negative values. Any modification to member variable “vmarks” can only be carried out through the setter method setMarks(int mark). This prevents the object “MyMarks” from having any negative values by throwing an exception.
Sample code:
Class MyMarks {
private int vmarks = 0;
private String name;
public void setMarks(int mark)
throws MarkException {
if(mark > 0)
this.vmarks = mark;
else {
throw new MarkException("No negative Values");
}
}
public int getMarks(){
return vmarks;
}
//getters and setters for attribute name goes here.
}