What is Proxy Design Pattern?

Provide a surrogate or placeholder for another object. This Place holder object provides some advantages, few are as below.

#1. to Access Remote Object.
#2. to control access of few methods of original object.
#3. it may be costly(consumes more memory or time) to use original object.
…and many more.

Below is an example, of using place holder object of VideoProxy instead of original Video object.

As shown in example below, object of Video class loads video file, even to display thumb nail. As known it consumes more memory to load multiple video thumb nails, in a single screen.

To keep memory consumption minimal, ProxyVideo has been implemented, which displays an Image to display thumb nail. And the video file is loaded, only when user want to play the video, that too only the specific video file which the user opted to view, will be loaded to play.

public interface IVideo {
   void displayThumbnail();
   void playVideo();
}

public class Video implements Image {

   private String fileName;

   public Video(String fileName){
      this.fileName = fileName;
   }

   @Override
   public void displayThumbnail() {
      loadVideoFromStorage();
      System.out.println("Displaying Thumbnail of " + fileName);
   }

   private void loadVideoFromStorage(){
      System.out.println("Loading actual video... " + fileName);
   }

   @override
   public void playVideo()
   {
      loadVideoFromStorage();
   }
}

public class ProxyVideo implements IVideo{

   private Video objVideo;
   private String fileName;

   public Video(String fileName){
      this.fileName = fileName;
   }

   @Override
   public void displayThumbnail() {
      String thumbnail_name = fileName+"_thumbnail.jpg";
      System.out.println("Display Thumbnail Image..."+thumbnail_name);
   }

   @Override
   public void playVideo() {
      objVideo = new Video(fileName);
      objVideo.playVideo();
   }
}

In this example, Aggregation is used(Read more on Composition and Aggregation), instead inheritance can be used here.

Difference between Proxy and Adapter Pattern

Adapter Pattern is to change the interface of class A to the expectations of another class B. The typical implementation is a wrapper class or set of classes.

Proxy Pattern is similar, but the purpose is different. The purpose of the proxy pattern is to create a stand-in for a real resource. As already briefed, this stand-in is required as the actual object is remotely located or it is expensive to create actual object or you want to give controlled access to methods of actual class, etc…

You may also like to read:
What is Factory Design Pattern
How to implement Singleton Design Pattern
Can Adapter Pattern use Composition
Adapter Pattern using Inheritance

Difference between Composition and Aggregation

In Object oriented languages, Composition, Aggregation and Inheritance are the most common relationships exist between classes.

Composition in Java

Composition is has-a relationship. Also sometimes referred as non-separable part of the whole.
Composition is more stronger relationship compared to Aggregation. Here composed object cannot exist without composing object, and both objects have same life time.

As shown in below code snippet, object of B(i..e obj) cannot exist without object of B. Object of B gets created only along with object of A. Also obj1 does not continue to exist, after object of A gets destroyed.

class A{
B obj;
//… other data members and methods, of class A
}

Aggregation

Aggregation is also a has-a relationship. Also sometimes referred as separable part to whole.
Aggregation is a weaker relationship compared to Composition.
As shown in below code snippet, object of D(i..e obj1) can exist even before object of C gets created. Also obj1 may continue to exist even after object of C is destroyed.

class C{
D obj1;
//… other data members and methods, of class C
}
Composition is Strong Has-A relationship Aggregation is a Weak Has-A relationship.

To understand difference between Composition and Aggregation, lets us take an example of a College with few Departments, and each Department with Lecturers.

aggregation and composition
aggregation and composition

Relationship between College and Department is Composition, and relationship between Department and Lecturer is Aggregation.

class College
{
  private List depts;

  public College()
  {
    depts.add(new Department("Computer Dept"));
    depts.add(new Department("Electrical Dept"));
    depts.add(new Department("Electronics Dept"));
  }

  //...other methods in College class
}

A Department cannot exist without College, hence difference between them is Strong and hence Composition.
When College no more exist, Department cannot exist.

Relationship between Department and Lecturer can be Aggregation, as it is weaker. A Lecturer can exist, even before Department exist. And Lecturer may continue to exist even after Department gets destroyed.

class Department
{
  private Lecturer my_obj;

  public void setLecturer(Lecturer lect)
  {
    my_obj = lect;
  }
  //...other methods in Department class
}

Hierarchical Inheritance

In Hierarchical Inheritance, there is common Base class for more than one derived class. Below is an Example of Hierarchical Inheritance

class A8
{
	public A8(int i)
	{
		System.out.println("A8() constructor:"+i);
	}

	public void show()
	{
		System.out.println("show() in A8");
	}
}

class B8 extends A8
{
	public B8()
	{
		super(0);
		System.out.println("B8() constructor");
	}

	public void met1()
	{
		System.out.println("met1() in B8");
	}
}

class C8 extends A8
{
	public C8()
	{
		super(20);
		System.out.println("C8() constructor");
	}

	public void met2()
	{
		System.out.println("met2() in C8");
	}
}

public class HierarchicalInheritance {
public static void main(String args[])
{
	B8 obj = new B8();
	System.out.println();
	C8 obj1 = new C8();

	obj.show();
	obj.met1();

	obj1.show();
	obj1.met2();
}
}


Output:
A8() constructor:0
B8() constructor

A8() constructor:20
C8() constructor
show() in A8
met1() in B8
show() in A8
met2() in C8

You may also like to read:
Java Multilevel Inheritance
What is final class

Inheriting from Generic Class

Below is an example showing how to inherit from a Generic class

class Wrapper1<T> {

  private T m;

 public Wrapper1()
 {
	 System.out.println("Wrapper1() Constructor");
 }

  public void add(T m) {
    this.m = m;
  }

  public T get() {
	  System.out.println("in get()");
    return m;
  }
}


class Sample extends Wrapper1<Float>
{
	public Sample()
	{
		System.out.println("Sample() Constructor");
	}

	public void met1()
	{
		System.out.println("met1() in Sample");
	}
}

class Example<K, L> extends Wrapper<L>
{
	private K n;

	public void add1(K p,L q)
	{
		add(q);
		n = p;
		System.out.println("add1()");
	}

	public void get1()
	{
		L h = get();

		System.out.println(n);
		System.out.println(h);
	}
}

public class GenericInherit
{
  public static void main(String[] args) {
     Wrapper1<Integer> integerBox = new Wrapper1<Integer>();
     Sample obj = new Sample();
     Example<Integer, String> objEx = new Example<Integer, String>();

     obj.met1();

     objEx.add1(new Integer(10), new String("Hello World"));
    objEx.get1();
  }
}

Java Multilevel inheritance

Multi level inheritance is a Derived class is Base class of another class. In below example class B is derived from A, and B is further base class of C.

One of the point to ponder in Multilevel inheritance is, what is the order in which constructors are invoked. First Base most constructor gets invoked, and then its Derived constructor, and so on. In below example, when an object of C is created, first constructor of class A gets invoked, then constructor of class B, finally class C constructor is invoked.

To understand this keyword, please refer Usage of this keyword

class A{
	int i;
	public A(int i)
	{
		this.i = i;
		System.out.println("A(int i)");
	}

	public void show()
	{
		System.out.println("Value of i is:"+i);
	}
}

class B extends A{
	int j;
	public B(int i,int j)
	{
		super(i);
		this.j = j;
		System.out.println("B(int i,int j)");
	}
	public void show()
	{
		super.show();
		System.out.println("Value of j is:"+j);
	}
}

class C extends B{
	int k;
	public C(int i,int j,int k)
	{
		super(i,j);
		this.k = k;
		System.out.println("C(int i,int j,int k)");
	}

	public void show()
	{
		super.show();
		System.out.println("Value of k is:"+k);
	}
}

public class MultiLevelInheritance {

	public static void main(String[] args) {
		C obj = new C(10,20,30);
		obj.show();
	}

}

You may also like to read: Hierarchical Inheritance