Interfaces
interfaceis a keyword which is used to define User Defined Datatypes.- Interface is a special class which is fully abstracted.
- Interface can be used to achieve the multiple inheritance in Java.
- One interface can extend one or more interfaces.
- One class can implement one or more interfaces.
Syntax to declare interface
<modifiers>interface<InterfaceName>
{
// Members
}
Interface can contain following members:
- public final static variables
- public abstract methods
- public static inner classes
- Variables declared in the interface are by default
public final static. So it is unnecessary to use these modifiers for variables. - Methods declared in the interface are by default
public abstract. So it is unnecessary to use these modifiers for methods.
Lab540.java
interfaceInter1{
voidm1();
publicabstractvoidm2();
intA=10;
publicfinalintB=20;
}
classHelloextendsInter1{ }
classLab540{
publicstaticvoidmain(Stringargs[]){
System.out.println("Hello Guys!");
}
}
Lab541.java
interfaceInter1{
voidm1();
publicabstractvoidm2();
intA=10;
publicfinalintB=20;
}
classHelloimplementsInter1{ }
classLab541{
publicstaticvoidmain(Stringargs[]){
System.out.println("Hello Guys!");
}
}
Lab542.java
interfaceInter1{
voidm1();
publicabstractvoidm2();
intA=10;
publicfinalintB=20;
}
abstractclassHelloimplementsInter1{ }
classLab542{
publicstaticvoidmain(Stringargs[]){
System.out.println("Hello Guys!");
}
}
Lab543.java
interfaceInter1{
voidm1();
publicabstractvoidm2();
intA=10;
publicfinalintB=20;
}
classHelloimplementsInter1{
voidm1(){
System.out.println("Hello -> m1()");
}
publicvoidm2(){
System.out.println("Hello -> m2()");
}
}
classLab543{
publicstaticvoidmain(Stringargs[]){
System.out.println("Hello Guys!");
}
}
Lab544.java
interfaceInter1{
voidm1();
publicabstractvoidm2();
intA=10;
publicfinalintB=20;
}
classHelloimplementsInter1{
publicvoidm1(){
System.out.println("Hello -> m1() :"+A);
}
publicvoidm2(){
System.out.println("Hello -> m2() :"+B);
}
}
classLab544{
publicstaticvoidmain(Stringargs[]){
Inter1ref=null;
// ref = new Inter1();
ref=newHello();
ref.m1();
ref.m2();
}
}
Lab545.java
interfaceInter1{
voidm1();
publicabstractvoidm2();
intA=10;
publicfinalintB=20;
}
abstractclassHelloimplementsInter1{
publicvoidm1(){
System.out.println("Hello -> m1() :"+A);
}
}
classHaiextendsHello{
publicvoidm2(){
System.out.println("Hai -> m2() :"+B);
}
voidm3(){
System.out.println("Hai -> m3()");
}
}
classLab545{
publicstaticvoidmain(Stringargs[]){
Inter1ref=newHai();
ref.m1();
ref.m2();
// ref.m3();
}
}
Lab546.java
interfaceInter1{
voidm1();
intA=10;
}
interfaceInter2{
voidm2();
intB=11;
}
classHelloimplementsInter1,Inter2{
publicvoidm1(){
System.out.println("Hello -> m1()");
}
publicvoidm2(){
System.out.println("Hello -> m2()");
}
}
classLab546{
publicstaticvoidmain(Stringargs[]){
Helloh=newHello();
System.out.println(h.A);
System.out.println(h.B);
h.m1();
h.m2();
}
}
Inter1.java
interfaceInter1{
voidm1();
voidm2();
intA=10;
intB=20;
}
Inter2.java
interfaceInter2{
voidm2();
voidm3();
intA=11;
intC=30;
}
Lab547.java
classHelloimplementsInter1,Inter2{
publicvoidm1(){
System.out.println("Hello -> m1()");
}
publicvoidm2(){
System.out.println("Hello -> m2()");
}
publicvoidm3(){
System.out.println("Hello -> m3()");
System.out.println(B);
System.out.println(C);
}
}
classLab547{
publicstaticvoidmain(Stringargs[]){
Helloh=newHello();
h.m1();
h.m2();
h.m3();
}
}
Lab548.java
classHelloimplementsInter1,Inter2{
publicvoidm1(){
System.out.println("Hello -> m1()");
}
publicvoidm2(){
System.out.println("Hello -> m2()");
}
publicvoidm3(){
System.out.println("Hello -> m3()");
System.out.println(A);
System.out.println(B);
System.out.println(C);
}
}
classLab548{
publicstaticvoidmain(Stringargs[]){
Helloh=newHello();
h.m1();
h.m2();
h.m3();
}
}
Lab549.java
classHelloimplementsInter1,Inter2{
publicvoidm1(){
System.out.println("Hello -> m1()");
}
publicvoidm2(){
System.out.println("Hello -> m2()");
}
publicvoidm3(){
System.out.println("Hello -> m3()");
System.out.println(Inter1.A);
System.out.println(Inter2.A);
System.out.println(B);
System.out.println(C);
}
}
classLab549{
publicstaticvoidmain(Stringargs[]){
Helloh=newHello();
h.m1();
h.m2();
h.m3();
}
}
Lab550.java
classHelloimplementsInter1,Inter2{
// Same as Lab549
}
classLab550{
publicstaticvoidmain(Stringargs[]){
Helloh=newHello();
Inter1ref1=h;
ref1.m1();
ref1.m2();
Inter2ref2=h;
ref2.m2();
ref2.m3();
}
}
Lab551.java
interfaceInter1{
voidshow();
}
classA{
publicvoidshow(){
System.out.println("A -> show()");
}
}
classBextendsAimplementsInter1{ }
classLab551{
publicstaticvoidmain(String[]args){
Bref=newB();
b.show();
}
}
Inter1.java
interfaceInter1{
intAB=90;
}
classHaiimplementsInter1{
voidshow(){
System.out.println(super.AB);
}
}
Inter1.java
interfaceInter1{
intAB=90;
}
classHello{
StringAB="JavaWorld";
}
classHaiextendsHelloimplementsInter1{
voidshow(){
System.out.println(super.AB);
System.out.println(Inter1.AB);
}
}
Limitation of Multiple Inheritance
Lab552.java
interfaceInter1{
voidshow();
}
interfaceInter2{
intshow();
}
classAimplementsInter1{
publicvoidshow(){ }
}
classBimplementsInter2{
publicintshow(){
return0;
}
}
classCimplementsInter1,Inter2{
publicvoidshow(){ }
publicintshow(){
return0;
}
}
Lab553.java
interfaceInter1{
voidshow();
}
classA{
publicstaticvoidshow(){
System.out.println("show method");
}
}
classBextendsAimplementsInter1{
publicvoidshow(){ }
}
Notes
- Always
superkeyword is used only in classes. It is avoided in interface. - One static method cannot be overridden as instance method.
Problem with Multiple Inheritance using Classes
Diagram Explanation
A
void show()
int x = 11;
/ \
/ \
B C
B: C:
void show(){} void show(){}
int x = 90; int x = 80;
\ /
\ /
D
Inside class D
voidshow(){
super.show();
super.x=88;
}
D(){
super();
}
➡ This causes Ambiguity Error
Because D does not know whether super refers to class B or class C.
Important Points
- When a class extends multiple classes, some members may be common in super classes.
- When you refer those common members from the subclass, it results in an ambiguity problem.
- When you create a subclass object, first superclass constructor should be invoked.
- If multiple superclasses are present, then it becomes confusing which superclass constructor should be invoked first.
Multiple Inheritance using Interfaces
Diagram
I1
void show();
int x = 11;
/ \
/ \
I2 I3
void show(); void show();
int x = 90; int x = 80;
\ /
\ /
A
Class A
voidshow(){
super.show();
I1.x
I2.x
I3.x
}
A(){
super();
}
Important Notes
1. super can't be used for interfaces
- Interface methods do not have implementation.
- So
super.show()is not possible in interfaces.
2. Accessing variables in interfaces
Because interface variables are static, we can access them using the interface name.
Example:
I1.x
I2.x
I3.x
3. Interfaces don't have constructors
So constructor ambiguity problems will not occur in interfaces.
Calling Interface Members
Calling interface methods
InterfaceName.method();
Accessing interface variables
InterfaceName.variable;
Why Multiple Inheritance works with Interfaces but not Classes
Multiple inheritance using classes causes:
- Ambiguity problem (same methods/variables from multiple superclasses)
- Constructor confusion (which superclass constructor should be called?)
Interfaces avoid these problems because:
- Interface methods normally don't have implementation.
- Variables are static and accessed using interface names.
- Interfaces don't have constructors.
Using Assignment and Type Casting with Reference Type
A.java
classA{ }
classBextendsA{ }
classCextendsA{ }
classDextendsB{ }
classE{ }
Lab554.java
classLab554{
publicstaticvoidmain(Stringargs[]){
Ddobj=newD();
Aaobj=dobj;// Upcasting
Bbobj=aobj;// Error
Ddobj1=aobj;// Error
}
}
Notes
- Upcasting is allowed directly.
- Downcasting requires explicit type casting.
Lab555.java
classLab555{
publicstaticvoidmain(Stringargs[]){
Ddobj=newD();
Aaobj=dobj;
Bbobj= (B)aobj;
Ddobj1= (D)aobj;
System.out.println("Hello Guys");
}
}
Output
Hello Guys
Notes
- Downcasting is possible using explicit casting.
Lab556.java
classLab556{
publicstaticvoidmain(Stringargs[]){
Aaobj=newD();
Ccobj= (C)aobj;
System.out.println("Hello Guys");
}
}
Notes
- Compiles successfully.
- Runtime error occurs (
ClassCastException). - Because
DandCare not related.
Using instanceof with Reference Type
Lab557.java
classLab557{
publicstaticvoidmain(Stringargs[]){
Aaobj=newD();
if(aobjinstanceofC){
Ccobj= (C)aobj;
}
System.out.println("Hello Guys");
}
}
Notes
instanceofprevents invalid casting.
Lab558.java
classLab558{
publicstaticvoidmain(Stringargs[]){
Aaobj=newD();
Eeobj= (E)aobj;
System.out.println("Hello Guys");
}
}
Notes
- Compile-time error.
AandEhave no relationship.
Lab559.java
classLab559{
publicstaticvoidmain(Stringargs[]){
Aaobj=newD();
System.out.println(aobjinstanceofA);
System.out.println(aobjinstanceofB);
System.out.println(aobjinstanceofC);
System.out.println(aobjinstanceofD);
}
}
Output
true
true
false
true
Lab560.java
classLab560{
publicstaticvoidmain(Stringargs[]){
Aaobj=newD();
System.out.println(aobjinstanceofE);
}
}
Notes
- Compile-time error.
AandEare incompatible types.
Using == Operator with Reference Type
To compare, both references should be comparable.
Lab561.java
classLab561{
publicstaticvoidmain(Stringargs[]){
Aaob=newD();
Bbob=newB();
Ddob=newD();
Ccob=newC();
System.out.println(aob==dob);
System.out.println(aob==bob);
System.out.println(aob==cob);
}
}
Output
false
false
false
Notes
- Different objects have different memory addresses.
- Comparison is allowed because the reference types are related/comparable.
Lab562.java
classLab562{
publicstaticvoidmain(Stringargs[]){
Aaob=newD();
Eeob=newE();
System.out.println(aob==eob);
Bbob=newB();
Ccob=newC();
System.out.println(bob==cob);
}
}
Notes
- Compile-time error.
- References are not comparable because classes are unrelated.
Using Array with User Defined Type
Inter1.java
interfaceInter1extendsObject { }
Notes
- Every interface internally extends
Object.
Lab563.java
interfaceInter1{
voidm1();
}
classHelloimplementsInter1{
publicvoidm1(){
System.out.println("Hello -> m1");
}
publicvoidm2(){
System.out.println("Hello -> m2");
}
}
classLab563{
publicstaticvoidmain(Stringargs[]){
Inter1in1=newHello();
in1.m1();
}
}
Notes
m1()can be accessed.m2()cannot be accessed because it is not part of the interface reference type.
Lab564.java
interfaceInter1{
voidm1();
}
classHelloimplementsInter1{
publicvoidm1(){
System.out.println("Hello -> m1");
}
publicvoidm2(){
System.out.println("Hello -> m2");
}
}
classLab564{
publicstaticvoidmain(Stringargs[]){
Inter1in1=newHello();
in1.m2();
}
}
Notes
- Compile-time error.
- Interface reference cannot access methods not declared in the interface.
Lab565.java
interfaceInter1{
voidm1();
}
classHelloimplementsInter1{
publicvoidm1(){
System.out.println("Hello -> m1");
}
publicvoidm2(){
System.out.println("Hello -> m2");
}
}
classLab565{
publicstaticvoidmain(Stringargs[]){
Inter1in1=newHello();
Objectobj=in1;
System.out.println(in1.toString());
}
}
Notes
- Interface references can access methods inherited from
Object. toString()is available because every interface indirectly relates toObject.
Lab566.java
interfaceInter1{ }
classAimplementsInter1{ }
classBextendsA{ }
classCextendsA{ }
classLab566{
publicstaticvoidmain(Stringargs[]){
Inter1arr[]=newInter1[3];
arr[0]=newA();
arr[1]=newB();
arr[2]=newC();
for(Inter1r :arr){
System.out.println(r);
}
}
}
Notes
- Interface array can store objects of implementing classes and subclasses.
Lab567.java
interfaceInter1{ }
classAimplementsInter1{ }
classBextendsA{ }
classCextendsA{ }
classLab567{
publicstaticvoidmain(Stringargs[]){
Inter1arr[]=newA[3];
arr[0]=newA();
arr[1]=newB();
arr[2]=newC();
for(inti=0;i<arr.length;i++){
System.out.println(arr[i]);
}
}
}
Notes
- Array type
A[]can storeA,B, andCobjects becauseBandCextendA.
Lab568.java
interfaceInter1{ }
classAimplementsInter1{ }
classBextendsA{ }
classCextendsA{ }
classLab568{
publicstaticvoidmain(Stringargs[]){
Inter1arr[]=null;
arr=newA[3];
arr[0]=newA();
for(inti=0;i<arr.length;i++){
System.out.println(arr[i]);
}
}
}
Notes
- Interface reference can refer to an array object of implementing class type.
Lab569.java
interfaceInter1{ }
classAimplementsInter1{ }
classBextendsA{ }
classCextendsA{ }
classLab569{
publicstaticvoidmain(Stringargs[]){
Inter1arr[]=null;
arr=newB[3];
arr[0]=newB();
arr[1]=newB();
arr[2]=newB();
for(inti=0;i<arr.length;i++){
System.out.println(arr[i]);
}
}
}
Notes
Inter1reference array can refer to subclass array objects.
Lab570.java
interfaceInter1{ }
classAimplementsInter1{ }
classBextendsA{ }
classCextendsA{ }
classLab570{
publicstaticvoidmain(Stringargs[]){
Inter1arr[]=newB[3];
arr[0]=newB();
arr[1]=newB();
arr[2]=newC();
for(inti=0;i<arr.length;i++){
System.out.println(arr[i]);
}
}
}
Notes
- Runtime error occurs.
- Because array actual type is
B[]. Cobject cannot be stored insideB[].