A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 赵家阳 中级黑马   /  2012-9-14 15:33  /  1933 人查看  /  9 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 赵家阳 于 2012-9-14 21:43 编辑
  1. abstract class Worker{
  2.         private String name;
  3.         private int age;
  4.         private double pay;
  5.         Worker(String name,int age,double pay){        //构造函数
  6.                  
  7.                 this.name = name;
  8.                 this.age = age;
  9.                 this.pay = pay;
  10.         }
  11.         abstract void work();//该方法必须被重写
  12.         void sleep(){
  13.                
  14.         }
  15. }
  16. class Manager extends Worker{
  17.         private int bonus;
  18.         Manager(String name,int age,double pay,int bonus){
  19.                 this.name = name;    //为什么会出错??
  20.                 this.age = age;        //为什么会出错??
  21.                 this.pay = pay;       //为什么会出错??
  22.                 this.bonus = bonus;
  23.         }
  24.         public void work(){
  25.                 System.out.println("working"+bonus);
  26.         }
  27. }
复制代码
疑问:为什么子类在继承这个抽象类时如果不声明构造函数会报错,而不声明sleep方法会没事?请高手赐教!
      还有,在子类的构造函数中为什么不能使用this.name,this.age,this.pay?

评分

参与人数 1技术分 +1 收起 理由
王德升 + 1 赞一个!

查看全部评分

9 个回复

正序浏览
比较地道的写法是这样:
Manager(String name, int age, double pay,int bonus) {      
                super(name,age,pay);
                this.bonus = bonus;
        }
如果非得像上面这么写,提升抽象类中变量的访问权限,因为private型变量,子类继承后在子类的方法体中是没有访问权限的即时使用关键字super,
这里还有一个潜意识影藏的错误,就是在调用子类的构造方法时,要么显示调用父类的构造方法,如果没有显示调用就会调用无参数的构造方法所以可以这么写:

abstract class Worker{
        protected String name;
        public int age;
        public double pay;

        Worker(String name,int age,double pay){        //构造函数
                 
                this.name = name;
                this.age = age;
                this.pay = pay;
        }
       Worker()  //无参构造方法
        {
               
        }
        abstract void work();//该方法必须被重写
        void sleep(){
               
        }
}
public class Manager extends Worker{
        Manager(String name, int age, double pay,int bonus) {   
                this.name = name;
                this.age = age;
                this.bonus = bonus;
        }

                private int bonus;

        public void work(){
                System.out.println("working"+bonus);
        }
}
回复 使用道具 举报
本帖最后由 廖智 于 2012-9-14 21:28 编辑
郭阳 发表于 2012-9-14 20:42
第一个问题
work方法后面没有大括号,换句话说就是没有具体的执行方法,所以是抽象的,所以必须要声明,否 ...

abstract class Worker{
private String name;
private int age;
private double pay;
Worker(String name,int age,double pay){ -----(1)子类初始化

this.name = name;
this.age = age;
this.pay = pay;
}
abstract void work();//该方法必须被重写
void sleep(){

}
}
class Manager extends Worker{
private int bonus;
Manager(String name,int age,double pay,int bonus){ ----(2)父类初始化。 子类继承父类,所以继承了父类中的name,age,pay,只要用super来调用父类的构造函数就行了。
//super.name = name; (3)-----这里改为super(name,age,pay)
                                                              this.bonus = bonus;
//super.age = age;
//this.pay = pay;
//this.bonus = bonus;
}
public void work(){
System.out.println("working"+bonus);
}
}
public class AbstractTest {
public static void main(String[] args){

}
}
答疑:为什么子类在继承这个抽象类时如果不声明构造函数会报错?
     答: 子类必须有构造方法,因为要进行初始化。
  
      还有,在子类的构造函数中为什么不能使用this.name,this.age,this.pay?

      答: 因为子类已经继承了父类中的name ,age,pay属性了,所以只要用super调用父类的构造方法就行了。
回复 使用道具 举报
谢谢给位大侠!该问题已解决!{:soso_e189:}
回复 使用道具 举报
郭阳 中级黑马 2012-9-14 20:42:21
8#
第一个问题
work方法后面没有大括号,换句话说就是没有具体的执行方法,所以是抽象的,所以必须要声明,否则报错
sleep方法不知道你是漏掉了还是怎么,后面是有大括号的,也就是说有执行方法,只不过为空而已,所以这个方法不是抽象方法,不能声明!(不是你说的不声明也不报错)

————————————————————————————————————————————————————————————————————————————
第二个问题
子类继承父类的变量的时候,该变量存在于对象中的父类区域,如果你在子类中定义一个同名变量,就可以用this和super来区分了。
回复 使用道具 举报
abstract class Worker{
private String name;
private int age;
private double pay;
Worker(String name,int age,double pay){//2

this.name = name;
this.age = age;
this.pay = pay;
}
abstract void work();//该方法必须被重写
void sleep(){

}
}
class Manager extends Worker{
private int bonus;
Manager(String name,int age,double pay,int bonus){//3
super(name,age,pay);//这里改为这样。那是因子类继承了父类,而且父类已经做完了初始化,那么这样super(name,age,pay)就会调用2不这里的初始化。
this.bonus = bonus;
}
public void work(){
System.out.println("working"+bonus);
}
}
public class AbstractDemo {

        /**
         * @param args
         */
        public static void main(String[] args) {
                // TODO Auto-generated method stub
                Manager m = new Manager("lisi",20,200.0,100);//1 这个会到3这里进行初始化。
        }

}
回复 使用道具 举报
  1. abstract class Worker{
  2. private String name;
  3. private int age;
  4. private double pay;
  5. Worker(String name,int age,double pay){

  6. this.name = name;
  7. this.age = age;
  8. this.pay = pay;
  9. }
  10. abstract void work();//该方法必须被重写
  11. void sleep(){

  12. }
  13. }
  14. class Manager extends Worker{
  15. private int bonus;
  16. Manager(String name,int age,double pay,int bonus){
  17. super.name = name;
  18. super.age = age;
  19. this.pay = pay;
  20. this.bonus = bonus;
  21. }
  22. public void work(){
  23. System.out.println("working"+bonus);
  24. }
  25. }
  26. public class AbstractTest {
  27. public static void main(String[] args){

  28. }

  29. }
复制代码
==================这是全部代码==========================
回复 使用道具 举报
楼主,能把所有代码贴出来吗?

点评

abstract class Worker{ private String name; private int age; private double pay; Worker(String name,int age,double pay){ this.name = name; this.age = age; this.pay = pay; }...  发表于 2012-9-14 16:11
回复 使用道具 举报
子类继承了父类中的属性和功能,所以要初始化子类,先要初始化父类,因为子类中有一部分内容是从父类继承过来的。
构造函数就是用来初始化类的,子类要先调用父类的构造函数,初始化父类,才能继续和父类相关的操作。
如果父类中的构造函数是没有参数的,子类中可以省略super();因为super()默认存在,但是如果父类中的构造函数有参数,就需要手动显示调用父类的构造函数了。
this指代的是本来,super指代父类,你要用父类中的变量,当然要用super来引用。

评分

参与人数 1技术分 +1 收起 理由
黑马_许芸 + 1 赞一个!

查看全部评分

回复 使用道具 举报
1.因为你子类的构造函数是带参数的,带参数的构造函数必须重写,不带参的可以不写。
sleep方法不是构造方法,不必重写。
2.你的子类当中没有name,age等,这些属性都是你父类的,所以应该写成super.name

点评

你确定是super.name?? 我试了 还是不行  发表于 2012-9-14 16:09
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马