I am looking for the solution how extend method of the super class with custom content.
for example I have a super class
class A{
public A(){
boolean ok = doSomeInitialWork();
if(ok){
specialMehtod();
}
}
specialMehtod(){
System.out.print("HEllO");
}
}
so my class A does some "init" things and then calls specialMehtod(). Now I would like to have class B extends A and add some other code to specialMehtod(). Something like:
Class B extends A{
B(){
super();
}
specialMehtod(){
System.out.print("BBBBB");
}
}
But if I do so, I call a.SpecialMethod() expizit, and actually I only want to "add" System.out.print("BBBBB"); to specialMethod(), so that it still get called from constructor of A.
What I want to achieve, is that finaly I could do in my main class
new B();
ant the output would be.
HELLO
BBBBB
because B() calls constructor of A(), which calls A.specialMethod() extended by B.specialMethod();
Is it possible?
Thanks
You would have to so something like this:
public abstract class A{
public abstract void anotherMethod();
public A(){
// some stuff..
specialMethod();
}
private final void specialMethod(){
System.out.println("specialMethod");
anotherMethod();
}
}
public class B extends A{
public B(){
super();
}
public void anotherMethod(){
System.out.println("anotherMethod");
}
}
This way you force your extending class to implement the method anotherMethod() and this method is called from your abstract class A. If your extending class does not need to do anything in anotherMethod(), you can just let the method body empty.
As mentioned in the comments of your question, you have to either inherit or override the method. When overriding a method, you have to call the super-method super.someMethod(); explicitly or when inheriting, you can not add additional functionality to the given method.
So to come with your example, if you don't implement specialMethod() in B, it will print out "HELLO", since A has an implementation for the method, but B does not. If you override the method like you are doing in the example in class B:
specialMethod(){
System.out.println("BBBBB");
}
It will have the effect that "HELLO" will not be printed out. In this case, the constructor of A will directly call B.specialMethod() (on the instance of the B Object). If you wan't A.specialMethod() to be called, you have to explicitly call it. So, no, you can not 'add functionality' to a method implemented in the super-class without explicitly calling super.specialMethod().
For this reason, I have constructed the example above as a workaround. Please note that I have updated the code. With that example, if you call new B();, the output will be:
specialMethod
anotherMethod
And with this workaround, the extending class does not explicitly have to call super.specialMethod(), but it must implement anotherMethod(). Additionally, by making specialMethod a final method, B is not allowed to override specialMethod.
Use abstract method in A. Like this -
public class A{
public abstract specialMethod();
}
Then when B extends A, B have to implement the specialMethod() by its own.
Related
I'm starting with developing something, and I have few classes that are using the same methods, so I want to have it in one class (to easy fixing in one place etc). Problem is that I dont know how to use methods from different classes on object in main class. Code for explanation:
public class A extends C {
public UiDevice device;
device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
public void test(){
methodFromC();
}
}
public class B extends C {
public UiDevice device;
device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
public void test(){
methodFromC();
}
}
public class C {
protected void methodFromC(){
device.something();
}
}
I know that I can do it by adding argument to methodFromC:
public class C {
protected void methodFromC(UiDevice device){
device.something();
}
and running it by
methodFromC(device);
But maybe is there better solution?
First of all, as a beginning programmer unless you are doing it for school, avoid extending classes. It ends up a big spaghetti mess until you learn to moderate it (I fell for this one big-time), What you are trying to do isn't good code right now.
I THINK what you are trying to do, however is something like this:
(Assume unspecified code remains pretty much as it is)
class A extends C
{
public UiDevice getDevice()
{
return device;
}
}
abstract class C
{
public abstract UiDevice getDevice();
public methodFromC()
{
getDevice().doSomethingToDevice();
}
}
This pattern allows you to access something from A in a parent class.
B can also have it's own device. I believe this is what you are after (C being able to operate on A's device or B's device depending on which one extended C).
Get rid of the public variable.
You can use the super keyword to access anything from the class you are extending. In your case :
public class B extends C {
public UiDevice device;
device = super.methodFromB();
public void test(){
methodFromB();
}
}
If many of your classes declare methods that do the same thing, you can make them inherit from one class, let's call it class A. In class declare and implement the method. Then in child classes declare methods and in their body write:
super.nameOfYourMethodFromParentClass();
In general, to use a method from different class you just create an object of the class and call a method on it. Like:
class A {
public void myMethod() {
B b = new B();
b.methodFromB();
}
}
When it comes to inheritance be aware of this:
You can create an object of a class that declares this method or of a class that inherits from the class that declares this method and call the method on this object.
Like:
Class A inherits from C. In class C you have method methodFromC() declared. To invoke method from class C on object from class A you can do:
A a = new A();
a.methodFromC(device);
The invoked method here is the method from class C.
But if in class A you override method from class C (that means in class A you declare a method that has the same name and parameters as method in class C), then by executing the code I have written above you will invoke the method from class A, not class C.
I had a doubt.
Imagine If we have a class A that implements the method
For example
private void methodA(int index) throws Exception, Error {
}
And if we have a Class B that extends the first class A.
My questions is, can class B implement
private void methodA(int index) throws Exception, Error {
}
And which method will be called under which circumstance!!
Thanks
If your methods weren't declared "private", this would just be standard polymorphism. Because they're private, the rules are a bit different. The version in class A can only be called from code that's in class A. The version in class B can only be called from code that's actually written in class B (as opposed to code that class B gets by extending class A).
YES, you can implement the methodA method in class B, but, pay attention, you are not overriding it.
Your method is declared ad private so is not "visible" from extending classes.
If your intention is to make your method overridable, you need to declare it as public.
Just give it a try :)
public class Main {
public static void main(String[] args) {
Base base;
base = new A();
System.out.println(base.doSth());
base = new B();
System.out.println(base.doSth());
}
}
abstract class Base {
public abstract String doSth();
}
class A extends Base {
#Override
public String doSth() {
return "A";
}
}
class B extends A {
#Override
public String doSth() {
return "B";
}
}
I think you wonna override the super-class method, and to do this, the method on sub-class must have the same signature of super-class method.
You can call these methods in following ways:
Suppose test1 is an instance of classA, teste1.methodA(index) will execute the implementation on super-class.
Suppose test2 is an instance of classB, test2.methodA(index) will execute the sub-class method.
In classB you can invoque the super class method (if the method is notprivate), something like :
public class ClassB extends ClassA
{
...
super.methodA(index);
...
}
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Use of ‘super’ keyword when accessing non-overridden superclass methods
I'm new to Java and have been reading a lot about it lately to get more knowledge and experience about the language. I have a question about inherited methods and extending classes when the compiler inserts automatic code.
I've been reading that if I create class A with some methods including lets say a method called checkDuePeriod(), and then create a class B which extends class A and its methods.
If I then call the method checkDuePeriod() within class B without using the super.checkDuePeriod() syntax, during compilation will the compiler include the super. before checkDuePeriod() or will the fact that the compiler includes the super() constructor automatically when compiling the class imply the super. call of the methods that class B calls from class A?
I'm a little confused about this. Thanks in advance.
The super class's implementation of regular methods is not automatically invoked in sub classes, but a form of the super class's constructor must be called in a sub class's constructor.
In some cases, the call to super() is implied, such as when the super class has a default (no-parameter) constructor. However, if no default constructor exists in the super class, the sub class's constructors must invoke a super class constructor directly or indirectly.
Default constructor example:
public class A {
public A() {
// default constructor for A
}
}
public class B extends A {
public B() {
super(); // this call is unnecessary; the compiler will add it implicitly
}
}
Super class without default constructor:
public class A {
public A(int i) {
// only constructor present has a single int parameter
}
}
public class B extends A {
public B() {
// will not compile without direct call to super(int)!
super(100);
}
}
If you call checkDuePeriod() in B without super., means you want to invoke the method that belongs to the this instance (represented by this within B) of B. So, it equivalent to saying this.checkDuePeriod(), so it just doesn't make sense for the compiler to add super. in the front.
super. is something that you must explicitly add to tell the compiler that you want to call the A's version of the method (it is required specially in case B has overridden the implementation provided by A for the method).
Call of super() as a default constructor (constructor with no args) can be direct or non direct but it garants that fields of extendable class are properly initialized.
for example:
public class A {
StringBuilder sb;
public A() {
sb = new StringBuilder();
}
}
public class B extends A {
public B() {
//the default constructor is called automatically
}
public void someMethod(){
//sb was not initialized in B class,
//but we can use it, because java garants that it was initialized
//and has non null value
sb.toString();
}
}
But in case of methods:
Methods implement some logic. And if we need to rewrite logic of super class we use
public class B extends A {
public B() {
}
public boolean checkDuePeriod(){
//new check goes here
}
}
and if we want just implement some extra check, using the value returned from checkDuePeriod() of superclass we should do something like this
public class B extends A {
public B() {
}
public boolean checkDuePeriod(){
if(super.checkDuePeriod()){
//extra check goes here
}else{
//do something else if need
}
return checkResult;
}
}
First about the Constructors:
- When ever an object of a class is created, its constructor is initialized and at that time immediately the constructor of its super-class is called till the Object class,
- In this process all the instance variables are declared and initialized.
- Consider this scenario.
Dog is a sub-class of Canine and Canine is a sub-class of Animal
Now when Dog object is initialized, before the object actually forms, the Canine class object must be form, and before Canine object can form the Animal class object is to be formed, and before that Object class object must be form,
So the sequence of object formed is:
Object ---> Animal ---> Canine ---> Dog
So the Constructor of the Super-Class is Called before the Sub-Class.
Now with the Method:
The most specific version of the method that class is called.
Eg:
public class A{
public void go(){
}
}
class B extends A{
public static void main(String[] args){
new B().go(); // As B has not overridden the go() method of its super class,
// so the super-class implementation of the go() will be working here
}
}
My Class Architecture goes like this.
I have an interface "myInterface". I create a class "mySuperMostClass" which implements "myInterface". Now i create a class "myBaseClass" which extends "mySuperMostClass". Then i create "mySubClass" which extends "myBaseClass". I have overridden the methods "methodA", "methodB" from "myBaseClass" in "mySubClass".
"methodB" is called from "methodA"
Now i create an object for mySubClass and refer it with instance of "myInterface". When i call methodA with the instance of myInterface, the implementation from "myBaseClass" is called. But i want it to call "mySubClass". Kindly help me to do this.
I am using Java 1.5
First of all, I'm sure that your actual class names don't start with lowercase. If they do, I would suggest that you read about Java Naming Convention
When overriding methods from your parent class make sure that the method signature remains consistent. For example, if you have a method called public void method(String input), you've to make sure that the same signature is maintained in the child class.
So, from reading your question, I assume the correct implementation would be something like this:
public interface MyInterface{
}
class MySuperMostClass implements MyInterface{
}
class MyBaseClass extends MySuperMostClass{
public void methodA(){
}
public void methodB(){
}
}
class MySubClass extends MyBaseClass{
#override
public void methodA(){
methodB();
}
#override
public void methodB(){
}
}
Note: I'm not so sure of the actual signature of your methods, hence I've kept them as parameterless. In your case, make sure that the signature remains the same.
And the way you would call would be something like this:
MyInterface myObject = new MySubClass();
myObject.methodA();
Java does not allow multiple inheritance, meaning that a class cannot inherit from two classes, which does not have anything in common, meaning that they are not on the same inheritance path. However, a class can inherit from more classes, if these classes are super classes of the direct super class of the class. But the class inherits from these classes indirectly, meaning that it does not "see" anything from these upper super classes, right? I was confused when considering constructors (using super() in the constructor). For example, if we have the following classes:
public class A {
public A() {
....
}
}
public class B extends A {
public B() {
super();
....
}
}
public class C extends B {
public C() {
super();
....
}
}
the constructor of class C invokes first the constructor of class B using super(). When this happens, the constructor of B itself invokes first the constructor of A (with super()), but the constructor of C does not know anything about the constructor of A, right? I mean, the inheritance is only from the direct super class - the first (nearest) class from the inheritance hierarchy. This is my question - with super() we mean only the constructor of the direct super class, no matter how many other classes we have in the inheritance hierarchy.
And this does not apply only for constructors, but for any methods and instance variables..
Regards
You have to invoke some constructor in your immediate base class. This can be
public class A {
public A() {
....
}
public A(String foo) {
....
}
}
public class B extends A {
public B() {
super();
.. or ..
super("ThisIsAB")
}
}
public class C extends B {
public C() {
super();
....
}
}
So for constructors you cannot AVOID constructing your intermediate base classes, but you can choose which constructor to use. If there is only the no-args constructor it's all handled for you with an implicit call to super. With multiple constructors you have some more choices.
super can refer to any non-private variable or method in any base class. So methods and variables are not the same as constructors in this respect.
Even if you could avoid calling the intermediate ctor, you wouldn't want to, because that would mean you had uninitialized pieces of the intermediate classes that might be acessed by the bottom-most derived class. To horrible effects.
But I sense that you're trying to trick your way around Java to do multiple inheritance. That is a Bad Thing. Instead, you can do it Java-wise by using an interface
class B extends A implements C {
// ... implement C methods here
}
or by using aggregation
class B extends A {
private C c;
}
Constructors for all parents are called. In fact, deep down C knows about A because B extends A. For example, if the class A contained method foo(), then you could call foo() from C.
So from your example, C calls the constructor from B, which calls the constructor from A. Additionnally, A also extends from the class Object. So the constructor in the class Object is also called!
Furthermore, you do not need to add a call to super(). If there is no call for the constructor of the parent, super is call implicitly.
As you say, C's constructor invokes B's constructor which invokes A's constructor. You can call any "A" methods on a C object, and a C object can see non-private fields in A.
Even if you override A's method "foo" in C, you can get the A version with "super.foo()", assuming B doesn't also override it.
As far as C knows, anything that it does not overwritten in C is contained in B, even if under the covers class A is where the implementation might be.
public class A {
public A() {
}
public void aMethod() {
}
}
public class B extends A {
public B() {
super();
}
}
public class C extends B {
public C() {
super();
}
public void doWork() {
super.aMethod();
}
}
So in this case A handles the implementation of aMethod(), even though calling super() in C's constructor called B's constructor directly, not A's.