黑马程序员技术交流社区

标题: 抽象类练习遇到错误,属性可以访问private,如何解决? [打印本页]

作者: 陈虹旭    时间: 2012-9-23 13:35
标题: 抽象类练习遇到错误,属性可以访问private,如何解决?
本帖最后由 陈虹旭 于 2012-9-24 11:51 编辑
  1. abstract class Employee
  2. {
  3. private String name;
  4. private String id;
  5. private double pay;
  6. Employee(String name,String id,double pay)
  7. {
  8. this.name = name;
  9. this.id = id;
  10. this.pay = pay;
  11. }
  12. public abstract void work();
  13. }
  14. class Professional extends Employee
  15. {
  16. Professional(String name,String id,double pay)
  17. {
  18. super(name,id,pay);
  19. }
  20. public void work()
  21. {
  22. System.out.println(this.name+"..."+this.id+"..."+this.pay+"...Professional work");
  23. }
  24. }
  25. class Manager extends Employee
  26. {
  27. private int bonus;
  28. Manager(String name,String id,double pay,int bonus)
  29. {
  30. super(name,id,pay);
  31. this.bonus = bonus;
  32. }
  33. public void work()
  34. {
  35. System.out.println(this.name+"..."+this.id+"..."+this.pay+"..."+this.bonus+"...Manager work");
  36. }


  37. }
  38. class EmployeeDemo
  39. {
  40. public static void main(String[] args)
  41. {
  42. Professional p = new Professional("zhangsan","Pro001",1000.00);
  43. p.work();
  44. Manager m = new Manager("lisi","Man001",2000.00,500);
  45. m.work();

  46. }
  47. }
复制代码
提示报错:
EmployeeDemo.java:34: name 可以在 Employee 中访问 private
                System.out.println(this.name+"..."+this.id+"..."+this.pay+"...Professional work");

为什么会出现可以访问private的错误呢?
我想带在work()方法中得到员工的姓名,工号,工资等属性该如何得到呢?求指点!                     


作者: 李建强    时间: 2012-9-23 13:57
本帖最后由 李建强 于 2012-9-23 15:19 编辑

子类继承了抽象类,也包括私有属性,但是属性是不可以被访问的。
虽然子类可以通过getXXX的方法获得父类私有属性。
但是抽象类根本没有提供操作私有属性的方法,比如说setXXX,getXXX。
work()方法覆盖了抽象类,还是访问继承自父类的私有属性。

在抽象类中定义get方法
public String getName()
{
  return name;
}
work方法中这么输出试试
System.out.println(super.name);


作者: 陈虹旭    时间: 2012-9-23 14:01
李建强 发表于 2012-9-23 13:57
注意:super(name,id,pay);
Java中子类是不能访问父类的private成员(方法、属性)。
public String name;

这个我知道,但是父类中定义了private的属性就是为了防止其他类的访问,而且父类中的方法已经在构造函数中提供出了公共访问方式的啊!
你说的把属性都公有化也许能编译通过,但是这不就不符合编程思想和现实中描述事物的规律了吗?
作者: 王陶成    时间: 2012-9-23 14:23
可以使用反射,这个是后面高新技术里面的了
作者: 陈虹旭    时间: 2012-9-23 14:37
王陶成 发表于 2012-9-23 14:23
可以使用反射,这个是后面高新技术里面的了

o_o  还没有学到...
作者: 陈虹旭    时间: 2012-9-23 15:03
有没有哪位高手给看一下啊
public void work()
{
System.out.println(this.name+"..."+this.id+"..."+this.pay+"...Professional work");
}
这里想调用name、id等属性该如何实现?才会不提示上述错误


作者: 李建强    时间: 2012-9-23 15:08
本帖最后由 李建强 于 2012-9-23 15:15 编辑

子类继承了抽象类,也包括私有属性,但是属性是不可以被访问的。
虽然子类可以通过getXXX的方法获得父类私有属性。
但是抽象类根本没有提供操作私有属性的方法,比如说setXXX,getXXX。
work()方法虽然覆盖了抽象类,还是访问继承自父类的私有属性。

在抽象类中定义get方法
public String getName()
{
  return name;
}




作者: AngieFans85    时间: 2012-9-23 15:23
李建强 发表于 2012-9-23 13:57
子类继承了抽象类,也包括私有属性,但是属性是不可以被访问的。
虽然子类可以通过getXXX的方法获得父类私 ...

"注意:super(name,id,pay);"

跟调用父类的构造方法没有任何关系,这种方式没有错误.
LZ的问题出在:
System.out.println(this.name + "..." + this.id + "..." + this.pay);
父类的name,id,pay属性是私有的,所以子类不能直接访问父类的私有属性.
作者: AngieFans85    时间: 2012-9-23 15:25
陈虹旭 发表于 2012-9-23 14:01
这个我知道,但是父类中定义了private的属性就是为了防止其他类的访问,而且父类中的方法已经在构造函数 ...

那就给父类的三个属性提供get和set方法就可以了.
作者: AngieFans85    时间: 2012-9-23 15:27
陈虹旭 发表于 2012-9-23 15:03
有没有哪位高手给看一下啊
public void work()
{
  1. abstract class Employee {

  2.         String name;
  3.         String id;
  4.         double pay;

  5.         Employee(String name, String id, double pay) {
  6.                 this.name = name;
  7.                 this.id = id;
  8.                 this.pay = pay;
  9.         }

  10.         public String getName() {
  11.                 return name;
  12.         }

  13.         public void setName(String name) {
  14.                 this.name = name;
  15.         }

  16.         public String getId() {
  17.                 return id;
  18.         }

  19.         public void setId(String id) {
  20.                 this.id = id;
  21.         }

  22.         public double getPay() {
  23.                 return pay;
  24.         }

  25.         public void setPay(double pay) {
  26.                 this.pay = pay;
  27.         }

  28.         public abstract void work();

  29. }
复制代码

作者: 李建强    时间: 2012-9-23 15:31
马镱洵 发表于 2012-9-23 15:23
"注意:super(name,id,pay);"

跟调用父类的构造方法没有任何关系,这种方式没有错误.

那是刚才吃饭前写的,没说准,但是刚才我修改了啊,怎么还有?
作者: 张忠豹    时间: 2012-9-23 15:47
本帖最后由 张忠豹 于 2012-9-23 15:48 编辑

abstract class Employee
{

        private String name;
        
        private String id;

        private double pay;
        //①
        public String getName() {   
                return name;
        }
       //②
        public String getId() {
                return id;
        }
        //③
        public double getPay() {
                return pay;
        }

        Employee(String name, String id, double pay)

        {

                this.name = name;

                this.id = id;

                this.pay = pay;

        }

        public abstract void work();

}
...
class EmployeeDemo

{

        public static void main(String[] args) {

                Professional p = new Professional("zhangsan", "Pro001", 1000.00);

                p.work();

                Manager m = new Manager("lisi", "Man001", 2000.00, 500);

                m.work();

        }

}
变量私有化确实是Java所提倡的,但是在此虽然你通过构造函数给属性进行了显示的初始化,但是在访问的时候,在此的this所代表的是子类的对象,因为在子类中是不能对私有化的成员变量进行访问的,除非对这些属性提供公有化的访问方式,如①②③,在此是满足Java的封装特性的。

作者: 陈虹旭    时间: 2012-9-24 11:22
马镱洵 发表于 2012-9-23 15:27

谢谢指点 得以解决!终于明白关键了“this代表子类对象,不能直接访问父类私有属性” 正解!
作者: 陈虹旭    时间: 2012-9-24 11:37
李建强 发表于 2012-9-23 13:57
子类继承了抽象类,也包括私有属性,但是属性是不可以被访问的。
虽然子类可以通过getXXX的方法获得父类私 ...

这种方法我也想到了 也照你的方法试过了 没有得到解决
我想应该是因为super()是调用父类构造函数,而super代表的是对象,而主函数中并未对父类对象做出过初始化,所以super.name这样的调用是不成立的...而且记得老师应该说过,this和super好像只能用于构造函数间的调用吧,一般函数好像不能调用构造函数,我把这点疏忽了...
作者: 陈虹旭    时间: 2012-9-24 11:50
张忠豹 发表于 2012-9-23 15:47
abstract class Employee
{

嗯 明白了 而且你的代码中没有setName()等方法,在对象调用构造函数初始化的时候就已经给出了相应的属性值,就不用在自行设置了,这样做省去了不少代码,很简便,谢谢!
作者: 杜佳瑞    时间: 2012-9-24 11:59
李建强 发表于 2012-9-23 13:57
子类继承了抽象类,也包括私有属性,但是属性是不可以被访问的。
虽然子类可以通过getXXX的方法获得父类私 ...

子类是不能继承父类的私有属性的。
要是能继承,当然就可以访问了。既然不可以访问,当然就不能继承。


作者: 李建强    时间: 2012-9-24 13:24
杜佳瑞 发表于 2012-9-24 11:59
子类是不能继承父类的私有属性的。
要是能继承,当然就可以访问了。既然不可以访问,当然就不能继承。

父类的工作都是建立在自己的私有成员上运行的,
不是给子类用的,所以子类不可见。

私有的目的是保证自己的运行环境不被外界改变。
这点你可以通过反射试一下。


作者: 李建强    时间: 2012-9-24 13:31
本帖最后由 李建强 于 2012-9-24 13:35 编辑
陈虹旭 发表于 2012-9-24 11:37
这种方法我也想到了 也照你的方法试过了 没有得到解决
我想应该是因为super()是调用父类构造函数,而supe ...
稍微修改了下。
结果应该是:抽象构造->子类构造->子类方法
  1. abstract class Employee

  2. {
  3.         private String name;
  4.         private String id;
  5.         private double pay;
  6.         public Employee(String name,String id,double pay)
  7.         {
  8.                 this.name = name;
  9.                 this.id = id;
  10.                 this.pay = pay;
  11.                 System.out.println("这个是在抽象类构造函数中"+this.name+"..."+this.id+"..."+this.pay+"...Professional work");
  12.         }
  13.         
  14.         public abstract void work();
  15.         public void set(String name,String id,double pay)
  16.         {
  17.                 this.name = name;
  18.                 this.id = id;
  19.                 this.pay = pay;
  20.         }
  21.         
  22.         public String getName()
  23.         {
  24.                 return name;
  25.         }
  26. }


  27. class Professional extends Employee
  28. {
  29.         Professional(String name,String id,double pay)
  30.         {
  31.                 super(name,id,pay);
  32.                 //super.set(name,id,pay);
  33.                 System.out.println("这个是在子类构造方法中"+super.getName());
  34.         }
  35.         public void work()
  36.         {
  37.                 System.out.println("这个是在子类方法中"+super.getName());
  38.         }
  39. }

  40. class EmployeeDemo
  41. {
  42.         public static void main(String[] args)
  43.         {
  44.                 Employee em = new Professional("zhangsan","1",1.0);
  45.                 em.work();

  46.         }
  47. }
复制代码

作者: 陈虹旭    时间: 2012-9-24 15:10
李建强 发表于 2012-9-24 13:31
稍微修改了下。
结果应该是:抽象构造->子类构造->子类方法

嗯 编译通过 正常运行 ...   看来用到get和set是很必要的!:victory::victory:
作者: 李建强    时间: 2012-9-24 15:22
陈虹旭 发表于 2012-9-24 15:10
嗯 编译通过 正常运行 ...   看来用到get和set是很必要的!

呵呵,一起努力。
作者: AngieFans85    时间: 2012-9-24 20:34
陈虹旭 发表于 2012-9-24 11:22
谢谢指点 得以解决!终于明白关键了“this代表子类对象,不能直接访问父类私有属性” 正解! ...

不客气:handshake




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