Making abstract an overridden method - java

Here's something I quite understand:
abstract class A {
public void foo() {
System.out.println("a");
}
}
abstract class B extends A {
#Override
public abstract void foo();
public void bar() {
super.foo();
foo();
}
}
class C extends B {
#Override
public void foo() {
System.out.println("c");
}
}
public static void main(String[] args) {
new C().foo();
new C().bar();
}
new C().foo() prints c to the console, while new C().bar() prints a then c.
Calling super.foo() is illegal in the #foo() implementation of the C class.
I don't have a clear question, but if anyone could give a complete explanation of what is going on with the foo method, it may be interesting I think.

A is super class for B, so calling super.foo() inside B calls method defined in A, and calling foo() inside the same class will invoke its own implementation that should be delivered by any subclass.
You cannot use super.foo() within C class because it is defined as abstract in B and cannot be invoked directly.

Related

Inheritance - What method is being called?

I have a class A that extends a class B.
A is defined like this, it also overrides a method of B:
class A extends B
{
public A() {
super();
}
#Override
public void doSomething(){
//does something
}
}
B is defined like this:
public class B
{
public B(){
doSomething();
}
public void doSomething(){
//does something
}
}
So if I initialize an object of A, the constructor calls the one of the superclass that calls the method doSomething(). But which one will be executed? B's implementation or the overriden one in A?
That is a common bug, only call final methods in constructor, the method from A will be called.
Btw Sonar(if you have it) will trigger a rule here saying that you should not call polymorphic methods inside a constructor.
If the class Overrides a method, then the overriden method will be called. Try the example below:
public class A {
void doSomething() {
System.out.println("a");
}
}
public class B extends A {
#Override
void doSomething() {
System.out.println("b");
}
}
A a = new B();
a.doSomething(); // will print "b"

Can I use default method in is override? [duplicate]

Java 8 introduces default methods to provide the ability to extend interfaces without the need to modify existing implementations.
I wonder if it's possible to explicitly invoke the default implementation of a method when that method has been overridden or is not available because of conflicting default implementations in different interfaces.
interface A {
default void foo() {
System.out.println("A.foo");
}
}
class B implements A {
#Override
public void foo() {
System.out.println("B.foo");
}
public void afoo() {
// how to invoke A.foo() here?
}
}
Considering the code above, how would you call A.foo() from a method of class B?
As per this article you access default method in interface A using
A.super.foo();
This could be used as follows (assuming interfaces A and C both have default methods foo())
public class ChildClass implements A, C {
#Override
public void foo() {
//you could completely override the default implementations
doSomethingElse();
//or manage conflicts between the same method foo() in both A and C
A.super.foo();
}
public void bah() {
A.super.foo(); //original foo() from A accessed
C.super.foo(); //original foo() from C accessed
}
}
A and C can both have .foo() methods and the specific default implementation can be chosen or you can use one (or both) as part of your new foo() method. You can also use the same syntax to access the default versions in other methods in your implementing class.
Formal description of the method invocation syntax can be found in the chapter 15 of the JLS.
This answer is written mainly for users who are coming from question 45047550 which is closed.
Java 8 interfaces introduce some aspects of multiple inheritance. Default methods have an implemented function body. To call a method from the super class you can use the keyword super, but if you want to make this with a super interface it's required to name it explicitly.
class ParentClass {
public void hello() {
System.out.println("Hello ParentClass!");
}
}
interface InterfaceFoo {
public default void hello() {
System.out.println("Hello InterfaceFoo!");
}
}
interface InterfaceBar {
public default void hello() {
System.out.println("Hello InterfaceBar!");
}
}
public class Example extends ParentClass implements InterfaceFoo, InterfaceBar {
public void hello() {
super.hello(); // (note: ParentClass.super could not be used)
InterfaceFoo.super.hello();
InterfaceBar.super.hello();
}
public static void main(String[] args) {
new Example().hello();
}
}
Output:
Hello ParentClass!
Hello InterfaceFoo!
Hello InterfaceBar!
The code below should work.
public class B implements A {
#Override
public void foo() {
System.out.println("B.foo");
}
void aFoo() {
A.super.foo();
}
public static void main(String[] args) {
B b = new B();
b.foo();
b.aFoo();
}
}
interface A {
default void foo() {
System.out.println("A.foo");
}
}
Output:
B.foo
A.foo
You don't need to override the default method of an interface. Just call it like the following:
public class B implements A {
#Override
public void foo() {
System.out.println("B.foo");
}
public void afoo() {
A.super.foo();
}
public static void main(String[] args) {
B b=new B();
b.afoo();
}
}
Output:
A.foo
It depends on your choice whether you want to override the default method of an interface or not. Because default are similar to instance method of a class which can be directly called upon the implementing class object. (In short default method of an interface is inherited by implementing class)
Consider the following example:
interface I{
default void print(){
System.out.println("Interface");
}
}
abstract class Abs{
public void print(){
System.out.println("Abstract");
}
}
public class Test extends Abs implements I{
public static void main(String[] args) throws ExecutionException, InterruptedException
{
Test t = new Test();
t.print();// calls Abstract's print method and How to call interface's defaut method?
}
}

Java execution flow?

what will be the flow of execution in case of override? What i believe is , when we call a constructor/object of any class, during execution first it call parent constructor and than child. but what will happen in case of over ridding?
lets suppose:
class A {
public A(){
printStatus();
}
public void printStatus(){
System.out.println("In Class A");
}
}
class B extends A{
public B(){
printStatus();
}
#Override
public void printStatus(){
System.out.println("In Class b");
}
}
public class Test2 {
public static void main(String[] args){
B b = new B();
}
}
Out put of this code is:
In Class b
In Class b
what i don't understand is, why it's printing "In Class be" only, it should be "In class A and, In Class b",
when i remove override method from class b. it give me desired output.
All java methods are virtual. It means the method is called with using actual type of this. So inside of constructor A() {} this is the instance of B, so that is why you've got its method call.
Calling like this printStatus() will call the method from the same class. If you call with super.printStatus() it will envoke method from the super class (class which you have extended).
When you over-ride a method you over-ride it completely. The existence of the original implementation is completely invisible to other classes (except via reflection but that's a big topic of its own and not really relevant). Only your own class can access the original method and that is by calling super.methodName().
Note that your class can call super.methodName() anywhere, not just in the overriding function, although the most usual use for it is in the overriding function if you want the super implementation to run as well as your own.
Constructors are a slightly special case as there are rules about how and why constructors are called in order to make sure that your super-class is fully initialized when you try and use it in the inheriting class.
super is always called whether you write super(); or not.
In the example printStatus() method of Class A will never be called. Since you are creating an instance of class B and there will be method overriding. You can use the following to call the Class A printStatus() method.
public B()
{
super.printStatus();
}
When you override a method, it will override the one that you expect from class A.
Should use super keyword for calling super class method.
class A {
public A(){
printStatus();
}
public void printStatus(){
System.out.println("In Class A");
}
}
class B extends A{
public B(){
super.printStatus();
}
#Override
public void printStatus(){
System.out.println("In Class b");
}
}
Constructor public B(){ super.printStatus(); } calls Class A print method and constructor public A(){ printStatus(); } calls Class B print method since you've overridden.
But its wrong with overridable method calls in constructors.
Try with like this :
class A {
public A(){
printStatus();
}
public void printStatus(){
System.out.println("In Class A");
}
}
class B extends A{
public B(){
super.printStatus();
printStatus();
}
#Override
public void printStatus(){
System.out.println("In Class b");
}
}
public class Test2 {
public static void main(String[] args){
B b = new B();
}
}
For better understanding the concepts of Overloading and Overriding just go through this links:
http://en.wikibooks.org/wiki/Java_Programming/Overloading_Methods_and_Constructors

Implement two interfaces in an anonymous class

I have two interfaces:
interface A {
void foo();
}
interface B {
void bar();
}
I am able to create anonymous instances of classes implementing either of these interfaces like so:
new A() {
void foo() {}
}
or:
new B() {
void bar() {}
}
I want to create an anonymous class that implements both interfaces. Something like (the fictitious):
new A implements B {
void foo() {}
void bar() {}
}
This obviously gives a compile error: "B cannot be resolved to a type".
The workaround is quite simple:
class Aggregate implements A, B {
void foo() {}
void bar() {}
}
I then use Aggregate where ever I would have used the anonymous class.
I was wondering if it is even legal for an anonymous class to implement two interfaces.
"An anonymous inner class can extend one subclass or implement one
interface. Unlike non-anonymous classes (inner or otherwise), an anonymous
inner class cannot do both. In other words, it cannot both extend a class and
implement an interface, nor can it implement more than one interface. " (http://scjp.wikidot.com/nested-classes)
If you are determined to do this, you could declare a third interface, C:
public interface C extends A, B {
}
In this way, you can declare a single anonymous inner class, which is an implementation of C.
A complete example might look like:
public class MyClass {
public interface A {
void foo();
}
public interface B {
void bar();
}
public interface C extends A, B {
void baz();
}
public void doIt(C c) {
c.foo();
c.bar();
c.baz();
}
public static void main(String[] args) {
MyClass mc = new MyClass();
mc.doIt(new C() {
#Override
public void foo() {
System.out.println("foo()");
}
#Override
public void bar() {
System.out.println("bar()");
}
#Override
public void baz() {
System.out.println("baz()");
}
});
}
}
The output of this example is:
foo()
bar()
baz()
For save some keystrokes (for example if the interfaces have a lot of methods) you can do this:
abstract class Aggregate implements A, B {
}
new MyObject extends Aggregate {
void foo() {}
void bar() {}
}
Notice the key is to declare the Aggregate as abstract.
Note that you can make a named local class that implements the two interfaces:
void method() {
class Aggregate implements A, B {
void foo() {}
void bar() {}
}
A a = new Aggregate();
B b = new Aggregate();
}
This save you from doing a class-level or top-level class declaration.
The result is called a local class. Local classes declared in instance methods are also inner classes, which means that they can reference the containing object instance.

calling a super method from a static method

Is it possible to call a super static method from child static method?
I mean, in a generic way, so far now I have the following:
public class BaseController extends Controller {
static void init() {
//init stuff
}
}
public class ChildController extends BaseController {
static void init() {
BaseController.loadState();
// more init stuff
}
}
and it works, but I'd like to do it in a generic way, something like calling super.loadState(), which doesn't seem to work...
In Java, static methods cannot be overidden. The reason is neatly explained here
So, it doesn't depend on the object that it is being referenced. But instead, it depends on the type of reference. Hence, static method is said to hide another static method and not override it.
For example (Cat is a subclass of Animal):
public class Animal {
public static void hide() {
System.out.format("The hide method in Animal.%n");
}
public void override() {
System.out.format("The override method in Animal.%n");
}
}
public class Cat extends Animal {
public static void hide() {
System.out.format("The hide method in Cat.%n");
}
public void override() {
System.out.format("The override method in Cat.%n");
}
}
Main class:
public static void main(String[] args) {
Cat myCat = new Cat();
System.out.println("Create a Cat instance ...");
myCat.hide();
Cat.hide();
myCat.override();
Animal myAnimal = myCat;
System.out.println("\nCast the Cat instance to Animal...");
Animal.hide();
myAnimal.override();
Animal myAnimal1 = new Animal();
System.out.println("\nCreate an Animal instance....");
Animal.hide();
myAnimal.override();
}
Now, the output would be as given below
Create a Cat instance ...
The hide method in Cat.
The hide method in Cat.
The override method in Cat.
Cast the Cat instance to Animal...
The hide method in Animal.
The override method in Cat.
Create an Animal instance....
The hide method in Animal.
The override method in Animal.
For class methods, the runtime system invokes the method defined in the compile-time type of the reference on which the method is called.
In other words, call to static methods are mapped at the compile time and depends on the declared type of the reference (Parent in this case) and not the instance the reference points at runtime. In the example, the compile-time type of myAnimal is Animal. Thus, the runtime system invokes the hide method defined in Animal.
There is static inheritance in Java. Adapting the example from Nikita:
class A {
static void test() {
System.out.print("A");
}
}
class B extends A {
}
class C extends B {
static void test() {
System.out.print("C");
B.test();
}
public static void main(String[] ignored) {
C.test();
}
}
This now compiles, and invoking C prints "CA", of course. Now we change class B to this:
class B extends A {
static void test() {
System.out.print("B");
}
}
and recompile only B (not C). Now invoking C again, it would print "CB".
There is no super like keyword for static methods, though - a (bad) justification may be that "The name of the super class is written in the declaration of this class, so you had to recompile your class nevertheless for changing it, so you could change the static calls here, too."
The whole inheritance concept isn't applied to static elements in Java. E.g., static method can't override another static method.
So, no, you'll have to call it by name or make them instance methods of some object. (You might want to check out one of factory patterns in particular).
A practical example
class A {
static void test() {
System.out.println("A");
}
}
class B extends A {
static void test() {
System.out.println("B");
}
}
A a = new B();
B b = new B();
a.test();
b.test();
This prints A and then B. I.e., invoked method depends on how variable is declared and nothing else.
You can actually call the static method of a superclass in a generic way, given that you know the method name and its parameters.
public class StaticTest {
public static void main(String[] args) {
NewClass.helloWorld();
}
}
public class NewClass extends BaseClass {
public static void helloWorld() {
try {
NewClass.class.getSuperclass().getMethod("helloWorld", new Class[] {}).invoke( NewClass.class ,new Object[]{} );
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("myVar = " + myVar);
}
}
public class BaseClass extends BaseBaseClass {
protected static String myVar;
public static void helloWorld() {
System.out.println("Hello from Base");
myVar = "Good";
}
}
This should work and in the subclass you have everything set in the base class available.
The output should be:
Hello from Base
myVar = Good
The official name of your implementation is called method hiding. I would suggest introducing a static init(Controller controller) method, and calling an instance method to take advantage of overriding.
public class Controller {
static void init(Controller controller) {
controller.init();
}
void init() {
//init stuff
}
}
public class BaseController extends Controller {
#override
void init() {
super.init();
//base controller init stuff
}
}
public class ChildController extends BaseController {
#override
void init() {
super.init();
//child controller init stuff
}
}
You can then call Controller.init(controllerInstance).
For static methods there is no instance of a class needed, so there is no super.

Categories