Showing posts with label Anonymous classes. Show all posts
Showing posts with label Anonymous classes. Show all posts

Thursday, 18 January 2018

Kotlin: Object Expressions

If you want to create an object that is slight modification to the existing class, you can use anonymous class.

By using Object expressions, you can create anonymous class.

For example,
open class PrintUtil {
         public open fun welcomeMessage(name: String) {
                 println("Hello $name")
         }
}

Now we can define anonymous class like below.

         /* Define object using anonymous class */
         var anonymousObj: PrintUtil = object : PrintUtil() {

                 override fun welcomeMessage(name: String) {
                          println("Welcome $name")
                 }
         }

As you observe above snippet, I defined the object 'anonymousObj' using object expression. Object expressions are defined using the keyword 'object'.

HelloWorld.kt
open class PrintUtil {
 public open fun welcomeMessage(name: String) {
  println("Hello $name")
 }
}

fun main(args: Array<String>) {
 var obj = PrintUtil()

 obj.welcomeMessage("Krishna")

 /* Define object using anonymous class */
 var anonymousObj: PrintUtil = object : PrintUtil() {

  override fun welcomeMessage(name: String) {
   println("Welcome $name")
  }
 }

 anonymousObj.welcomeMessage("Krishna")
}

Output

Hello Krishna
Welcome Krishna

You can also pass parameterized constructor while defining anonymous class

open class PrintUtil(var greeting : String) {
         public open fun welcomeMessage(name: String) {
                 println("Hello $name")
         }
}

We can define anonymous class like below.

         /* Define object using anonymous class */
         var anonymousObj: PrintUtil = object : PrintUtil("Good Morning") {

                 override fun welcomeMessage(name: String) {
                          println("Welcome $name")
                 }
         }

Find the below working application.


HelloWorld.kt

open class PrintUtil(var greeting: String) {
 public open fun welcomeMessage(name: String) {
  println("Hello $name")
 }
}

fun main(args: Array<String>) {
 var obj = PrintUtil("Good Morning")

 obj.welcomeMessage("Krishna")

 /* Define object using anonymous class */
 var anonymousObj: PrintUtil = object : PrintUtil("Good Morning") {

  override fun welcomeMessage(name: String) {
   println("Welcome $name")
  }
 }

 anonymousObj.welcomeMessage("Krishna")
}

Can I define an anonymous object without any super type?
Yes, you can define anonymous object, without any super type.

Ex
         val newAnonymousObj = object {
                 var x: Int = 1
                 var y: Int = 2
                 var z: Int = 3

                 fun welcomeUser(name: String) {
                          println("Hello $name")
                 }
         }

Find below working application.


HelloWorld.kt
fun main(args: Array<String>) {
 val newAnonymousObj = object {
  var x: Int = 1
  var y: Int = 2
  var z: Int = 3

  fun welcomeUser(name: String) {
   println("Hello $name")
  }
 }

 newAnonymousObj.welcomeUser("Krishna")

 println("Value of x is : ${newAnonymousObj.x}")
 println("Value of y is : ${newAnonymousObj.y}")
 println("Value of z is : ${newAnonymousObj.z}")
}


Output
Hello Krishna
Value of x is : 1
Value of y is : 2
Value of z is : 3

Can an object expression access the code of enclosing block?
Yes, an object expression can access the code of enclosing block.


HelloWorld.kt

fun main(args: Array<String>) {
 var message = "Hello, Good Morning"
 
 val newAnonymousObj = object {

  fun welcomeUser(name: String) {
   println("$message $name")
  }
 }

 newAnonymousObj.welcomeUser("Krishna")

}

Output

Hello, Good Morning Krishna



Previous                                                 Next                                                 Home

Tuesday, 18 February 2014

Class inside an Interface

A class can be defined in an interface, By default the class defined in interface is public and static. Just like accessing the static final variables in the interface, we can access the class defined in the interface.

Example
interface InterfaceEx{
 double PI=3.142;
 
 class Employee{
  String firstName;
  String lastName;
 }

 String getEmployee();
 void setEmployee(Employee e);
}

class InterfaceExTest implements InterfaceEx{
 Employee emp;
 
 public String getEmployee(){
  return emp.firstName +"\t" + emp.lastName;
 }

 public void setEmployee(Employee emp){
  this.emp = emp;
 }

 public static void main(String args[]){
  Employee e1 = new Employee();
  e1.firstName = "abc";
  e1.lastName = "def";
  
  InterfaceExTest obj1 = new InterfaceExTest();
  obj1.setEmployee(e1);
  System.out.println(obj1.getEmployee());
 }
}
  
Output
abc def

Some points to Remember
1. A class defined in interface can implement the same interface.
interface InterfaceEx{

 class ClassInside implements InterfaceEx{
  public void print1(){
   System.out.println(" I am print1");
  }
 }
 
 void print1();
}

class InterfaceExTest{
 public static void main(String args[]){
  InterfaceEx.ClassInside e1 = new InterfaceEx.ClassInside();
  e1.print1();
 }
}

Output
I am print1

2. The class defined in an interface is public and static by default.

3. Can an abstract class defined in interface ?
Yes      
interface InterfaceEx{

 abstract class ClassInside implements InterfaceEx{
  public void print1(){
   System.out.println(" I am print1");
  }
 }
 
 void print1();
 void print2();
}

class InterfaceExTest{

 public static void main(String args[]){
  InterfaceEx.ClassInside e1 = new InterfaceEx.ClassInside(){
   public void print2(){
    System.out.println("I am in print2");
   }
  };
  
  e1.print1();
  e1.print2();
 }
}

Output
I am print1
I am in print2

4. Can I override the methods defined in the class, by the same class object ?
Yes, It is possible by using Anonymous classes.
Example
interface InterfaceEx{
 class ClassInside implements InterfaceEx{
  public void print1(){
   System.out.println(" I am print1");
  } 
  public void print2(){
   System.out.println(" I am print2");
  }
 }
 
 void print1();
 void print2();
}

class InterfaceExTest{
 public static void main(String args[]){
  InterfaceEx.ClassInside e1;
  e1 = new InterfaceEx.ClassInside(){
     public void print2(){
      System.out.println("Overriding print2");
     }
     
     public void print1(){
      System.out.println("Overriding print1");
     }
    };
    
  e1.print1();
  e1.print2();
 }
}
 
Output
Overriding print1
Overriding print2

As you see, the methods defined by the class “ClassInside” are overridden using Anonymous class.
.

Extend interface                                                 Interface in interface                                                 Home

Wednesday, 12 February 2014

Anonymous Classes

Anonymous classes are just like local classes, except these don't have name.

Syntax of Anonymous Classes
The syntax of an anonymous class expression is like the invocation of a constructor, except there is a class definition contained in a block of code.

Example   
Uniform zpschool = new Uniform(){
 String color;
 void setColor(String color){
  this.color = color;
 }

 String getColor(){
  return color;
 }
}; 


The anonymous class expression consists of the following:
       The new operator
     The name of an interface to implement or a class to extend.
     Parentheses that contain the arguments to a constructor

Creating Anonymous Classes using Abstract class
class AnonymousEx{
 abstract class Uniform{
  abstract void setColor(String color);
  abstract String getColor();
 }

 Uniform zpschool = new Uniform(){
  String color;
  
  void setColor(String color){
   this.color = color;
  }
  
  String getColor(){
   return color;
  }
 };

 public static void main(String args[]){
  AnonymousEx obj = new AnonymousEx();
  obj.zpschool.setColor("Blue");
  System.out.println(obj.zpschool.getColor());
 }
}

Output
Blue
 

Creating Anonymous class using Interface
class AnonymousEx{
 interface Uniform{
  void setColor(String color);
  String getColor();
 }

 Uniform zpschool = new Uniform(){
  String color;
  
  public void setColor(String color){
   this.color = color;
  }

  public String getColor(){
   return color;
  }
 };

 public static void main(String args[]){
  AnonymousEx obj = new AnonymousEx();
  obj.zpschool.setColor("Blue");
  System.out.println(obj.zpschool.getColor());
 }
}

Output
Blue
1. Can I declare an interface inside Class ?
Yes

2. Can I declare abstract class inside class ?
Yes

3. Can I create an object for an Interface ?
Yes, Using Anonymous classes

4. Can I create an object for abstract class ?
Yes, Using Anonymous classes

5. An anonymous class cannot access local variables in its enclosing scope that are not declared as final
class AnonymousEx{
 String name="HI";

 interface Uniform{
  void setColor(String color);
   String getColor();
 }

 public void print(){
  int val = 10;
   
  class myClass implements Uniform{
   String color;

   public void setColor(String s){
    color = s;
   }

   public String getColor(){
    System.out.println(val);
    return color;
   }
  }
 }
}

When you try to compile compiler throws the below error
        
AnonymousEx.java:18: error: local variable val is accessed from within inner class; needs to be          declared final
System.out.println(val);
^
1 error

To make the program compiles fine, define the local variable as final
     final int val = 10;
  
6. You cannot declare static initializers or member interfaces in an anonymous class.
class AnonymousEx{
 String name="HI";
 
 interface Uniform{
  void setColor(String color);
  String getColor();
 }

 public void print(){
  class myClass implements Uniform{
   static String color;
   public void setColor(String s){
    color = s;
   }

   public String getColor(){
    return color;
   }
  }
 }
}


When you tries to compile the above program, compiler throws the below error

AnonymousEx.java:12: error: Illegal static declaration in inner class myClass
static String color;
^
modifier 'static' is only allowed in constant variable declarations
1 error

7. An anonymous class can have static members provided that they are constant variables

8. Can I declare extra methods in Anonymous classes ?
Yes. It is valid

Example
class AnonymousEx{
 interface Uniform{
  void setColor(String color);
  String getColor();
 }

 Uniform zpschool = new Uniform(){
  String color;

  public void setColor(String color){
   this.color = color;
  }

  public String getColor(){
   return color;
  } 

  void print(){
   System.out.println("I am Extra method");
  }
 };
}
 
As you see in the above program, interface Uniform has 2 abstract methods, setColor, getColor.But the Anonymous class has extra method print().


9. Is below program compile ?
class AnonymousEx{
 abstract class Uniform{
  void setColor(String color);
  String getColor();
   }
}
No, Compiler throws the below error.
AnonymousEx.java:4: error: missing method body, or declare abstract
void setColor(String color);
^
AnonymousEx.java:5: error: missing method body, or declare abstract
String getColor();
^
2 errors

To solve the above error, make the methods in the abstract class as abstract

class AnonymousEx{
 abstract class Uniform{
  abstract void setColor(String color);
  abstract String getColor();
 }
}
         

Local Classes                                                 Lambda Expressions                                                 Home