Confusion on call Java Interface method - java

Let's say I have an interface A, defined as follows:
public interface A {
public void a();
}
It includes method called void a();
I have a class which implements this interface and has only one method:
public class AImpl implements A {
#Override
public void a() {
System.out.println("Do something");
}
}
Q: If in the main class, I call interface method, will it call the implementation belonging to class which implements the interface?
For example:
public static void main(String[] args){
A aa;
aa.a();
}
Will this print "Do something"?

A aa = new AImpl();
aa.a();
Here your reference variable is interface A type But actual Object is AImpl.
When you define a new interface, you are defining a new reference data
type. You can use interface names anywhere you can use any other data
type name. If you define a reference variable whose type is an
interface, any object you assign to it must be an instance of a class
that implements the interface.
Read more on Documentation
A Interface reference can hold Object of AImpl as it implements the A interface.

It depends on the runtime type of the object. See:
This is your interface:
public interface A {
public void a();
}
And this is your class:
public class AImpl implements A {
public void a() {
println("I am AImpl");
}
}
There is another implementation:
public class AnotherAImpl implements A {
public void a() {
println("I am another AImpl");
}
}
So have a look at the this main method:
public static void main(String[] args){
A aa;
aa = new AImpl();
aa.a(); // prints I am AImpl
aa = new AnotherAImpl();
aa.a(); // now it prints I am another AImpl
}

You could probably find this out by running the code yourself.
Currently you will get a NullPointerException because you haven't assigned anything to the variable aa. Changing your code to the following will invoke the method and output the text:
public static void main(String[] args){
A aa = new AImpl();
aa.a();
}

You need to invoke the routine on the actual AImpl object
A aa = new AImpl();
aa.a();
which here is equivalent to following
AImpl aa = new AImpl();
aa.a();
Your sample will raise an error since you're trying invoke a method on an uninitalized object.

No. I will not.
You have declared a variable. You should initialze it first with instance of an object in this case your class AImpl.
public static void main(String[] args){
A aa = new AImp();
aa.a();
}

Related

Access to a protected constructor in Java

If I have a class A and its subclass B.
package washington;
public class A{
protected A(){}
}
package washington;
public class B extends A{
public B(){super();} // it works
public static void main (String[] args){
A b = new A(); // it does work.
}
}
The class A has a protected constructor, but I cannot access the constructor in B. I think it is a rule, however, I cannot find a webpage describing this situation.. All that I saw mention protected can be accessed from subclass, same-package.... e.t.c.
package california;
public class A extends washington.A{
public static void main (String[] args){
new washington.A(); // it does not work.
}
}
I wonder if this is because I use IntelliJ IDEA 2017.3.4.. compiler is javac 9.0.4
It seems that the problem is that you have your classes in different packages. Java doc says:
If the access is by a simple class instance creation expression new C(...), or a qualified class instance creation expression E.new C(...), where E is a Primary expression, or a method reference expression C :: new, where C is a ClassType, then the access is not permitted. A protected constructor can be accessed by a class instance creation expression (that does not declare an anonymous class) or a method reference expression only from within the package in which it is defined.
class A{
protected A() {
System.out.println("hello from A");
}
}
class B extends A{
public B() {
super();
System.out.println("hello from B");
}
public static void main (String[] args){
A b1 = new B(); // you can either do this
B b2 = new B(); // or this
}
}
Try running the program and you will see the expected result printed on console.

Can an Interface variable be reinitialised?

interface abs{
int a=10;// by default final static
void callme();
}
class B implements abs{
int a =11;// reinitializing
void call()
{
System.out.println("No problem"+a);
}
public void callme()
{
System.out.println("Call me"+a);
}
}
class main{
public static void main(String args[]){
B m=new B();
m.call();
m.callme();
}
}
In Herbert Schildt book, I have read that the interface variables are default Final and static. Which implicitly means that it will act like a constant. but when I am assigning 11 in the variable a in my above mentioned code, it is not giving any error.
o/p
No problem11
Call me11
You're not re-initializing the variable, but you're hiding it.
In order to access abs's a member, you have to refer it with the interface name. Something like:
System.out.println("No problem" + abs.a);
Because you have declared variable again
int a =11;
so see the error you want
do this in your class
a=11;
in your case the a is an entire new variable belonging to class B
You are not modifying the value of abs.a when you initialize a in class B. The field B.a simply hides the inherited a from the interface. You can still get to abs.a from code in class B by using the fully qualified name abs.a.
No, You can't reinitialize Interface variable. The variable in your Implementation Class is not interface variable A, but B class' instance variable. If you want to access Interface variable you reference it as abs.A
What you are actually doing is hiding the variable in interface by declaring a variable with same name in class B. You can verify it by using this code:
public interface Abs {
int a=10;// by default final static
void callme();
default void printA() {
System.out.println("A in interface: " + a);
}
}
public class B implements Abs {
int a =11;// reinitializing
void call()
{
System.out.println("A in class: "+a);
}
public void callme()
{
printA();
}
}
Then we have:
public static void main(String[] args){
B m=new B();
m.call();
m.callme();
}
It prints:
A in class: 11
A in interface: 10

Can you override a base class's method in an object of an anonymous type in VB.Net?

Just that:
Is it possible to create an object of an anonymous type that can override a method of its base class in VB.NET?
E.g., in Java we can do:
public class Foo {
public static Foo bar = new Foo() {
#Override
public void doStuff(){
System.out.println("Look, I'm doing stuff!");
}
};
public void doStuff() {
//do nothing
}
public static void main(String[] args) {
Foo.bar.doStuff();
}
}
//Output:
//Look, I'm doing stuff!
Is this possible in VB.NET?
Looks like you can imitate most of this functionality by declaring the method to be overridden as a delegate function that is a property of the class.
For example:
Public Class Foo
Public ReadOnly doStuff As delDoStuff
Delegate Sub delDoStuff()
Private Sub New(del As delDoStuff)
Me.doStuff = del
End Sub
Public Shared bar As New Foo(AddressOf barDoStuff)
Private Sub barDoStuff
WL("Look, I'm doing stuff!")
End Sub
End Class
Anyone have a better way?

Inheritance and Private Methods

Given the following block of code:
public class Trial {
public static void main (String[] args){
B obj = new B();
obj.doMethod(); #prints "From A".
}
}
class A {
private void method(){System.out.print("from A");}
public void doMethod(){method();}
}
class B extends A {
public void method(){System.out.print("from B");}
public void doMethod(){super.doMethod();}
}
It turns out that the method() from class A is invoked. Why is this?
You explicitly implement it that way. super calls method from base class which is A
public void doMethod(){super.doMethod();}
So the method chaining is like this:
B.doMethod() -> A.doMethod() -> A.method() -> "from A"
I think your question is if in class A private void method(){System.out.print("from A");} is private then why is printing "from A" in class B.
Answer is very simple you can't call method() of A class form any other class .But you can call it with object of its own.
when you calls super.doMethod(); then its function of super and method() is its own method so it can call it.
Because, see below:
class B extends A {
public void method(){System.out.print("from B");}
public void doMethod(){super.doMethod();}
}
Here in Class B's doMethod() you're invoiking Class A's doMethod() using super.doMethod(). So obviously it's printing Class A's doMethod().
You call the doMethod with super keyword. It's means it will call parent implementation
More on super keyword
Your code gives simple object creation (B obj = new B();) and a call using super. Super is used like other people mentioned for parent class. Things could have been different if you try something like (A obj = new B();), which is more interesting.
method() in class A is private and private methods can't be overriden. And when overriding it's better to use #Override annotion.
class B extends A {
#Override
public void method(){System.out.print("from B");} // Compile error
}
A similar thing happens, if you change the method to a static method.
class A {
public static void method(){System.out.print("from A");}
}
class B extends A {
public static void method(){System.out.print("from B");}
}

Can a private method in super class be overridden in the sub-class?

Can private methods be overridden in Java?
If no, then how does the following code work?
class Base{
private void func(){
System.out.println("In Base Class func method !!");
};
}
class Derived extends Base{
public void func(){ // Is this a Method Overriding..????
System.out.println("In Derived Class func method");
}
}
class InheritDemo{
public static void main(String [] args){
Derived d = new Derived();
d.func();
}
}
No, you are not overriding it. You can check by trying to mark it with #Override, or by trying to make a call to super.func();. Both won't work; they throw compiler errors.
Furthermore, check this out:
class Base {
private void func(){
System.out.println("In base func method");
};
public void func2() {
System.out.println("func2");
func();
}
}
class Derived extends Base {
public void func(){ // Is this an overriding method?
System.out.println("In Derived Class func method");
}
}
class InheritDemo {
public static void main(String [] args) {
Derived D = new Derived();
D.func2();
}
}
It will print:
func2
In base func method
When you change func() in Base to public, then it will be an override, and the output will change to:
func2
In Derived Class func method
No, a private method cannot be overridden because the subclass doesn't inherit its parent's private members. You have declared a new method for your subclass that has no relation to the superclass method. One way to look at it is to ask yourself whether it would be legal to write super.func() in the Derived class. There is no way an overriding method would be banned from accessing the method it is overriding, but this would precisely be the case here.
No, it is not. You can mark an override just to make sure like this:
#Override
public void func(){
System.out.println("In Derived Class func method");
}
And in this case it would be a compiler error.
You are not overriding. You cannot override private members, you are merely defining a new method in Derived. Derived has no knowledge Base's implementation of func() since its declared as private. You won't get a compiler error when you define func() in Derived but that is because Derived does not know Base has an implementation of func(). To be clear: it would be incorrect to say you are overriding Base's implementation of func().
In addition to the already correct answer, consider this:
public class Private {
static class A {
public void doStuff() {
System.out.println(getStuff());
}
private String getStuff() {
return "A";
}
}
static class B extends A {
public String getStuff() {
return "B";
}
}
public static void main(String[] args) {
A a = new A();
a.doStuff();
a = new B();
a.doStuff();
B b = new B();
b.doStuff();
}
}
This will print
A
A
A
although B "overrides" getStuff(). As implementation of doStuff() is fixed to calling A#getStuff(), no polymorphism will be triggered.
Nope because if you do something like Base b = new Derived(); you still won't be able to call b.func(). What you're doing is called "hiding".
Since the method is private it is not visible to the other classes.Hence the derived class does not inherit this method.
So this is not the case of overriding
Method hiding will be happening here instead of overriding. like what happens in case of static.
Actually,you are not overriding.Before Java5
an overridden method's return type must match with parent class's method.
But Java 5 introduced a new facility called covariant return type.You can override a method with the same signature but returns a subclass of the object returned. In another words, a method in a subclass can return an object whose type is a subclass of the type returned by the method with the same signature in the superclass.
you can follow this thread :Can overridden methods differ in return type?
The private member of the base class cannot be access by anyone outside of the class and cannot be overridden. The function in the derive class is an independent function that can be access by anywhere.
The code would run the function in the derived class
A private method can never be over ridden. It is always hidden.
In your example - Derived class has one parent class private method and has its own function func. Both are different, and the func is not over ridden. Its a separate independent function.
If you create a new function in parent class calling parent class function, the parent func will be called, if parent class reference is used as opposed in the case of method over ridding
Note : An object defines the members which it has, and a reference defines which it can access
// Method Over ridding case
class Base{
public void func(){
System.out.println("Parent class");
};
public void func1(){
func();
}
}
class Derived extends Base{
public void func(){
System.out.println("Derived class");
}
}
class InheritDemo{
public static void main(String [] args){
Derived d = new Derived();
d.func1(); // Prints Derived class
Base b = new Derived();
b.func1(); // Prints Derived class - no matter parent reference is calling,as there as method is overridden - Check func1() is in parent class, but id doesn't call parent class func() as the compiler finds a func() method over ridden in derived class
}
}
// Method Hidding case - Private and static methods case
class Base{
private void func(){
System.out.println("Parent class");
};
public void func1(){
func()
}
}
class Derived extends Base{
public void func(){ // Is this a Method Overriding..????
System.out.println("Derived class");
}
}
class InheritDemo{
public static void main(String [] args){
Derived d = new Derived();
d.func1(); // Prints Derived class
Base b = new Derived();
b.func1();
// Prints Parent class - the reason is we are using the parent class reference, so compiler is looking for func() and it founds that there is one private class method which is available and is not over ridden, so it will call it. Caution - this won't happen if called using derived class reference.
b.func();
// this prints the Derived class - the compiler is looking func(), as Derived class has only one func() that it is implementing, so it will call that function.
}
}
Read comments in the below code snippet to find the answer.
Sources:
Definition reference:
Credits for the source code example(reference) from the book - "OCA Oracle Certified Associate Java SE 8 Programmer Study Guide Exam 1Z0-808 Book" from 'Jeanne Boyarsky' and 'Scott Selikoff'.
public class Deer {
public Deer() { System.out.print("Deer"); }
public Deer(int age) { System.out.print("DeerAge"); }
private boolean hasHorns() { return false; }
public static void main(String[] args) {
Deer deer = new Reindeer(5);
System.out.println(","+deer.hasHorns());// false is printed.
}
}
class Reindeer extends Deer {
public Reindeer(int age) { System.out.print("Reindeer"); }
private boolean hasHorns() { return true; } // Overriding possible, but is of no use in the below context.
// Below code is added by me for illustration purpose
public static void main(String[] args) {
Deer deer = new Reindeer(5);
//Below line gives compilation error.
//System.out.println(","+deer.hasHorns());
}
}

Categories

Resources