从父类变量调用子类方法,而不使用 instanceof 或强制转换 [duplicate]

Call a child class method from a parent class variable without using instanceof or casting [duplicate]

提问人:Mohamed Amir 提问时间:11/14/2023 最后编辑:Mohamed Amir 更新时间:11/14/2023 访问量:100

问:

我有4个班级

public class User {
    private Account account;

    public void setAccount(Account account) {
        this.account = account;
    }

    public Account getAccount() {
        return this.account;
    }
}
public abstract class Account {
    private double balance;
    private String password;
    private String userName;
    private String mobileNumber;
    private Provider provider;
// some getters and setters
    
}
public class BankAccount extends Account {
 
        // this not in the parent class
    private String accountNumber;

    public String getAccountNumber() {
        return accountNumber;
    }

    
    public void setAccountNumber(String accountNumber) {
        this.accountNumber = accountNumber ;
    }
}
public class WalletAccount extends Account {

}

我如何重新设计它以制作成这样

Account account = new BankAcccount() ;
account.getAccountNumber() ;

无需使用或铸造instanceof

((BankAccount) account)getAccountNumber() ;

重新设计类以允许调用方法,而无需使用或强制转换设计模式,或者添加更多类的任何方法。BankAccountinstanceof

Java OOP 继承 多态性

评论

0赞 Grinding For Reputation 11/14/2023
你能添加一个新的类/接口吗?

答:

1赞 Louis Wasserman 11/14/2023 #1

你不能。没有办法这样做。只有某种类型的东西 - 必须被投射到它身上 - 才能调用它。BankAccountgetAccountNumber()

评论

0赞 Mohamed Amir 11/14/2023
连设计模式都解决不了?
0赞 Louis Wasserman 11/14/2023
不。如果只有函数,则只能在 上调用该函数。BankAccountgetAccountNumberBankAccount
0赞 Roman C 11/14/2023 #2

在简单情况下,您可以向父类添加方法。abstract

public abstract class Account {
    private double balance;
    private String password;
    private String userName;
    private String mobileNumber;
    private Provider provider;
// some getters and setters
    public abstract String getAccountNumber();
}

这使得属性是抽象的。每个非抽象子类都应该实现类的抽象方法。accountNumberAccount

然后你可以使用

Account account = new BankAcccount() ;
account.getAccountNumber() ;

无需使用或铸造instanceof

((BankAccount) account)getAccountNumber() ;

这是允许的,因为方法可以使用多态性abstract


另一种方法是使用接口来访问某个子类的属性。如果另一个子类没有这样的属性,它可能不会实现这个接口。当您需要访问该属性时,您可以向上转换到没有 .instanceof

public interface AccountNumberAware {
  public String getAccountNumber();
}

public abstract class Account implements AccountNumberAware {
    private double balance;
    private String password;
    private String userName;
    private String mobileNumber;
    private Provider provider;
// some getters and setters

    // dummy implementation of interface
    public String getAccountNumber() {
        return null;
    }
    
}
public class BankAccount extends Account {
 
        // this not in the parent class
    private String accountNumber;

    public String getAccountNumber() {
        return accountNumber;
    }

    
    public void setAccountNumber(String accountNumber) {
        this.accountNumber = accountNumber ;
    }
}

然后你可以使用

Account account = new BankAcccount() ;
account.getAccountNumber() ;

评论

0赞 Mohamed Amir 11/14/2023
但类 WalletAccount 没有帐号
0赞 Roman C 11/14/2023
它必须有一个帐号,因为它是扩展的和抽象的。我已经添加了它,它被继承了。AccountgetAccountNumber()AccoutWalletAccount
0赞 Mohamed Amir 11/14/2023
在 BankAccount 类中它表示的银行帐号,在提供商中,钱包没有银行,因此它没有银行帐号
0赞 Roman C 11/14/2023
如果它没有帐号,则不应扩展。此类提供了一个属性。所以这个数字将包含所有子类。我们不能为特定类继承此属性,因此它被继承给所有类。AccountaccountNumber
0赞 Roman C 11/14/2023
您已经询问了如何在不强制转换的情况下从父类调用子方法。仅当父类在子类中覆盖了虚拟方法时,才有可能。您应该同时拥有 in 和 。不管你如何实现它,它都应该被覆盖。尝试从方法中删除,然后不必实现它。类变量仅属于 ,因此它不能用于其他子级,但在运行时可用于父级,因为父级是实例的子级。getAcvountNumber()AccountBankAccountabstractWalletAccountBankAccount
0赞 Reilas 11/14/2023 #3

从技术上讲,不应期望 Account 具有 getAccountNumber 方法。

请尝试以下操作。

abstract class Account {
    private double balance;
    private String password;
    private String userName;
    private String mobileNumber;
    private Provider provider;

    String getAccountNumber() {
        return 
            this instanceof BankAccount 
                ? ((BankAccount) this).getAccountNumber() 
                : null;
    }
}