java的继承和多态性

java的继承和多态性,java,Java,我有一个基类Customer的对象数组。它有3个子类Account1、Account2和account3。当我运行一个循环检查每个帐户的类型,然后适当地分配它时,最后我只得到空的数据字段 这样做可能吗 public static int readFile(String filename, Customer[] review)throws IOException{ Scanner scan = new Scanner (new

我有一个基类Customer的对象数组。它有3个子类Account1、Account2和account3。当我运行一个循环检查每个帐户的类型,然后适当地分配它时,最后我只得到空的数据字段

这样做可能吗

                 public static int readFile(String filename, Customer[] review)throws IOException{

                 Scanner scan = new Scanner (new File (filename));

                /*Reading the first record separatly*/
                  Customer first = new Customer();
                  Account1 first1= new Account1();
                  Account2 first2= new Account2();
                  Account3 first3 = new Account3();

                  String[] a = scan.nextLine().split("=");
                  first.set_account_id(Integer.parseInt(a[1].trim()));

                  a = scan.nextLine().split("=");
                  first.set_name(a[1].toUpperCase().trim());

                  a = scan.nextLine().split("=");
                  first.set_address(a[1].trim());
                  a= scan.nextLine().split("=");                                                                  
          first.set_accType(a[1].trim());

                  if (first.get_accType().equals("Saving")){
                      first = first1;
                  }

                  else if(first.get_accType().equals("Checking")){

                      first = first2;
                  }

                 else if(first.get_accType().equals("Fixed")){

                      first = first3;
                      a = scan.nextLine().split("=");
                      first3.set_intRate(Double.parseDouble(a[1].trim()));
                  }

这段代码为我的对象提供了空的数据字段。

您始终可以将子类的对象指定给超类类型的变量,但不能反过来

关于您的编辑版本: 您所做的在语法上是正确的(即编译器不会抱怨),但是它不会做您想做的事情:从您的输入中设置first的特定属性(
first.set_address(a[1].trim())
),但是当您在中覆盖对
first
的引用时,所有这些更改都将“丢失”

              if (first.get_accType().equals("Saving")){
                  first = first1;

您始终可以将子类的对象指定给超类类型的变量,但不能反过来

关于您的编辑版本: 您所做的在语法上是正确的(即编译器不会抱怨),但是它不会做您想做的事情:从您的输入中设置first的特定属性(
first.set_address(a[1].trim())
),但是当您在中覆盖对
first
的引用时,所有这些更改都将“丢失”

              if (first.get_accType().equals("Saving")){
                  first = first1;

简单回答:不会丢失任何数据

简单回答:不会丢失任何数据

您应该构造一个正确类型的对象,然后将其引用为超类(即Customer)的实例,这将允许您设置一些通用值

Customer customer;
if (<insert test to tell if this should be of type Account1>){
     customer = newAccount1();
}
else if (<insert test to tell if this should be of type Account2>){
     customer = newAccount2();
}
else {// I'm assuming all others will be of type Account3, however if this is not the case you'll have to decide what to do
              customer = new Account3(); 
}
customer.setName("abc");
customer.setAdd("xyz new york");
客户;
如果(){
customer=newAccount1();
}
如果(){
customer=newAccount2();
}
否则{//我假设所有其他类型都是Account3,但是如果不是这样,您必须决定要做什么
客户=新账户3();
}
客户名称(“abc”);
customer.setAdd(“xyz纽约”);

您应该构造一个正确类型的对象,然后将其作为超类(即Customer)的实例引用,这将允许您设置一些通用值

Customer customer;
if (<insert test to tell if this should be of type Account1>){
     customer = newAccount1();
}
else if (<insert test to tell if this should be of type Account2>){
     customer = newAccount2();
}
else {// I'm assuming all others will be of type Account3, however if this is not the case you'll have to decide what to do
              customer = new Account3(); 
}
customer.setName("abc");
customer.setAdd("xyz new york");
客户;
如果(){
customer=newAccount1();
}
如果(){
customer=newAccount2();
}
否则{//我假设所有其他类型都是Account3,但是如果不是这样,您必须决定要做什么
客户=新账户3();
}
客户名称(“abc”);
customer.setAdd(“xyz纽约”);

是的,这是可能的。在Java中,您可以使用子类的基类作为类型(也可以赋值)来实例化子类。您可能在没有注意到的情况下使用了它,但是java中的每个类都扩展了
对象
类,因此这样做(例如)是正确的:

Object o = new Integer(12);
这个例子本身是非常无用的,但对于演示目的来说,它是有效的。这种方法是在Java定义中存在泛型之前使用的


希望有帮助

是的,这是可能的。在Java中,您可以使用子类的基类作为类型(也可以赋值)来实例化子类。您可能在没有注意到的情况下使用了它,但是java中的每个类都扩展了
对象
类,因此这样做(例如)是正确的:

Object o = new Integer(12);
这个例子本身是非常无用的,但对于演示目的来说,它是有效的。这种方法是在Java定义中存在泛型之前使用的


希望有帮助

首先,我们必须区分对象和变量。Customer类型的变量可以保存对Customer类型的任何对象或从Customer派生的任何类型的对象的引用。赋值将变量设置为引用不同的对象。赋值根本不会改变对象本身。通过这种推理,分配不会导致数据丢失

现在,您询问是否可以将基类的对象分配给用于保存派生类型的变量,例如
子类obj=new BaseClass()
。无法执行此操作,因为基类的对象不是派生类型的对象。另一种方法是可能的,例如“BaseClass obj=new SubClass()”,因为派生类型的对象是基类的对象

但是,如果有一个变量保存对基类型的引用,并且已将派生类型的对象指定给此变量,则可以使用强制转换将对象指定给派生类型的变量:

BaseClass obj = new SubClass();
Subclass subObj = (SubClass) obj; 
在您的示例中,您可以执行以下操作:

  • 首先创建一个Customer对象并为变量指定一个引用
  • 首先更改变量中引用的客户对象的状态
  • 首先将变量中的引用替换为对Account1对象的引用
  • 这个事件链不会导致预期的结果,我收集的结果是在Account1对象中调用setName和setAdd方法。实际上,赋值
    first=first1
    将在首先通过变量查看时重置情况(对象first和first1的内部状态保持不变)

    你打算做的事情应该如下所示

      private static String nextProperty(Scanner scanner) {
          return scanner.nextLine().split("=").trim()
       }
    
    
       public static int readFile(...) {
          ... 
       final int accountId = Integer.parseInt(nextProperty(scan));
       final String accountName = nextProperty(scan);
       final String accountAddress = nextProperty(scan); 
       final String accountType = nextProperty(scan); 
    
       Customer account = null;
       if(accountType.equals("Saving")) {
          account = new Account1();
       } else if (accountType.equals("Checking")) {
          account =  new Account2();
       } else if (accountType.equals("fixed")) {
          account = new Account3();
          ((Account3)account).set_intRate(Double.parseDouble(nextProperty(scan)));
       } else {
          throw new IllegalStateException("Unexpected account type encountered");
       }
       account.set_account_id(accountId);
       account.set_name(accountName);
       account.set_address(accountAddress);
       account.set_accType(accountType);
       ...
    
      }
    

    首先,我们必须区分对象和变量。Customer类型的变量可以保存对Customer类型的任何对象或从Customer派生的任何类型的对象的引用。赋值将变量设置为引用不同的对象。赋值根本不会改变对象本身。通过这种推理,分配不会导致数据丢失

    现在,您询问是否可以将基类的对象分配给用于保存派生类型的变量,例如
    子类obj=new BaseClass()
    。无法执行此操作,因为基类的对象不是派生类型的对象。另一种方法是可能的,例如“BaseClass obj=new SubClass()”,因为派生类型的对象是基类的对象

    但是,如果您有一个包含对基类型a的引用的变量