Showing posts with label super class. Show all posts
Showing posts with label super class. Show all posts

Tuesday, 21 April 2020

Javassist: Add super class to a class

Step 1: Get the instance of ClassPool.
ClassPool pool = ClassPool.getDefault();

ClassPool is the root class that controls the byte code modifications. It is a container of CtClass objects (CtClass object represent a class file).

Step 2: Read class file from the source.
CtClass cc = pool.get("com.sample.app.model.Employee");

‘pool.get()’ method reads a class file from the source and returns a reference to the CtClass object representing that class file.  If that class file has been already read, this method returns a reference to the CtClass created when that class file was read at the first time.

‘pool.get’ method searches the default system search path to find the class.

Step 3: Set super class to this class.
cc.setSuperclass(pool.get("com.sample.app.model.BaseEntity"));

Step 4: Write the class file to a directory.
cc.writeFile("/Users/Shared/assistDemos");

Find the below working application.

BaseEntity.java
package com.sample.app.model;

public class BaseEntity {
 private String createdBy;
 private String updatedBy;

 public String getCreatedBy() {
  return createdBy;
 }

 public void setCreatedBy(String createdBy) {
  this.createdBy = createdBy;
 }

 public String getUpdatedBy() {
  return updatedBy;
 }

 public void setUpdatedBy(String updatedBy) {
  this.updatedBy = updatedBy;
 }

}

Employee.java
package com.sample.app.model;

public class Employee {
 private int id;
 private String name;

 public int getId() {
  return id;
 }

 public void setId(int id) {
  this.id = id;
 }

 public String getName() {
  return name;
 }

 public void setName(String name) {
  this.name = name;
 }

}

App.java
package com.sample.app;

import java.io.IOException;

import javassist.CannotCompileException;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.NotFoundException;

public class App {
 public static void main(String args[]) throws NotFoundException, CannotCompileException, IOException {
  ClassPool pool = ClassPool.getDefault();
  
  CtClass cc = pool.get("com.sample.app.model.Employee");
  cc.setSuperclass(pool.get("com.sample.app.model.BaseEntity"));
  
  cc.writeFile("/Users/Shared/assistDemos");
  
 }
}

Run App.java.

Open the generated .class file in java decompiler, you can confirm that the class Employee extends BaseEntity.



Previous                                                    Next                                                    Home

Monday, 22 January 2018

Kotlin: Access super class of outer class from inner class

By using the super keyword qualified with outer class name, we can access the super class of the outer class. Let’s me explain with an example.

Ex

Find below working application.

HelloWorld.kt
open class GrandParentClass {
 fun grandParentFunction() {
  println("I am in grand parent class")
 }
}

open class ParentClass : GrandParentClass() {
 fun parentClass() {
  println("I am in parent class")
 }

 inner class ChildInnerClass {
  fun printInfo() {
   parentClass()
   super@ParentClass.grandParentFunction()
  }
 }
}

fun main(args: Array<String>) {
 var innerObj = ParentClass().ChildInnerClass()

 innerObj.printInfo()
}

Output
I am in parent class
I am in grand parent class



Previous                                                 Next                                                 Home

Saturday, 6 January 2018

Kotlin: Overriding methods

By using ‘override’ keyword, you can override the methods of base class. By default all the methods in a class are final (not overridable), you can make them overridable by using ‘open’ keyword’.

Override.kt
open class BaseClass{
 open fun sayHello(){
  println("******Hello World******")
 }
}

class DerivedClass : BaseClass(){
 override fun sayHello(){
  println("@@@@Hello World@@@@@")
 }
}
fun main(args: Array<String>) {
 var obj = DerivedClass()
 
 obj.sayHello()
 
}


Output
@@@@Hello World@@@@@


As you observe above snippet, DerivedClass inhrites from BaseClass. sayHello() method of DerivedClass override the sayHello() method of BaseClass using override keyword.

A method defined with the keyword ‘override’ is itself open, so the child classes of the DerivedClass, can override this method.


Override.kt
open class BaseClass {
 open fun sayHello() {
  println("******Hello World******")
 }
}

open class DerivedClass : BaseClass() {
 override fun sayHello() {
  println("@@@@Hello World@@@@@")
 }
}

class ChildDerivedClass : DerivedClass() {
 override fun sayHello() {
  println("####Hello World####")
 }
}

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

 obj.sayHello()

}

Output
####Hello World####

If you want to prohibit the re-overriding, use the keyword final.

Ex
open class DerivedClass : BaseClass() {
         final override fun sayHello() {
                 println("@@@@Hello World@@@@@")
         }
}


Override.kt
open class BaseClass {
 open fun sayHello() {
  println("******Hello World******")
 }
}

open class DerivedClass : BaseClass() {
 final override fun sayHello() {
  println("@@@@Hello World@@@@@")
 }
}

class ChildDerivedClass : DerivedClass() {
 override fun sayHello() {
  println("####Hello World####")
 }
}

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

 obj.sayHello()

}

When you try to compile above program, kotlin compiler throws below error.

'sayHello' in 'DerivedClass' is final and cannot be overridden





Previous                                                 Next                                                 Home

Thursday, 4 January 2018

Kotlin: Inheritance

Inheritance is the concept of re usability. Object of one class can get the properties and methods of object of another class by using inheritance.

By using inheritance, you can create new class by extending the existing class. The new class is called derived class and the existing class is called base class.



Example
open class BaseClass{

}

class DerivedClass : BaseClass{

}


By default, all the classes in kotlin are final. To make these class inheritable, you should use the keyword ‘open’.


Let’s see inheritance feature by an example. In every organization, there are two kinds of employees.
a.   Permanent Employees
b.   Contract Employees

Both the permanent and contract employees share properties like firstName, lastName and id. Where as contract employees has separate payroll company. We can place these common properties (firstName, lastName and id) in separate class Employee and make the classes PermanentEmployee and ContractEmployee inherit these properties from the common base class Employee.

open class Employee {

}

class PermanentEmployee : Employee {

}

class ContractEmployee : Employee {

}

Find the below working application.


Inheritance.kt
open class Employee {
 var firstName: String = ""
 var lastName: String = ""
 var id: String = ""

 constructor(firstName: String, lastName: String, id: String) {
  this.firstName = firstName
  this.lastName = lastName
  this.id = id
 }

 open fun getEmployee(): String {
  return "firstName : $firstName, lastName: $lastName, id: $id"
 }

}

class PermanentEmployee : Employee {
 var healthInsuranceNumber = ""
 var salary: Double = 0.0

 constructor(firstName: String, lastName: String, id: String, healtInsuranceNumber: String, salary: Double) : super(firstName, lastName, id) {
  this.healthInsuranceNumber = healtInsuranceNumber
  this.salary = salary
 }

 override fun getEmployee(): String {
  return super.getEmployee() + ", healthInsuranceNumber: $healthInsuranceNumber, salary: $salary"
 }

}

class ContractEmployee : Employee {
 var payRollCompany = "ABC"

 constructor(firstName: String, lastName: String, id: String, payRollCompany: String) : super(firstName, lastName, id) {
  this.payRollCompany = payRollCompany
 }

 override fun getEmployee(): String {
  return super.getEmployee() + ", payRollCompany: $payRollCompany"
 }
}


fun main(args: Array<String>) {
 var emp = PermanentEmployee("krishna", "Gurram", "123", "health3425", 56789.01)

 println(emp.getEmployee())
}


Output
firstName : krishna, lastName: Gurram, id: 123, healthInsuranceNumber: health3425, salary: 56789.01

constructor(firstName: String, lastName: String, id: String, healtInsuranceNumber: String, salary: Double) : super(firstName, lastName, id)
If super class don’t have default constructor, then all the sub class constructors must call the super class constructor explicitly.

By default, all the functions and classes are not inheritable (final), to make them inheritable, you should use the keyword ‘open’.

open class Employee {

         open fun getEmployee(): String {
                 return "firstName : $firstName, lastName: $lastName, id: $id"
         }

}

To override a function of super class, you should use override keyword.

class PermanentEmployee : Employee {

         override fun getEmployee(): String {
                 return super.getEmployee() + ", healthInsuranceNumber: $healthInsuranceNumber, salary: $salary"
         }

}

Important Points
a.   If the class has a primary constructor, the base type can (and must) be initialized right there, using the parameters of the primary constructor.


b.   If the class has no primary constructor, then each secondary constructor has to initialize the base type using the super keyword, or to delegate to another constructor which does that. Note that in this case different secondary constructors can call different constructors of the base type:


Previous                                                 Next                                                 Home

Thursday, 20 February 2014

super keyword

Super keyword is used to
1. call super class methods
2. call super class variables
3. call super class constructor

Usage of super keyword are valid only in an instance method, instance initializer, or constructor. If they appear anywhere else, a compile-time error occurs.

1. Call super class methods
      Syntax
      super.methodName(parameters)

Overridden method of the super class is called by using super keyword.
class SuperClass{
 void print(){
  System.out.println("I am super class method");
 }
} 

class SubClass extends SuperClass{

 void print(){
  System.out.println("I am sub class method");
  super.print();
 }

 public static void main(String args[]){
  SuperClass obj1 = new SubClass()
  obj1.print();
 }

}
 
Output
I am sub class method
I am super class method

2. Call super class variables
     Syntax
     super.variableName

class SuperClass{
 String s = "I am super class variable";
 
 void print(){
  System.out.println("I am super class method");
 }
}
   
class SubClass extends SuperClass{
 String s = "I am sub class variable";

 void print(){
  System.out.println(super.s);
  System.out.println(s);
 }

 public static void main(String args[]){
  SuperClass obj1 = new SubClass();
  obj1.print();
 }
}


Output
I am super class variable
I am sub class variable

3. Call super class constructor
     Syntax
     super();
       (OR)
     super(parameter list);

super() is used to call the default constructor of super class.
super(parameter list) is used to call the parametrized constructor of super class.
class SuperClass{
 SuperClass(String s){
  System.out.println("Super Class: " + s);
 }
}
  
class SubClass extends SuperClass{

 SubClass(String s){
  super(s);
  System.out.println("Sub Class: " + s);
 }

 public static void main(String args[]){
  SuperClass obj1 = new SubClass("abcde");
 }

}

Output
Super Class: abcde
Sub Class: abcde

Some Points to Remember
1. Super can't be used in static context, whether it is inside static method or block.
class SuperClass{
 static String s = "Super Class";
}

class SubClass extends SuperClass{
 static String s = "Sub Class";

 public static void main(String args[]){
  System.out.println(super.s);
 }
} 
   
When you tries to compile the above program compiler throws the below error

SubClass.java:5: error: non-static variable super cannot be referenced from a static context
System.out.println(super.s);
^
1 error

2. What is wrong with the below code ?
class SuperClass{
 static String s = "Super Class";

 SuperClass(String s){
 }
}

class SubClass extends SuperClass{
 static String s = "Sub Class";

 SubClass(){
 }

 public static void main(String args[]){
  SubClass s1 = new SubClass();
 }
}

If a constructor does not explicitly invoke a super class constructor, the Java compiler automatically inserts a call to the no-argument constructor of the super class. If the super class does not have a no-argument constructor, compiler provides one default constructor only if the super class doesn't have no constructors like parametrized, Otherwise you will get a compile-time error.

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

SubClass.java:4: error: constructor SuperClass in class SuperClass cannot be applied to given types;

SubClass(){
^
required: String
found: no arguments
reason: actual and formal argument lists differ in length
1 error

To make program, run you have 2 options.

Option 1
Provide a default constructor for super class
class SuperClass{
 static String s = "Super Class";

 SuperClass(String s){

 }

 SuperClass(){

 }
} 
  
Option 2
Explicitly call the super class parameterized constructor.
class SubClass extends SuperClass{
 static String s = "Sub Class";

 SubClass(){
  super(s);
 }

 public static void main(String args[]){
  SubClass s1 = new SubClass();
 }
} 

3. Call to super must be first statement in constructor
  

4.Calling super class constructors in any methods other than constructors, cause compiler error.
  


Fields hiding                                                 final keyword                                                 Home

Hiding methods

If a subclass defines a class method (static method) with the same signature as a class method in the super class, the method in the subclass hides the one in the super class.

Distinction between Hiding and Overriding
class Animal{
 static void printMsg(){
  System.out.println("I am the super class static method");
 }

 void showMsg(){
  System.out.println("I am the super class instance method");
 }
}

class Tiger extends Animal{
 static void printMsg(){
  System.out.println("I am the sub class static method");
 }

 void showMsg(){
  System.out.println("I am the sub class instance method");
 }

 public static void main(String args[]){
  Animal ref = new Tiger();
  ref.printMsg();
  ref.showMsg();
 }
}

Output
I am the super class static method
I am the sub class instance method

As you observe the output, run time polymorphism not happened for the static method. So the message “I am the super class static method” printed.

The showMsg() method of class Tiger overrides the showMsg() of super class. Where as, the printMsg() of subclass hides the printMsg() of super class.

Remember,A sub class static method always hides the super class static method. Where as sub class instance method overrides the super class instance method.

Some points to remember
1. Can a sub class instance method hides the super class static method?
     No, Compiler error thrown.

Example
class Animal{
 static void printMsg(){
  System.out.println("I am the super class static method");
 }
}
      
class Tiger extends Animal{
 void printMsg(){
  System.out.println("I am the sub class static method");
 }
}
When you try to compile the class Tiger, compiler throws the below error. You will get a compile-time error if you attempt to change an instance method in the superclass to a class method in the subclass, and vice versa.

Tiger.java:2: error: printMsg() in Tiger cannot override printMsg() in Animal
void printMsg(){
^
overridden method is static
1 error

2. What is wrong with the below program ?
class Animal{
 public static void printMsg(){
  System.out.println("I am the super class static method");
 }
}

class Tiger extends Animal{
 static void printMsg(){
  System.out.println("I am the sub class static method");
 } 
} 

The access specifier for an hiding method can allow more, but not less, access than the hidden method. For example, a public static method in the superclass can be made public, but not private, protected and default.

When you tries to compile the class Tiger, compiler throws the below error.

Tiger.java:2: error: printMsg() in Tiger cannot override printMsg() in Animal
static void printMsg(){
^
attempting to assign weaker access privileges; was public
1 error

3. What is wrong with the below program ?     
class Animal{
 static void printMsg(){
  System.out.println("I am the super class static method");
 }
}

class Tiger extends Animal{
 static void printMsg()throws Exception{
  System.out.println("I am the sub class static method");
 }
} 

The hiding method cannot throw any exceptions that are not thrown by the overridden method.

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

Tiger.java:2: error: printMsg() in Tiger cannot override printMsg() in Animal
static void printMsg()throws Exception{
^
overridden method does not throw Exception
1 error

4. Can I specify weaker access specifier to the overriding method in the sub class ?
No



Covariant Return types                                                 Polymorphism Usage                                                 Home