简体   繁体   中英

How to call abstract class method

I have an interface called Hospital.java

public interface Hospital {
    public void operate();
    public void doScan();
    public void doVaccination();
}

I have an abstract class called StreetHospital.java

public abstract class StreetHospital implements Hospital{
    public void operate(){
        System.out.println("Street Hospital operate");
  }
}

Now I am using another class CommunityHospital.java to extend StreetHospital.java

public class CommunityHospital extends StreetHospital{

    public void doScan(){
        System.out.println("CommunityHospital doScan");
    }
    public void doVaccination(){
        System.out.println("CommunityHospital doVaccination");
}
    public void operate(){
        System.out.println("CommunityHospital operate");
    }
}

I am creating the CommunityHospital object in my MainHospital class

public class MainHospital {

    public static void main(String[] args){
        CommunityHospital ch = new CommunityHospital();
        ch.operate();
        ch.doScan();
        ch.doVaccination();

    }
}

I am getting this output:

CommunityHospital operate
CommunityHospital doScan
CommunityHospital doVaccination

My question is how do I print "Street Hospital operate" sysout statement in output?

You can't do that.

There can't be two methods in one class with same name and param. Once you override operate() in CommunityHospital , the same mthod in StreetHospital no longer exist.

You need to use super keyword to invoke the superclass members in the subclass as shown below:

public class CommunityHospital extends StreetHospital{

    public void doScan(){
        System.out.println("CommunityHospital doScan");
    }
    public void doVaccination(){
        System.out.println("CommunityHospital doVaccination");
    }
    public void operate(){
        super.operate();//call super class operate to get StreetHospital features
        //If you want, you can add CommunityHospital features here
    }
}

I suggest you look here for more details and understand the concept.

If your method overrides one of its superclass's methods, you can invoke the overridden method through the use of the keyword super .

One way is to remove the operate method from CommunityHospital class.

In terms of design that would mean that community hospital's operate does not differ from a street hospital's operate.

Another consideration would be that you actually want street hospital's operate and then there are some specifics that need to be accomplished in community hospital's operate. For that CommunityHospital operate function should look like:

public void operate() {
        super.operate(); //Street hospital operate
        // Add community hospital operate details here
} 

You are extending a class, but then overwriting its methods. So whenever you call operate it will use the one in CommunityHospital which is the overwritten one. If you remove that, it will find the operate method from the StreetHospital class.

If for some reason you do need an operate method in CommunityHospital , don't implement a new one and just call super.operate() . This will call the StreetHospital class' operate method.

CommunityHospital overrides the operate method, so if that class doesn't call super then is not possible...

do modify the class like:

 public void operate(){
        super.operate(); // call the method from super class

    }

Add another function to CommunityHospital with another name say superOperate like this:

public void superOperate(){
    super.operate();
}

and call it from anywhere

 public void operate(){
        super.operate(); // call the method from super class

    }

or just remove

@Override
    public void operate() {
        System.out.println("CommunityHospital operate");
    }

form CommunityHospital

If you want to write StreetHospital in a way so that subclasses can override operate() , but the StreetHospital 's operate() (the non-overridden one) can still be called, you could do this:

public abstract class StreetHospital implements Hospital {
    public final void streetOperate() {
        System.out.println("Street Hospital operate");
    }
    public void operate() {
        streetOperate();
    }
}

Now operate() can be overridden, but streetOperate() can still be called on any CommunityHospital object, or any other subclass of StreetHospital .

However, it's really difficult for me to think of an actual case where this would be a good design.

You could do it by using super

class CommunityHospital extends StreetHospital{
    // same code
    public void operate(){
        super.operate(); //-> this line
        //System.out.println("CommunityHospital operate");
    }
}

You could also make the operate method final , if you don't want to allow overriding of it.

abstract class StreetHospital implements Hospital{
    final public void operate(){
        System.out.println("Street Hospital operate");
    }
}

As long as you don't override the operate method, it will be available in your class when you extend it.

So don't override the operate method in your class when you are extending it.

public class CommunityHospital extends StreetHospital {
   public class CommunityHospital extends StreetHospital {

    public void doScan() {
        System.out.println("CommunityHospital doScan");
    }

    public void doVaccination() {
        System.out.println("CommunityHospital doVaccination");
    }
}

This shall work.

Unfortunately there is no other way than calling super.operate in subclass.

Upcasting in java doesn't work. Demo that shows it:

package com.stackoverflow.main;

class A {
    void operate() {
        System.out.println("A");
    }
}

class B extends A {
    void operate() {
        System.out.println("B");
    }
}

public class Main {

    public static void main(String[] args) {
        A b = new B();
        ((A) b).operate();
    }
}

Prints:

B

Use the concept of down casting . I have written the code in C#

abstract class MyClass1 {
    public void operate() {
        System.Console.WriteLine("base class");
    }
    public abstract void operate1();
    public virtual void operate2() {
        System.Console.WriteLine("Virtual");
    }
}

class myclass2 : MyClass1 {
    public override void operate1() {
        Console.WriteLine("Success");
    }
    public override void operate2() {
        Console.WriteLine("overidden");
    }
    public new void operate() {
        Console.WriteLine("!base class");
    }
}

class program {
    static void Main(string[] args) {
        MyClass1 m = new myclass2();
        m.operate();
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM