【问题标题】:How to call abstract class method如何调用抽象类方法
【发布时间】:2017-05-10 05:19:08
【问题描述】:

我有一个名为 Hospital.java 的接口

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

我有一个名为 StreetHospital.java 的抽象类

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

现在我正在使用另一个类 CommunityHospital.java 来扩展 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");
    }
}

我正在我的 MainHospital 类中创建 CommunityHospital 对象

public class MainHospital {

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

    }
}

我得到这个输出:

CommunityHospital operate
CommunityHospital doScan
CommunityHospital doVaccination

我的问题是如何在输出中打印“Street Hospital operation”sysout 语句?

【问题讨论】:

  • 从你的主,你不能,因为它被覆盖了。在CommunityHospital 但是你可以打电话给super.operate()
  • CommunityHospital 类中操作的方法中使用super.operate()CommunityHospital 类覆盖了该方法,因此没有其他方法,因为在一个类中不能有两个具有相同签名的方法。
  • @i_am_zero 它不必是第一行。 (您可能会将它与在构造函数中使用 super() 混淆,它必须是第一个。)
  • 真的不确定你想要实现什么,但你可以创建StreetHospital 的另一个子类,而无需自己实现operate 方法;例如PrivateHospital extends StreetHospital,然后在新类的对象上调用operate
  • @ajb 是的 :)

标签: java class inheritance abstract core


【解决方案1】:

将另一个函数添加到CommunityHospital,并使用另一个名称说superOperate,如下所示:

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

并从任何地方调用它

【讨论】:

  • 谢谢你。它有效。除了使用 super 关键字还有其他方法吗?
  • @nsd 访问父级方法的唯一方法是超级。我认为没有其他方法。
【解决方案2】:

子类中调用超类成员需要使用super关键字,如下图:

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
    }
}

我建议您查看here 了解更多详细信息并了解这个概念。

如果您的方法覆盖了其超类的方法之一,您可以 通过使用关键字 super 调用被覆盖的方法。

【讨论】:

    【解决方案3】:
     public void operate(){
            super.operate(); // call the method from super class
    
        }
    

    或者直接删除

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

    形成社区医院

    【讨论】:

      【解决方案4】:

      你不能这样做。

      一个类中不能有两个具有相同名称和参数的方法。一旦您在 CommunityHospital 中覆盖了operate(),StreetHospital 中的相同方法将不再存在。

      【讨论】:

        【解决方案5】:

        如果您想以某种方式编写StreetHospital,以便子类可以覆盖operate(),但仍然可以调用StreetHospitaloperate()(未被覆盖的),您可以这样做:

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

        现在operate() 可以被覆盖,但streetOperate() 仍然可以在任何CommunityHospital 对象或StreetHospital 的任何其他子类上调用。

        但是,我真的很难想出一个实际案例,这会是一个好的设计。

        【讨论】:

          【解决方案6】:

          一种方法是从CommunityHospital 类中删除operate 方法。

          就设计而言,这意味着社区医院的运作方式与街道医院的运作方式没有区别。

          另一个考虑因素是您实际上想要街道医院的运营,然后在社区医院的运营中需要完成一些细节。对于 CommunityHospital operate 函数应该如下所示:

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

          【讨论】:

            【解决方案7】:

            您正在扩展一个类,但随后覆盖了它的方法。因此,无论何时您调用operate,它都会使用CommunityHospital 中的那个被覆盖的那个。如果删除它,它将从 StreetHospital 类中找到 operate 方法。

            如果出于某种原因您确实需要CommunityHospital 中的operate 方法,请不要实现新方法,只需调用super.operate()。这将调用StreetHospital 类的operate 方法。

            【讨论】:

              【解决方案8】:

              CommunityHospital 覆盖了操作方法,因此如果该类不调用 super 则不可能...

              修改类如:

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

              【讨论】:

                【解决方案9】:

                使用向下转换的概念。 我已经用 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();
                    }
                }
                

                【讨论】:

                • 因为你不能创建一个抽象类的实例,但你可以创建它的引用变量。
                【解决方案10】:

                你可以使用super来做到这一点

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

                如果您不想允许覆盖它,也可以将operate 方法设为final

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

                【讨论】:

                  【解决方案11】:

                  不幸的是,除了在子类中调用super.operate 之外别无他法。

                  在 java 中向上转换不起作用。演示:

                  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();
                      }
                  }
                  

                  打印:

                  B
                  

                  【讨论】:

                    【解决方案12】:

                    只要你不重写操作方法,当你扩展它时,它就会在你的类中可用。

                    因此,在扩展类时不要覆盖类中的操作方法。

                    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");
                        }
                    }
                    

                    这应该可行。

                    【讨论】:

                      猜你喜欢
                      • 1970-01-01
                      • 1970-01-01
                      • 2012-09-21
                      • 1970-01-01
                      • 2023-03-07
                      • 1970-01-01
                      • 2017-05-02
                      • 1970-01-01
                      • 2011-12-26
                      相关资源
                      最近更新 更多