【问题标题】:How do I make instances of different child classes have the same instance of their common parent class?如何使不同子类的实例具有其公共父类的相同实例?
【发布时间】:2022-01-18 12:33:25
【问题描述】:

问题陈述:学习环境包含学生员工,他们具有共同的属性,因为他们都是在某些机构中,学生也可能同时作为员工工作。上述面向对象编程中所述的含义是:

  • Student 继承 Person
  • Staff 继承 Person
  • 在某些情况下,Student 对象和 Staff 对象都应构建在同一个 Person 实例上(即共享同一个父类实例)

如何使用 OOP 实现列表中的最后一个含义? (最好是 C#、Java、C++ 或 Python)

【问题讨论】:

  • 你没有。每个实例都是其自身的实例。您描述的是组合,而不是继承
  • 是您在问题陈述中列出的含义还是您自己的解释?
  • @Angela Lopez 前两个基于 OOP 的传统规则。第三个是我个人认为所描述的 seinario 应该如何实现,但我对其他建议持开放态度。

标签: java c# oop inheritance ooad


【解决方案1】:

我认为继承不是解决问题的正确方法。 StudentStaff 有必要是不同的类吗?

学生或工作人员只是Person 的实例似乎更合适,并且有一个成员属性role 可能包含"Student""Staff" 或两者兼有。

【讨论】:

    【解决方案2】:

    使用接口 IPerson(解释继承更广泛)你可以在 Java 中做这样的事情 (很接近但可能没有雪茄):

    public interface IPerson
    {
    
        default String getName() {
            return getPerson().getName();
        };
    
        default void setName(String name) {
            getPerson().setName(name);
        }
    
        IPerson getPerson();
    
    }
    
    public class Person implements IPerson
    {
    
        private String name;
    
        @Override
        public String getName()
        {
            return name;
        }
    
        @Override
        public void setName(String name)
        {
            this.name = name;
    
        }
    
        public IPerson getPerson() {
            return this;
        }
    }
    
    public class Staff implements IPerson
    {
    
        private Person person;
    
        private String socialInsuranceNumber;
    
        public String getSocialInsuranceNumber()
        {
            return socialInsuranceNumber;
        }
    
        public void setSocialInsuranceNumber(String socialInsuranceNumber)
        {
            this.socialInsuranceNumber = socialInsuranceNumber;
        }
    
        public Staff(Person person)
        {
            super();
            this.person = person;
        }
    
        @Override
        public IPerson getPerson()
        {
            return person;
        }
    
    }
    
    public class Student implements IPerson
    {
    
        private Person person;
    
        private String matriculationNumber;
    
        public String getMatriculationNumber()
        {
            return matriculationNumber;
        }
    
        public void setMatriculationNumber(String matriculationNumber)
        {
            this.matriculationNumber = matriculationNumber;
        }
    
        public Student(Person person)
        {
            super();
            this.person = person;
        }
    
        @Override
        public IPerson getPerson()
        {
            return person;
        }
    
        public static void main(String[] args) {
            Person peterP = new Person();
            peterP.setName("Peter");
    
            Staff peterStaff = new Staff(peterP);
            peterStaff.setSocialInsuranceNumber("123");
    
            Student peterStudent = new Student(peterP);
            peterStudent.setMatriculationNumber("456");
    
            peterStudent.setName("Dr. Peter");
    
            System.out.println(peterStaff.getName());
    
        }
    
    }
    

    如果不使用接口,您可以覆盖所有 getter、setter 等并将其委托给 Person(忽略子类中的字段,也不好。这是伪装成继承的组合):

    public class Student extends Person
    {
    
        private Person person;
    
        private String matriculationNumber;
    
        public String getMatriculationNumber()
        {
            return matriculationNumber;
        }
    
        public void setMatriculationNumber(String matriculationNumber)
        {
            this.matriculationNumber = matriculationNumber;
        }
    
        public Student(Person person)
        {
            super();
            this.person = person;
        }
    
        @Override
        public String getName()
        {
            return person.getName();
        }
    
        @Override
        public void setName(String name)
        {
            person.setName(name);
        }
    
    }
    

    【讨论】:

      【解决方案3】:

      java中只能继承单个类,不能有class WorkingStudent extends Student, Staff。但是你可以实现多个接口,所以我会向你推荐一个带接口的解决方案。首先让我们定义学生功能。学生必须学习,所以:

          public interface Student {
              
              void study();
          }
      

      现在对于员工来说,他显然必须工作,所以:

          public interface Staff {
      
              void work();
          }
      

      一个非常简单的person类:

          public class Person {
      
              private final String name;
      
      
              public Person(String name) {
                  this.name = name;
              }
      
              public String getName() {
                  return this.name;
              }
          }
      

      普通学生只是学习或不学习,谁知道呢,但我们假设他学习了。他是一个人,也做学生的事情。

          public class NormalStudent extends Person implements Student {
      
              public NormalStudent(String name) {
                  super(name);
              }
      
              @Override
              public void study() {
                  System.out.println(getName() + " studies a lot.");
              }
          }
      

      还有你的普通员工,他们没有尽职尽责。他是一个人,他做员工的事情。

          public class NormalStaff extends Person implements Staff {
      
              public NormalStaff(String name) {
                  super(name);
              }
      
              @Override
              public void work() {
                  System.out.println(getName() + " does whatever the staff does");
              }
          }
      

      现在对于同时也是工作人员的学生:

          public class WorkingStudent extends NormalStudent implements Staff {
      
              public WorkingStudent(String name) {
                  super(name);
              }
      
              @Override
              public void work() {
                  System.out.println(getName() + " has finished studying, but does not go to the party and instead does his obligations as a staff member of his university.");
                  System.out.println(getName() + " has a bright future ahead of him. Probably.");
              }
          }
      

      WorkingStudent 是一个 NormalStudent,也是一个 Person(他从 NormalStudent 继承了 Student 的功能和 Person 的属性),并实现了 Staff 从而获得了相应的功能。

      还有一个小例子:

          NormalStudent james = new NormalStudent("James");
          james.study();
          WorkingStudent george = new WorkingStudent("George");
          george.study();
          george.work();
          NormalStaff john = new NormalStaff("John");
          john.work();
      

      【讨论】:

        猜你喜欢
        • 2020-02-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-06-10
        • 2020-06-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多