简体   繁体   English

用相同的附加字段包装不同的子类

[英]Wrap different subclasses with same additional field

Let's say I have some abstract class User , and then subclasses Owner and Client . 假设我有一些抽象类User ,然后子类OwnerClient Each of the two subclasses have some specific fields, but they both inherit common fields from the User . 这两个子类中的每一个都有一些特定的字段,但是它们都从User继承了公共字段。 This is all OK, but in a specific situation I'd like to be able to wrap any instance of User with another field. 没关系,但是在特定情况下,我希望能够用另一个字段包装User任何实例。 Here is the example. 这是例子。

User.java User.java

public abstract class User {

    private String email;

    private String password;

    private String name;

}

Client.java Client.java

public class Client extends User {

    private String salary;

    private String profit;

}

Owner.java Owner.java

public class Owner extends User {

    private int numberOfClients;

    private double averageClientSalary;

}

Now in a specific case, I'd like to be able to wrap such instances with a login token. 现在在特定情况下,我希望能够使用登录令牌包装此类实例。 So no matter if it is a Client or the Owner instance, it should receive another field loginToken on top of all it's fields. 因此,无论是Client实例还是Owner实例,它都应该在其所有字段loginToken接收另一个字段loginToken

The use-case would be something like this. 用例将是这样的。

Client client = new Client(email, password, name, salary, profit);

String loginToken = "123abc456";

UserLogin clientLogin = new UserLogin(client);
clientLogin.setLoginToken(loginToken);

// now this should be possible
clientLogin.getEmail(); // base class field
clientLogin.getSalary(); // derived class field
clientLogin.getLoginToken(); // field from a wrapper

So this UserLogin should be able to receive any subclass of User as constructor argument, and remain all of it's fields, just add the extra one, ie. 因此,此UserLogin应该能够接收User任何子类作为构造函数参数,并保留其所有字段,只需添加额外的一个即可。 loginToken . loginToken

Would something like this be possible and how? 这样的事情有可能吗?

Basically, what would the UserLogin class look like? 基本上, UserLogin类是什么样的?

For base class fields and wrapper class fields (or to be precise getters as private fields are not accessible from subclasses) , you can add delegation methods in the wrapper UserLogin class. 对于基类字段和包装器类字段(或者确切地说是获取器,因为不能从子类访问private字段),可以在包装器UserLogin类中添加委派方法。
But you could not use getters of the subclass as the wrapper manipulates a User declared variable. 但是您不能使用子类的getters,因为包装器会处理User声明的变量。

public class UserLogin {

    private User user;
    private String token;

    public UserLogin(User user, String token) {
        this.user = user;
        this.token = token;
    }

    public String getEmail() {
        return user.getEmail();
    }    

    public String getLoginToken() {
        return token;
    }

    // not possible for derived fields
    public String getSalary() {
        return user.getSalary();
    }

}

As workaround to do such a thing you could make UserLogin a generic class that provides a method that returns an instance of the specific User class. 作为解决此问题的方法,您可以使UserLogin为通用类,该通用类提供一种返回特定User类实例的方法。

For example : 例如 :

public class UserLogin<T extends User> {

    private T user;
    private String token;

    public UserLogin(T user, String token) {
        this.user = user;
        this.token = token;
    }

    public String getEmail() {
        return user.getEmail();
    }

    public T getConcreteUser() {
        return user;
    }

    public String getLoginToken() {
        return token;
    }    

}

You can now invoke : 您现在可以调用:

UserLogin<Client> clientLogin = new UserLogin<>(new Client(), "token");

clientLogin.getEmail(); 
clientLogin.getConcreteUser()
           .getSalary(); 
clientLogin.getLoginToken(); 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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