首页 > 解决方案 > 是否可以在不初始化超类的情况下从初始化的子类返回超类对象

问题描述

我有以下代码:

public class Person
{
    final String firstName;
    final String lastName;
    final int age;
    final UUID identification;

    public Person(final String firstName, final String lastName, final int age)
    {
        this.firstName = firstName;
        this.lastName = lastName;
        this.age = age;
        this.identification = UUID.randomUUID();
    }

    protected Person(final String firstName, final String lastName, final int age, final UUID identification)
    {
        this.firstName = firstName;
        this.lastName = lastName;
        this.age = age;
        this.identification = identification;
    }

    /*
        Getter functions 
    */

    public Person asPerson()
    {
        return this;
    }

    /*
        Hash and Equals code
        Equals checks for first/lastName, age, and identification
    */
}

public class Employee extends Person
{
    final String occupation;
    final float salary;

    public Employee(final String firstName, final String lastName, final int age, final String occupation, final float salary)
    {
        super(firstName, lastName, age);
        this.occupation = occupation;
        this.salary = salary;
    }

    public Employee(final Person person, final String occupation, final float salary)
    {
        super(person.getFirstName(), person.getLastName, person.getAge(), person.getID());
        this.occupation = occupation;
        this.salary = salary;
    }

    /*
        Getter functions for occupation and salary
    */

    @Override
    public Person asPerson()
    {
        return new Person(firstName, lastName, age, identification);
    }

    /*
        Hash and Equals code
        Equals checks for equality in occupation and salary
    */
}

public class Volunteer extends Person
{
    final String location;

    public Volunteer(final String firstName, final String lastName, final int age, final String location)
    {
        super(firstName, lastName, age);
        this.location = location;
    }

    public Volunteer(final Person person, final String location)
    {
        super(person.getFirstName(), person.getLastName(), person.getAge(), person.getID());
        this.location = location;
    }

    /*
        Getter for location
    */

    @Override
    public Person asPerson()
    {
        return new Person(firstName, lastName, age, identification);
    }

    /*
        Hash and Equals
        Equals checks for equality in location.
    */
}

public Main
{
    public static void main(String[] args)
    {
        final Person person = new Person("Man", "Fredman", 25);
        final Person employee = new Employee(person, "Driver", 65000.0f);
        final Person volunteer = new Volunteer(person, "Philly");

        final boolean eqality = compareVtoE(volunteer, employee);

        System.out.println(equality);
    }

    private boolean compareVtoE(final Person volunteer, final Person employee)
    {
        return volunteer.asPerson().equals(employee.asPerson());
    }
}

已经定义了一个变量,函数中Employee是否有办法返回超类实例而无需调用?asPersonEmployeenew Person(...)

我目前的解决方法是使用受保护的构造函数来接受identification,但我认为有更好的方法来解决这个问题。

编辑

我已经扩展了这个例子。假设我有一个Volunteer和一个Employee,它既可以扩展Person又可以在Person构造函数中接收一个对象。他们可以是同一个人,但做不同的事情。要查看一个志愿者是否与员工相同,我需要一种获取Person对象的方法,而无需更改 UUID。我的解决方法是使用一个受保护的构造函数,Person它接受 UUID,在子类构造函数中使用super. 我想避免在 中使用构造函数asPerson(),创建 的新实例Person

标签: java

解决方案


我很确定没有办法做你所要求的,因为它需要改变对象而不改变它,但这里有两种可能的解决方案来解决你的比较问题:

  1. 重写类中的equals方法,Person以便您可以比较不同角色(员工或志愿者)的人:

    @Override
    public boolean equals(Object other) {
        if (other instanceof Person) {
            return identification.equals(((Person)other).identification);
        }
    
        return false;
    }
    
  2. 如果由于某种原因你不能使用equals,例如你需要在具有不同功能的派生类中覆盖它,只需创建一个isSamePerson这样的函数:

    public boolean isSamePerson(Person other) {
        if (other != null) return identification.equals(other.identification);
        return false;
    }
    

这将为您节省不必要的对象重复,以及丢失人迹的危险。


推荐阅读