黑马程序员技术交流社区

标题: 一个关于抽象类的问题 [打印本页]

作者: 王晓新    时间: 2012-6-15 23:12
标题: 一个关于抽象类的问题
本帖最后由 王晓新 于 2012-6-15 23:46 编辑
  1. abstract class  Employee
  2. {
  3.         private String name;
  4.         private String id;
  5.         private double pay;
  6.         Employee(){}          [color=Red]//这条注释掉就会出现错误[/color]
  7.         Employee(String name,String id,double pay)
  8.         {
  9.                 this.name=name;
  10.                 this.id=id;
  11.                 this.pay=pay;
  12.         }
  13.         public abstract void work();
  14. }
  15. class Manager extends Employee //经理类
  16. {
  17.         private int bonus;
  18.         Manager(){}
  19.         Manager(String name,String id,double pay,int bonnus)
  20.         {
  21.                 super(name,id,pay);
  22.                 this.bonus=bonus;
  23.         }
  24.         public void work()
  25.         {
  26.                 System.out.println("Manager work");
  27.         }
  28. }
  29. class Pro extends Employee  //普通员工类
  30. {
  31.         Pro(){}
  32.         Pro(String name,String id,double pay)
  33.         {
  34.                 super(name,id,pay);
  35.         }
  36.         public void work()
  37.         {
  38.                 System.out.println("Pro work");
  39.         }
  40. }
  41. class AbstractTest
  42. {
  43.         public static void main(String[] args)
  44.         {
  45.                 new Manager().work();
  46.                 Pro p=new Pro();
  47.                 p.work();
  48.         }
  49. }
复制代码
我不理解为什么当抽象类里的无参构造函数去掉之后就会出错,难道在子类中定义的无参构造函数不会初始化对象么?还是说子类的属性(除了bonus)都是从父类继承的,所以必须继承父类的无参构造函数来初始化对象?
作者: 张_涛    时间: 2012-6-15 23:23
只要在程序中创建Java对象,系统总是先调用最顶层父类构造器,然后依次向下调用所有父类的初始化操作,最终执行本类的初始化操作返回本类的实例。
当子类构造器执行体中既没有super调用,也没有this调用,系统将会在执行子类构造器之前,隐式调用父类无参数的构造器。
而当你注释Employee(){} ,系统将找不到父类的无参数的构造器,因此报错。
作者: 张_涛    时间: 2012-6-15 23:29
当有super调用和this调用的情况:
1. 子类构造器的执行体的第一行代码使用super显示调用父类构造器,系统将根据super调用里传入的参数列表来确定调用父类的哪个构造器;
2. 子类构造器执行体的第一行代码使用this显示调用本类中重载的构造器,系统将根据this调用里传入的实参列表来确定本类的另一个构造器(执行本类的另一个构造器时即进入第一种情况)
作者: 李盼    时间: 2012-6-15 23:31
在创建子类对象的时候,会先创建父类对象,这个过程是由子类构造方法中调用父类构造方法实现的,如果你没在子类构造方法的第一句调用父类构造方法,那么系统默认你调用了父类无参的构造方法。
但是你父类你不写构造方法,系统会默认给你加一个无参构造方法,但是你写了有参构造方法,系统就不会给你加无参构造方法,而此时子类要创建对象,找不到父类无参的构造方法,所以出错,这个跟抽象类是没关系的!
作者: 王晓新    时间: 2012-6-15 23:38
哎呀,多谢楼上几位哥们的提醒,把这么关键的地方忘了。。谢谢
作者: 郑冬    时间: 2012-6-15 23:48
子类构造器调用父类构造器分如下几种情况:
1.子类构造器执行体的第一行使用super显示调用父类构造器,系统将根据super调用里传入的实参列表调用父类对应的构造器
2.子类构造器执行体的第一行代码使用this显示调用本类中重载的构造器,系统将根据this调用里传入的实参列表调用本类另一个构造器,执行本类中另一个构造器时即会调用父类的构造器
3.子类构造器执行体中既没有super调用,也没有this调用,系统将会在执行子类构造器之前隐式调用父类无参数的构造器,所以如果注释掉了父类的无参数构造器,肯定会报错
作者: 胡卿    时间: 2012-6-16 00:45
  1. abstract class  Employee
  2. {
  3.         private String name;
  4.         private String id;
  5.         private double pay;
  6.         Employee(){}          [color=Red]//这条注释掉就会出现错误[/color]
  7.         Employee(String name,String id,double pay)
  8.         {
  9.                 this.name=name;
  10.                 this.id=id;
  11.                 this.pay=pay;
  12.         }
  13.         public abstract void work();
  14. }
  15. class Manager extends Employee //经理类
  16. {
  17.         //super();  这里省略了这条语句,子类初始化时默认调用父类中空参数构造函数,如果你改成super(String name,String id,double pay),那么就没问题了
  18.         private int bonus;
  19.         Manager(){}
  20.         Manager(String name,String id,double pay,int bonnus)
  21.         {
  22.                 super(name,id,pay);
  23.                 this.bonus=bonus;
  24.         }
  25.         public void work()
  26.         {
  27.                 System.out.println("Manager work");
  28.         }
  29. }
  30. class Pro extends Employee  //普通员工类
  31. {
  32.         Pro(){}
  33.         Pro(String name,String id,double pay)
  34.         {
  35.                 super(name,id,pay);
  36.         }
  37.         public void work()
  38.         {
  39.                 System.out.println("Pro work");
  40.         }
  41. }
  42. class AbstractTest
  43. {
  44.         public static void main(String[] args)
  45.         {
  46.                 new Manager().work();
  47.                 Pro p=new Pro();
  48.                 p.work();
  49.         }
  50. }
复制代码





欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2