【问题标题】:Java Inheritance: Calling a subclass method in a superclassJava继承:在超类中调用子类方法
【发布时间】:2017-06-17 12:33:11
【问题描述】:

我是 java 新手,想知道在超类中调用子类方法是否可行。如果进行继承,那么设置 public static void main 的合适位置在哪里。

超类

public class User {
    private String name;
    private int age;

    public User() {
        //Constructor
    }

    //Overloaded constructor
    public User(String name, int age) {
        this.name = name; 
        this.age = age;
    }

    public String getName() {
        return this.name;
    }
    public static void main(String []args) {
        User user1 = new Admin("Bill", 18, 2); 

        System.out.println("Hello "+user1.getName()); 
        user1.getLevel();
    }

}

子类

public class Admin extends User {

    private int permissionLevel;

    public Admin() {
    //Constructor 
    }

    //Overloading constructor
    public Admin(String name, int age, int permissionLevel) {
        super(name, age); 
        this.permissionLevel = permissionLevel;
    }

    public void getLevel() {
        System.out.println("Hello "+permissionLevel);

    }

}

【问题讨论】:

  • 不,这不可能。一个类无法知道它是否或何时被子类化。用户并不总是管理员,而是管理员 IS-A 用户。管理员可以调用父方法,但不能反过来,除非您将用户引用转换为管理员。
  • 我养成了将 main 方法放在所有“功能”类之外的习惯。在您的示例中,我将创建一个类 Functionality,它包含 main 方法和您的两个额外类。如果您的程序有一天可能会提供与用户无关的功能怎么办。最简单的用例可能是显示帮助文本——这不适合 User 类,不是吗?
  • 乍一看,似乎为了调用user1.getLevel(),您需要像Admin user1 一样声明user1,或者像((Admin) user1).getLevel() 一样转换user1

标签: java inheritance


【解决方案1】:

我是java新手,想知道是否调用子类 超类中的方法是可能的。

超类对其子类一无所知,因此,您不能在超类中调用子类的instance方法。

哪里是设置 public static void main 的合适位置。

我不建议将main 方法放在Admin 类或User 类中,因为很多因素。而是创建一个单独的类来封装main 方法。

例子:

public class Main{
   public static void main(String []args) {
        User user1 = new Admin("Bill", 18, 2); 

        System.out.println("Hello "+user1.getName()); 
        user1.getLevel();
    }
}

【讨论】:

  • 如果我正确理解了这个问题,那么问题似乎是关于超类中包含的static 方法,在这种情况下,当然可以调用子类的方法。如果你试图在超类的this 上调用子类方法,这是不可能的。
【解决方案2】:

简短回答:不。

中等答案:是的,但是您必须在超类中声明该方法。然后在子类中覆盖它。子类中的方法体将在超类调用时被调用。在您的示例中,您可以在 User 上放置一个空的 getLevel 方法。

您还可以考虑将 User 声明为抽象类,并将 getLevel 方法声明为 User 类的抽象。这意味着您不会将任何方法主体放在 User 类的 getLevel 中,但每个子类都必须包含一个。同时,User 可以引用 getLevel 并使用其子类的实现。我认为这就是你要在这里的行为。

【讨论】:

    【解决方案3】:

    ,不能在超类内部调用子类方法。

    虽然可以在客户端代码中调用同一方法的不同实现,而您有一个具有超类类型的变量并使用超类或子类对象实例化它。它被称为多态

    请考虑以下示例:

    public class User {
        private String name;
        private int age;
        protected int permissionLevel;
    
        public User() {
            //Constructor
        }
    
        //Overloaded constructor
        public User(String name, int age) {
            this.name = name;
            this.age = age;
        }
    
        public String getName() {
            return this.name;
        }
    
        public void getLevel() {
            System.out.println("Hello "+ permissionLevel);
        }
    }
    
    public class Admin extends User {
    
        public Admin() {
            //Constructor
        }
    
        //Overloading constructor
        public Admin(String name, int age, int permissionLevel) {
            super(name, age);
            this.permissionLevel = permissionLevel;
        }
    
        @Override
        public void getLevel() {
            System.out.println("Hello "+permissionLevel);
        }
    
        public static void main(String []args) {
            User user1 = new Admin("Bill", 18, 2);
    
            System.out.println("Hello "+user1.getName());
            user1.getLevel(); //call to subclass method
    
            user1 = new User("John", 22); //the variable is the same but we assign different object to it
            user1.getLevel(); //call to superclass method
        }
    }
    

    回答您的第二个问题,不,只要它具有正确的方法签名,您将主要方法放在哪里都没有关系。正如您在我的示例中看到的,我将该方法移至 Admin.java - 它仍然可以接受。

    【讨论】:

      【解决方案4】:

      在超类中调用子类方法是可能的,但在超类变量/实例上调用子类方法是不可能的。

      在 java 中,所有静态变量和方法都被认为是在类之外,即它们确实可以访问任何实例变量或方法。在您上面的示例中,明智的做法是创建一个名为 Main 的新类并将 public static void main 放在那里,但这只是一个卫生问题,您上面的内容除了行之外都可以工作。

      user1.getLevel()
      

      【讨论】:

        【解决方案5】:

        用例:如果员工吃饭,那么应该自动睡觉:-)

        1. 从类person 中声明两个方法eatsleep。 从eat 调用sleep 方法。

        2. employee 类中扩展person 并仅覆盖sleep 方法:

          Person emp=new Employee();
          emp.eat();
          

        解释:由于eat方法不在子类中,它会调用超类eat。从那里,子类的sleep 将被调用。

        【讨论】:

          猜你喜欢
          • 2011-10-17
          • 2021-05-04
          • 1970-01-01
          • 2018-01-05
          • 1970-01-01
          • 2012-05-11
          • 2023-03-23
          • 1970-01-01
          • 2015-01-14
          相关资源
          最近更新 更多