Inner classes inside Interface - java

Can we have a class inside an interface which has different methods of the interface implemented in it. I have a doubt here that why Java allows writing Inner classes inside interfaces and where can we use it.
In the program below I have written a class inside Interface and implemented the methods of the interface. In the implementation class of the interface I have just called the inner class methods.
public interface StrangeInterface
{
int a=10;int b=5;
void add();
void sub();
class Inner
{
void add()
{
int c=a+b;
System.out.println("After Addition:"+c);
}
void sub()
{
int c=a-b;
System.out.println("After Subtraction:"+c);
}
}
}
abstract public class StrangeInterfaceImpl implements I {
public static void main(String args[])
{
StrangInterface.Inner i=new StrangeInterface.Inner();
i.add();
i.sub();
}
}

You can define a class inside an interface. Inside the interface, the inner class is implicitly public static.
From JLS Section 9.1.4:
The body of an interface may declare members of the interface, that is, fields (§9.3), methods (§9.4), classes (§9.5), and interfaces (§9.5).
From JLS Section 9.5:
Interfaces may contain member type declarations (§8.5).
A member type declaration in an interface is implicitly static and public. It is permitted to redundantly specify either or both of these modifiers.
The only restriction on the inner class defined inside the interface or any other class, for that matter, is that, you have to access them using the enclosing member name.
Apart from that, there is no relation between them. The inner class will result in completely a different class file after compilation.
For e.g., if you compile the following source file:
interface Hello {
class HelloInner {
}
}
Two class files will be generated:
Hello.class
Hello$HelloInner.class

Can we have a class inside an interface which has different methods of the interface implemented in it.
IMHO But interfaces are not meant to for that purpose.
If you write inner class in an interface it is always public and static.
It's equivalent to
public interface StrangeInterface
{
public static class Inner{
}
and the variable inside the interface also explicitly public static variables.

An interface might provide its own implementation as a default.
Note that unless you declare the inner class implements the interface, there's no relation between the two other than it's an inner class. When a class is very tightly related to the interface this isn't intrinsically unreasonable, although I'd be suspicious it's a generally-useful pattern.

to summarize "where can we use it" by defining a class inside an interface:
1. to provide default implementation for an interface
2. if argument or return type for interface method/s is class
w.r.t your code
interface StrangeInterface {
int a = 10;
int b = 5;
void add();
void sub();
class Inner implements StrangeInterface {
public void add() {
int c = a + b;
System.out.println("After Addition:" + c);
}
public void sub() {
int c = a - b;
System.out.println("After Subtraction:" + c);
}
}
}
class MyTest implements StrangeInterface {
public void add() {
System.out.println("My own implementation for add : " + (a +b));
}
public void sub() {
System.out.println("My own implementation for sub : " + (a- b));
}
}
public class StrangeInterfaceImpl {
public static void main(String args[]) {
StrangeInterface.Inner i = new StrangeInterface.Inner(); // calling default implementation
i.add();
i.sub();
MyTest t = new MyTest(); // my own implementation
t.add();
t.sub();
}
}

Related

Ambiguity for Variable but not for Method

We have an interface and class with no relation each having methods with same signature. These can be related to a class which would compile fine.
interface A {
void test();
}
class B {
public void test() {
System.out.println("Test");
}
}
public class MultipleLevelInheritance extends B implements A {
public static void main(String[] args) {
new MultipleLevelInheritance().test();
}
}
But when we do the same with the a variable its causing ambiguity.
interface A {
int a = 10;
}
class B {
public static int a = 9;
}
public class MultipleLevelInheritance extends B implements A {
public static void main(String[] args) {
System.out.println(a); //The field a is ambiguous
}
}
Even if we keep a as final in B, its still causing the error. Why is that valid for methods and invalid for variables?
When you implement an interface, all variables are inherited in the class. So, when you extend a class and implements the interface, it will have two declaration of variable a. Hence you are getting ambiguity error.
But when it comes to methods, when you implement the interface, you are expected to provide the implementation of the methods defined in interface. In your example, this implementation is provided by class B. Therefore there is no error.
Your class MultipleLevelInheritance is implementing an interface and extending a class, and both have the same property name (a),when you call a in MultipleLevelInheritance, Java is not able to determine if the variable refers to A.a or B.a. you just need to prefix it.

creating object with different reference [duplicate]

This question already has answers here:
Why do we assign a parent reference to the child object in Java?
(11 answers)
What does it mean to "program to an interface"?
(33 answers)
Closed 6 years ago.
I am so confused in this topic.
//a class (lets say B) extendes or implements another class or interface respectively
interface myInterfaceA{
int interfaceDataMember1;
int interfaceDataMember2;
void interfaceMethod1();
void interfaceMethod2();
}
class myClassA{
int parentClassDataMember1;
int parentClassDataMember2;
myclassA(){}
void parentClassMethod1(){}
void parentClassMethod2(){}
}
//case1
class B implements myInterfaceA{
int dataMember1;
int dataMember2;
B(){}
void method1(){}
void method2(){}
}
// OR case2
class B extends myClassA{
int dataMember1;
int dataMember2;
B(){}
void method1(){}
void method2(){}
}
// so in either case what is the purpose of creating the object of class B in the following way
myInterfaceA objectB = new B();
// or
myClassA objectB = new B();
1) is there any name of this procedure?
2) what (data memeber, methods, constructor ) will be loaded in objectB?
3) if all the code of class B will be loaded in the objectB then why did we give the refrece of interface or parent class?
4) is this shows polymorphism? if yes, then why?
5) in case2 will class B also inherit the constructor of myClassA
6) why the constructor of parentclass is also called whe we create child class object
1) is there any name of this procedure?
This is polymorphism.
2) what (data memeber, methods, constructor ) will be loaded in
objectB?
Every data member and method will be inherited by the objectB.
In case of interfaces, the data members are private, static, final constants. They must be initialized in the constructor. The methods must be implemented by the class B.
In case of superclasses, the data members and methods are simply inherited. You can override the methods. Variables are not polymorphic.
3) if all the code of class B will be loaded in the objectB then why
did we give the refrece of interface or parent class?
We give reference of interface or parent class so that in case of multiple subtypes, we can have a single method that accepts supertype instead of creating multiple methods. This reduces lines of code and makes the code readable.
4) is this shows polymorphism? if yes, then why?
This shows polymorphic behaviour so you don't need to bind each subtype to a different method. A single method can be written to dynamically bind all the subtypes of a single supertype.
5) in case2 will class B also inherit the constructor of myClassA
The constructor is not inherited. You must call explicitly super() if required.
6) why the constructor of parentclass is also called whe we create
child class object
It is not mandatory to call the constructor of the parentclass everytime. You may skip it if it is not required. But as a standard practice, super() is the first line of the child class constructor, so that any changes in the super class object creation does not affect child class.
Interfaces (and implementing them) only dictate what method signatures the inheriting class must have. The only thing that is 'copied', ie available as methods, are default methods since Java 8
Extending from a class (or abstract class) is a whole different story, although it also can dictate what method signatures are to be implemented by the inheriting class.
But here, all data is not copied, but available, to the calling interface.
Interfaces are used to standardise behaviour (treat dogs and birds as pets), abstract classes to standardise behaviour AND provide implementations (let budgie and cockatoo fly)
package zoo;
import java.util.ArrayList;
interface Pet {
void printName();
}
abstract class Bird implements Pet {
public void fly() {
System.out.println("I (" + getClass().getSimpleName() + ") am flying");
}
}
class Dog implements Pet {
#Override public void printName() {
System.out.println("Hans");
}
}
class Budgie extends Bird {
#Override public void printName() {
System.out.println("Jockl");
}
}
class Cockatoo extends Bird {
#Override public void printName() {
System.out.println("Zenzi");
}
}
public class AnimalSchool {
public static void main(final String[] args) {
final Dog d = new Dog();
d.printName();
final Budgie b = new Budgie();
b.printName();
b.fly();
final Cockatoo c = new Cockatoo();
c.printName();
c.fly();
final ArrayList<Pet> pets = new ArrayList<>();
pets.add(d);
pets.add(b);
pets.add(c);
for (final Pet pet : pets) {
System.out.print("\nPet is a " + pet.getClass().getSimpleName() + " and is called ");
pet.printName();
}
final ArrayList<Bird> byrdies = new ArrayList<>();
// byrdies.add(d); this will not compile, as it is not a bird
byrdies.add(b);
byrdies.add(c);
for (final Pet pet : byrdies) {
System.out.print("\nBird is a " + pet.getClass().getSimpleName() + " and is called ");
pet.printName();
}
}
}
To answer your question.
It is called polymorphism
In object B using case 1, B will be forced to implement myInterfaceA methods also your class B cannot have unimplemented methods except you declare the class as abstract thus:
class B implements myInterfaceA{
int dataMember1;
int dataMember2;
B(){}
public void method1(){
}
public void method2(){
}
//interface methods
public void interfaceMethod1(){
}
public void interfaceMethod2(){
}
}
Hence class b will have properties of the interface and that of itself as well as methods it has implemented.
Using case 2 B will however be implemented like this. (Assuming a is not an abstract class, thus it's methods will be implemented not declared like interface methods or abstract class method)
class B extends myClassA{
int dataMember1;
int dataMember2;
B(){
super();
}
public void method1(){
}
public void method2(){
}
}
notice that an explicit call may be made to the super class constructor
we give the reference to the interface/parent class because we want to have a single implementation where the super type is passed and the implementation is used for cases where there are many subtypes
Yes, it is polymorphic so that we can have different behaviours and implementations of the super type.
As i said earlier, an explicit call will be made to the super class constructor
It is standard practice to call the superclass constructor so that changes to it will not affect the subclass

Anonymous classes having interface keyword inside a class declaration

The below example I had seen in oracle doc for anonymous classes example.But how they can write interface HelloWorld inside a class HelloWorldAnonymousClasses
public class HelloWorldAnonymousClasses {
interface HelloWorld {
public void greet();
public void greetSomeone(String someone);
}
public void sayHello() {
class EnglishGreeting implements HelloWorld {
String name = "world";
public void greet() {
greetSomeone("world");
}
public void greetSomeone(String someone) {
name = someone;
System.out.println("Hello " + name);
}
}
HelloWorld englishGreeting = new EnglishGreeting();
HelloWorld frenchGreeting = new HelloWorld() {
String name = "tout le monde";
public void greet() {
greetSomeone("tout le monde");
}
public void greetSomeone(String someone) {
name = someone;
System.out.println("Salut " + name);
}
};
HelloWorld spanishGreeting = new HelloWorld() {
String name = "mundo";
public void greet() {
greetSomeone("mundo");
}
public void greetSomeone(String someone) {
name = someone;
System.out.println("Hola, " + name);
}
};
englishGreeting.greet();
frenchGreeting.greetSomeone("Fred");
spanishGreeting.greet();
}
public static void main(String... args) {
HelloWorldAnonymousClasses myApp =
new HelloWorldAnonymousClasses();
myApp.sayHello();
}
}
Interfaces can be anonymously implemented. This will not be an implementation of the interface, but rather the implementation of an interface in an anonymous subclass.
The interface itself doesn't get instantiated.
The line in question is this:
HelloWorld frenchGreeting = new HelloWorld() {
where HelloWorld is an interface. The curly brackets already indicate that this is an anonymous class. By defining it as HelloWorld you force the anonymous class to implement the methods defined in the interface.
If you are referring to the interface itself being defined inside class: if you want to have an interface defined for only the current class without exposing it to other objects, you can define it inside your class.
If you want to make it available to the outside world as well, you'll have to declare your class and interface public and access it using MyClass.MyInterface.
You can declare nested interfaces in the same way as you can declare static nested classes and inner classes. A nested interface declaration is implicitly static (Java Language Specification §8.5.1) - an "inner interface" wouldn't make sense because every instance of an inner class holds a reference to the relevant instance of the containing class, and you can't create an instance of an interface (only of a class that implements the interface).
In your example the interface definition has default visibility (it isn't declared public, protected or private) so any class that is in the same package as HelloWorldAnonymousClasses could refer to the nested interface as HelloWorldAnonymousClasses.HelloWorld.
There may be a scenario, where you need multiple implementations of a interface inside a class(and only to that class, you don't want to expose), so Java provides feature of declaring Interface inside class.
You can refer here, similar question.
If you read the tutorial trail a little farther, it actually can answer your question.
An anonymous class definition is an expression, it must be part of a statement. The syntax of an anonymous class expression is like the invocation of a constructor, except that there is a class definition contained in a block of code.
The instantiation of the frenchGreeting object in your example:
HelloWorld frenchGreeting = new HelloWorld() { /* other code */ };
The anonymous class expression is part of the statement that instantiates the frenchGreeting object, ended by a semicolon after the closing brace. the anonymous class is implementing the interface HelloWorld. When you implement an interface, there is no constructor, so you use an empty pair of parentheses, as in this example.

What is the difference between a public and private interface in Java

I know the difference between all the access modifiers in Java. However, someone asked me a very interesting question that I struggled to find the answer to: What is the difference between a private interface and a public interface in Java, in particular, how it is used as a class member? Any help would be greatly appreciated.
I believe we all know the use of public interface, so I would mention the point of private/protected interface here.
Interfaces can be members of class definitions and can be declared private or protected there.
public class Test {
private interface Sortable {
}
protected interface Searchable {
}
}
Example 1: -- Source
public class PrivateInterface {
private interface InnerInterface {
void f();
}
private class InnerClass1 implements InnerInterface {
public void f() {
System.out.println("From InnerClass1");
}
}
private class InnerClass2 implements InnerInterface {
public void f() {
System.out.println("From InnerClass2");
}
}
public static void main(String[] args) {
PrivateInterface pi = new PrivateInterface();
pi.new InnerClass1().f();
pi.new InnerClass2().f();
}
}
/* Output:
From InnerClass1
From InnerClass2
*/
It's the interface itself that can be package-private, not the methods
in it. You can define an interface that can only be used (by name)
within the package it's defined in, but its methods are public like
all interface methods. If a class implements that interface, the
methods it defines must be public. The key thing here is that it's the
interface type that isn't visible outside the package, not the
methods.
The public, private, and protected access modifiers on an interface mean the same thing that they mean on a class. I typically see these modifiers used on an interface that is nested in a class. Something like this:
//: interfaces/RandomWords.java
// Implementing an interface to conform to a method.
package interfaces;
public class PrivateInterface {
private interface InnerInterface {
void f();
}
private class InnerClass1 implements InnerInterface {
public void f() {
System.out.println("From InnerClass1");
}
}
private class InnerClass2 implements InnerInterface {
public void f() {
System.out.println("From InnerClass2");
}
}
public static void main(String[] args) {
PrivateInterface pi = new PrivateInterface();
pi.new InnerClass1().f();
pi.new InnerClass2().f();
}
}
An interface declaration may include these access modifiers:
public protected private abstract static strictfp
public: If an interface type is declared public,then it can be accessed by any code.
protected/private: The access modifiers protected and private pertain only to member interfaces within a directly enclosing class declaration. A member interface is an interface whose declaration is directly enclosed in another class or interface declaration.
static: The access modifier static pertains only to member interfaces, not to top level interfaces.
abstract: Every interface is implicitly abstract. This modifier is obsolete and should not
be used in new programs.
strictfp: The effect of the strictfp modifier is to make all float or double expressions
within the interface declaration be explicitly FP-strict.
Ref: Java Language and Virtual Machine Specifications

What is an anonymous inner class?

When I tried to do some sample on an abstract class in Java I accidentally got some thing like anonymous inner class in Eclipse.
I have pasted the piece of code below. I don't understand how the abstract class is related to anonymous class.
package com.Demo;
abstract class OuterClass {
abstract void OuterClassMethod();
}
public abstract class InnerClass extends OuterClass {
public static void main(String[] args) {
InnerClass myInnerClass = new InnerClass() {
#Override
void OuterClassMethod() {
int OuterClassVariable = 10;
System.out.println("OuterClassVariable" + " " + OuterClassVariable);
}
};
}
}
A anonymous class is an "in-line" concrete implementation of a class, typically (but not necessarily) of an abstract class or an interface. It is technically a subclass of the extended/implemented super class.
Google for more.
In your example, your class (InnerClass) extends class (OuterClass) and implementing their abstract methods which is the typical behavior of extending an abstract class. In the same way if your class implementing any interfaces you have to override their abstract methods. This is the way to implement Anonymous inner class.
Basically, an anonymous class is an implementation that has no name -- hence the "anonymous" bit.
This particular bit is what makes your class anonymous:
InnerClass myInnerClass = new InnerClass() {
#Override
void OuterClassMethod() {
int OuterClassVariable = 10;
System.out.println("OuterClassVariable" + " " + OuterClassVariable);
}
};
In normal class instantiations, you would just use:
InnerClass myInnerClass = new InnerClass();
but in this case, you are specifying a new implementation of that class, by overriding a function (OuterClassMethod()) within it. In other instances of InnerClass, OuterClassMethod() will still have its original implementation, because you only adapted this particular instance of InnerClass, and did not store this new implementation in a new class.
If you don't want anonymous classes, do this instead:
Somewhere, specify AnotherInnerClass to extend InnerClass, and to override that function:
class AnotherInnerClass extends InnerClass {
#Override
void OuterClassMethod() {
int OuterClassVariable = 10;
System.out.println("OuterClassVariable" + " " + OuterClassVariable);
}
};
And then instantiate it as such:
AnotherInnerClass myInnerClass = new AnotherInnerClass();

Categories

Resources