Java 需要将子类对象类型转换为访问子类方法的子类

Java 需要将子类对象类型转换为访问子类方法的子类,java,inheritance,Java,Inheritance,这是(节略的)超级类: public class Account { private double bal; //The current balance private int accnum; //The account number public Account(int a) { bal=0.0; accnum=a; } } 子类: public class SavingsAccount extends

这是(节略的)超级类:

public class Account
{
    private double bal;  //The current balance
    private int accnum;  //The account number


    public Account(int a)
    {    
        bal=0.0;
        accnum=a;
    }
}
子类:

public class SavingsAccount extends Account{

    private static final double INTEREST_RATE = 5;  // Interest amount for savings account

    public SavingsAccount(int a) {
        super(a);
    }

    public void addInterest(){
        double interest = getBalance()/100*INTEREST_RATE;
        deposit(interest);
    }
}
以及主要代码:

public class AccountMain {

    public static void main(String[] args) {
        // Declare Variables
        Account myAccount = new SavingsAccount(500);

        // Do stuff
        myAccount.deposit(1000);
        System.out.println(myAccount.toString());
        ((SavingsAccount) myAccount).addInterest();
        System.out.println(myAccount.toString());
    }

}
当我的账户被声明为SavingsAccount时,为什么我必须将其转换为SavingsAccount

我读过的所有内容都暗示,通过将新对象声明为子类,应该可以使用所有的超类和子类方法。我觉得我错过了什么,但找不到什么

当我的账户被声明为SavingsAccount时,为什么我必须将其转换为SavingsAccount

以下是变量声明部分:

Account myAccount;
这就是编译器理解变量类型的方式

以下是作业部分:

myAccount = new SavingsAccount(500);
这是为变量指定特定对象引用的地方。请注意,它不会也不能更改声明的类型

因此,您可以看到myAccount变量最明确的定义是不是声明的SavingsAccount类型变量。它已声明为帐户类型变量,该变量已分配给SavingsAccount类型对象。您也可以稍后将赋值更改为另一个Account类型对象,因此为了类型安全,如果希望将变量用作更具体的类型,编译器将要求您强制转换该变量

当我的账户被声明为SavingsAccount时,为什么我必须将其转换为SavingsAccount

以下是变量声明部分:

Account myAccount;
这就是编译器理解变量类型的方式

以下是作业部分:

myAccount = new SavingsAccount(500);
这是为变量指定特定对象引用的地方。请注意,它不会也不能更改声明的类型

因此,您可以看到myAccount变量最明确的定义是不是声明的SavingsAccount类型变量。它已声明为帐户类型变量,该变量已分配给SavingsAccount类型对象。您也可以稍后将赋值更改为另一个Account类型对象,因此为了类型安全,如果希望将变量用作更具体的类型,编译器将要求您强制转换该变量

当我的账户被声明为SavingsAccount时,为什么我必须将其转换为SavingsAccount

以下是变量声明部分:

Account myAccount;
这就是编译器理解变量类型的方式

以下是作业部分:

myAccount = new SavingsAccount(500);
这是为变量指定特定对象引用的地方。请注意,它不会也不能更改声明的类型

因此,您可以看到myAccount变量最明确的定义是不是声明的SavingsAccount类型变量。它已声明为帐户类型变量,该变量已分配给SavingsAccount类型对象。您也可以稍后将赋值更改为另一个Account类型对象,因此为了类型安全,如果希望将变量用作更具体的类型,编译器将要求您强制转换该变量

当我的账户被声明为SavingsAccount时,为什么我必须将其转换为SavingsAccount

以下是变量声明部分:

Account myAccount;
这就是编译器理解变量类型的方式

以下是作业部分:

myAccount = new SavingsAccount(500);
这是为变量指定特定对象引用的地方。请注意,它不会也不能更改声明的类型


因此,您可以看到myAccount变量最明确的定义是不是声明的SavingsAccount类型变量。它已声明为帐户类型变量,该变量已分配给SavingsAccount类型对象。您也可以稍后将分配更改为另一个帐户类型对象,因此,为了类型安全,如果要将变量用作更具体的类型,编译器将要求您强制转换该变量。

这实际上是多态性的行为-myAccount对象仅在运行时被视为SavingsAccount。简言之:

MyClass a = new MyClass(); // 'a' type is considered as MyClass in both development & runtime
MySuper b = new MyClass(); // 'b' type is MySuper on development and MyClass on runtime
除非您正在使用集合,否则实际上不需要以这种方式声明对象。但如果需要收集,您可以:

  • 将整个集合声明为所需的类型
  • 或者改用接口(如果需要使用与继承无关的公共特性)

  • 这实际上就是多态性的行为-只有在运行时,myAccount对象才会被视为SavingsAccount。简言之:

    MyClass a = new MyClass(); // 'a' type is considered as MyClass in both development & runtime
    MySuper b = new MyClass(); // 'b' type is MySuper on development and MyClass on runtime
    
    除非您正在使用集合,否则实际上不需要以这种方式声明对象。但如果需要收集,您可以:

  • 将整个集合声明为所需的类型
  • 或者改用接口(如果需要使用与继承无关的公共特性)

  • 这实际上就是多态性的行为-只有在运行时,myAccount对象才会被视为SavingsAccount。简言之:

    MyClass a = new MyClass(); // 'a' type is considered as MyClass in both development & runtime
    MySuper b = new MyClass(); // 'b' type is MySuper on development and MyClass on runtime
    
    除非您正在使用集合,否则实际上不需要以这种方式声明对象。但如果需要收集,您可以:

  • 将整个集合声明为所需的类型
  • 或者改用接口(如果需要使用与继承无关的公共特性)

  • 这实际上就是多态性的行为-只有在运行时,myAccount对象才会被视为SavingsAccount。简言之:

    MyClass a = new MyClass(); // 'a' type is considered as MyClass in both development & runtime
    MySuper b = new MyClass(); // 'b' type is MySuper on development and MyClass on runtime
    
    除非您正在使用集合,否则实际上不需要以这种方式声明对象。但如果需要收集,您可以:

  • 将整个集合声明为所需的类型
  • 或者改用接口(如果需要使用与继承无关的公共特性)