黑马程序员技术交流社区

标题: 父类中的成员私有了以后,子类可以继承吗? [打印本页]

作者: 黄基焜    时间: 2012-9-7 22:15
标题: 父类中的成员私有了以后,子类可以继承吗?
本帖最后由 黄基焜 于 2012-9-8 00:24 编辑

今天看到老毕的一段代码如下:
class Employee
{
        private String name;
        private String id;
        private double pay;

        Employee(String name,String id,double pay)
        {
                this.name = name;
                this.id = id;
                this.pay = pay;
        }
        
        public void work(){};

}



class Manager extends Employee
{
        private int bonus;
        Manager(String name,String id,double pay,int bonus)
        {
                super(name,id,pay);
                this.bonus = bonus;
        }
        public void work()
        {
                System.out.println("manager work");
        }
}

class Pro extends Employee
{
        Pro(String name,String id,double pay)
        {
                super(name,id,pay);
        }
        public void work()
        {
                System.out.println("pro work");
        }
}

父类Employee中的私有成员name、id、poy可以给子类Manager继承到吗?
之前看老毕的视频听到父类成员private后,子类也不能引用。
作者: 郑世光    时间: 2012-9-7 22:18
不可以,就像你不能用你爸的名字一样。你爸的名字是你爸专有的。
作者: 黄基焜    时间: 2012-9-7 22:19
本帖最后由 黄基焜 于 2012-9-7 22:22 编辑

class Manager extends Employee
{
        private int bonus;
        Manager(String name,String id,double pay,int bonus)
        {
                super(name,id,pay);//这里不是引用了父类的私有成员吗?
                this.bonus = bonus;
        }
        public void work()
        {
                System.out.println("manager work");
        }
}

如果不是引用私有成员;
方法参数列表里的(String name,String id,double pay)name、id、pay不就变成了局部变量了吗?
作者: 何明辉    时间: 2012-9-7 22:49
楼主好像没有区分什么是成员方法和构造函数哦。
你上面的Manager()是构造函数,使用来给相对应的类来进行实例化,因为默认没有构造函数即Manager(){}没有显示指出,那么系统就会把你所指定的那个构造函数当成默认的了,这时你建立该类对象的时候就一定传递相应的参数才可以的,而构造函数本身就是在实列化类中的成员,所以当然可以访问private的私有属性啦。也就是你在其他类中

作者: 范泰洋    时间: 2012-9-7 22:58
本帖最后由 范泰洋 于 2012-9-7 23:05 编辑

      子类不能直接访问父类私有成员变量,但是父类可以对外提供一个get()获取的方法间接访问父类私有成员变量。
      其实堆内存中创建的子类对象中包含着一个父类的引用,而私有成员变量在父类中是真实存在的,所以子类不能直接对其访问,但可以通过特定方法get()方法间接访问。
class Manager extends Employee
{
        private int bonus;
        Manager(String name,String id,double pay,int bonus)
        {
                super(name,id,pay);//这里不是引用了父类的私有成员吗?//这里不是引用了父类的私有成员,super语句是到父类找到相对应的构造器对父类的私有成员进行初始化!
                this.bonus = bonus;
        }
        public void work()
        {
                System.out.println("manager work");
        }
}



作者: 黄基焜    时间: 2012-9-7 23:04
何明辉 发表于 2012-9-7 22:49
楼主好像没有区分什么是成员方法和构造函数哦。
你上面的Manager()是构造函数,使用来给相对应的类来进行 ...


我确实不明白什么叫成员方法。
我知道那个是构造函数,他的参数列表就是实例化传进去的初始化值。
如果父类的成员变量私有化了之后,子类不能继承。
但是子类中并没有对应的成员变量啊。
那么构造函数里的变量,不就成了局部变量呢?
作者: 黄基焜    时间: 2012-9-7 23:07
本帖最后由 黄基焜 于 2012-9-7 23:20 编辑
范泰洋 发表于 2012-9-7 22:58
子类不能直接访问父类私有成员变量,但是父类可以对外提供一个get()获取的方法间接访问父类私有成 ...


你说我也知道,对外提供的方法还要用public修饰。
但是我说的继承问题。
建立子类对象在子类的构造函数里面给父类私有成员初始化值??不可能的
作者: 杨卫腾    时间: 2012-9-7 23:30
哥们,还是你没有好好理解。

      子类不能直接访问父类私有成员变量和私有的成员方法,但是父类可以对外提供一个 get() 获取的方法可以间接访问父类私有成员变量。
      
      其实堆内存中创建的子类对象中包含着一个父类的引用,你的子类构造函数之中不是有一个super(name,id,pey),你知道super代表的是什么吗?
      其实代表的是父类中的一个空间,在这个空间中有父类的私有成员变量,子类就会找到这片区域对自己进行初始化,已达到创建创建对象目的。
     
      而私有成员变量在父类中是真实存在的,所以子类不能直接对其访问,但可以通过特定方法 get() 或者其他方法间接访问。
作者: 范泰洋    时间: 2012-9-7 23:43
黄基焜 发表于 2012-9-7 23:04
我确实不明白什么叫成员方法。
我知道那个是构造函数,他的参数列表就是实例化传进去的初始化值。
如果父 ...

哥们建议你回头去看看super关键字。
作者: 黄基焜    时间: 2012-9-7 23:48
杨卫腾 发表于 2012-9-7 23:30
哥们,还是你没有好好理解。

      子类不能直接访问父类私有成员变量和私有的成员方法,但是父类可以对外 ...

我问的是继承不是封装。
私有成员的访问方法,你说的提供get()间接访问是封装的问题,不是继承的问题。

父类的name,id,pey已经私有了。
子类中并没有name,id,pey成员;super(name,id,pey)不就变成只是编译运行的一行代码。没有其他意义?
因为对于子类来说name,id,pey变成了类似于函数中的局部成员的存在。
对于子类对象建立里面没有name,id,pey的属性。
作者: 何明辉    时间: 2012-9-7 23:55
黄基焜 发表于 2012-9-7 23:04
我确实不明白什么叫成员方法。
我知道那个是构造函数,他的参数列表就是实例化传进去的初始化值。
如果父 ...

不好意思哈刚才没有说明白,我个人的理解是对于构造函数里面的参数列表是可以当成局部变量来理解,在进行运算的时候局部的变量的值通过super(参数值)语句传给了父类的成员变量,这其实就是父类实列化的过程。super语句是调用了父类的构造函数,
作者: 黄基焜    时间: 2012-9-8 00:00
本帖最后由 黄基焜 于 2012-9-8 00:10 编辑
范泰洋 发表于 2012-9-7 23:43
哥们建议你回头去看看super关键字。


你一开始就没搞清楚我问的是什么问题。
我也回头看了。super(name,id,pey)这句对子类来说也就是对子类建立对象编译通过的语句。在楼顶的代码里面对子类来说没有任何意义。
作者: 范泰洋    时间: 2012-9-8 00:08
黄基焜 发表于 2012-9-8 00:00
你一开始就没搞清楚我问的是什么问题

是的,我没看懂。
作者: 黄基焜    时间: 2012-9-8 00:18
本帖最后由 黄基焜 于 2012-9-8 00:23 编辑

class Employee
{
        private String name;
        private String id;
        private double pay;

        Employee(String name,String id,double pay)
        {
                this.name = name;
                this.id = id;
                this.pay = pay;
                                System.out.println(name+","+id);
        }
        
        public void work()
                {
                        System.out.println(name+","+id);
                }

}

class Manager extends Employee
{
        private int bonus;
        Manager(int bonus)
        {
                super("name","id",0.1);
                this.bonus = bonus;
        }

}

class demo
{
        public static void main(String[] args)
        {
                Manager n1 = new Manager(5);
                n1.work();
        }
}
感谢LS几位帮忙,我有了自己的理解:
子类对象的建立,包含着父类的成员和方法。(我不清楚是子类实体里包含,还是在建立子类对象时,也建立了一个模版对象来引用。)
父类私有成员的继承是隐藏式的继承。必须要父类提供方法才能调用、访问。

作者: Morrfree    时间: 2015-8-4 23:16
#在这里快速回复#其实并没有被继承,只是用super(参数)方法调用了父类的构造函数,没有真正的直接访问父类私有的成员变量
作者: muffin    时间: 2015-8-6 13:04
楼主看这个就应该明白了,这个问题我也想了半天。

PHL@AYT(3XEUT8[3OML6EGB.png (92.38 KB, 下载次数: 174)

PHL@AYT(3XEUT8[3OML6EGB.png

作者: muffin    时间: 2015-8-6 13:06
不知道自己理解的对不对,应该差不多吧。
其实自己也遇到了这个问题,发一个方便后面的人参考吧。




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