面向对象最简单的问题,
网上甚至一些教材却给了形形色色的回答。
关于私有成员和继承之间的关系的问题。
今天我和同学在网上就这个问题争论了一下,
最终发现咱们俩的理解都是对的。
哈哈。
记录一下这段有意义的对话。
我是 “一头猪”……
2009-07-17 21:46:08 WL
我常常在想要有个技术牛人一直教你
2009-07-17 21:46:21 WL
你肯定日益精进啊
2009-07-17 21:46:36 WL
就跟他妈练武的拿到葵花宝典一样
2009-07-17 21:58:49 WL
你说基类的一个方法是private的,在子类里面能实现他的继承方法重定义后变成public的么?
2009-07-17 22:26:08 WL
在么?
2009-07-17 22:43:27 ぃ_●壹頭猪
不能
2009-07-17 22:43:32 ぃ_●壹頭猪
你是傻逼把
2009-07-17 22:43:41 ぃ_●壹頭猪
基类的private 变成子类的public
2009-07-17 22:43:48 ぃ_●壹頭猪
那C++ 的private还有什么用
2009-07-17 22:45:17 WL
不是
2009-07-17 22:45:27 WL
我是说子类继承过来的方法
2009-07-17 22:45:29 WL
我重载
2009-07-17 22:45:39 WL
并且写成public的
2009-07-17 22:45:41 WL
可以么
2009-07-17 22:45:48 ぃ_●壹頭猪
可以的
2009-07-17 22:45:52 ぃ_●壹頭猪
你可以试试
2009-07-17 22:45:56 ぃ_●壹頭猪
应该可以
2009-07-17 22:46:02 ぃ_●壹頭猪
overload应该可以
2009-07-17 22:48:14 WL
不是override么?
2009-07-17 22:49:11 WL
你说的这个重载还得拿关键字声明?
2009-07-17 22:49:19 ぃ_●壹頭猪
不用
2009-07-17 22:49:22 ぃ_●壹頭猪
override
2009-07-17 22:49:24 ぃ_●壹頭猪
嗯
2009-07-17 22:49:36 WL
直接覆盖就好了是吧
2009-07-17 22:49:49 ぃ_●壹頭猪
你拿VC试试补就行了
2009-07-17 22:49:51 ぃ_●壹頭猪
我在网吧
2009-07-17 22:49:54 ぃ_●壹頭猪
试补了
2009-07-17 22:49:57 WL
嗯
2009-07-17 22:49:59 WL
好的
2009-07-17 22:54:54 WL
额
2009-07-17 22:55:08 WL
其实根本没有发生覆盖或者是重载
2009-07-17 22:55:16 WL
这是两个不相关的函数
2009-07-17 22:55:30 WL
因为函数签名不一样
2009-07-17 22:55:45 WL
private跟public是属于函数签名的
2009-07-17 22:56:26 ぃ_●壹頭猪
……
2009-07-17 22:56:43 WL
这叫什么
2009-07-17 22:56:56 WL
多态性
2009-07-17 22:57:02 WL
可以同名
2009-07-17 22:57:04 ぃ_●壹頭猪
是啊
2009-07-17 22:57:07 ぃ_●壹頭猪
就是多态啊
2009-07-17 22:57:09 ぃ_●壹頭猪
晕
2009-07-17 22:57:12 ぃ_●壹頭猪
我知道你什么意思了
2009-07-17 22:57:14 WL
但是签名不一样
2009-07-17 22:57:14 ぃ_●壹頭猪
不能那样
2009-07-17 22:57:17 ぃ_●壹頭猪
我就是说多态
2009-07-17 22:57:38 ぃ_●壹頭猪
你说重载一个private然后基类调用时使用你子类重载过得函数是把?
2009-07-17 22:57:41 ぃ_●壹頭猪
不可以
2009-07-17 22:57:52 WL
哦
2009-07-17 22:58:43 WL
你的意思是private不能被继承?
2009-07-17 22:58:50 ぃ_●壹頭猪
嗯
2009-07-17 22:59:01 WL
我不得不说一句
2009-07-17 22:59:04 WL
你是SB
2009-07-17 22:59:14 WL
private可以被继承
2009-07-17 22:59:16 ぃ_●壹頭猪
不可以
2009-07-17 22:59:19 WL
可以
2009-07-17 22:59:24 WL
绝对可以
2009-07-17 22:59:34 WL
我写了几个这种程序了
2009-07-17 22:59:38 ぃ_●壹頭猪
标准C++绝对不可以
2009-07-17 22:59:44 ぃ_●壹頭猪
这是原话
2009-07-17 22:59:55 ぃ_●壹頭猪
除非你的编译器有问题
2009-07-17 23:00:40 WL
我的书上写的是
Y对X实现了继承
2009-07-17 23:01:05 WL
代表Y继承了X所有的数据成员和成员对象
2009-07-17 23:01:24 WL
事实上我在几天前就试过了
2009-07-17 23:01:37 WL
并且发现我以前对继承的理解不对
2009-07-17 23:02:06 ぃ_●壹頭猪
你有病
2009-07-17 23:02:09 WL
。。。
2009-07-17 23:02:14 WL
你自己搞错了而已
2009-07-17 23:02:22 WL
你随便再去问问别人吧
2009-07-17 23:02:23 ぃ_●壹頭猪
你知道么,那天你在MSN上问我private能补能被继承
2009-07-17 23:02:31 ぃ_●壹頭猪
被我同事看到了,他们暴笑
2009-07-17 23:02:36 WL
自己写个程序试试
2009-07-17 23:02:38 ぃ_●壹頭猪
说你这都不知道不能被继承……
2009-07-17 23:02:47 ぃ_●壹頭猪
我当时不再座位上
2009-07-17 23:02:52 WL
可以被继承
2009-07-17 23:02:54 WL
。。。
2009-07-17 23:03:21 WL
说实话
2009-07-17 23:03:24 WL
你告诉我这后
2009-07-17 23:03:33 WL
我只是觉得他们很无知
2009-07-17 23:03:53 WL
对于自己所认知的事务
2009-07-17 23:04:10 WL
你舅百分之百确定你知道的都是对的么?
2009-07-17 23:04:10 ぃ_●壹頭猪
class Clidder{
private final void flipper(){
System.out.println("Clidder");
}
}
public class Example extends Clidder{
private final void flipper(){
System.out.println("Example");
}
public static void main (String[] args) {
new Example().flipper();
}
}
运行结果:
Example
处理已完成。
程序并没有错误,尽管父类Clidder中的flipper()方法是final方法,不能被重载。而子类Example中依然存在一个flipper()方法而并不会产生编译错误,这是因为子类中的flipper()方法并不是重载方法,而是一个新声明的方法。因为父类Clidder中的flipper()方法是private()方法,并没有被子类继承,因此何谈发生子类父类间的方法重载。
2009-07-17 23:04:35 ぃ_●壹頭猪
因为 我前两天在C++ 上看到的原话
2009-07-17 23:04:39 ぃ_●壹頭猪
private 不能被继承
2009-07-17 23:04:45 ぃ_●壹頭猪
C++ PRIMER
2009-07-17 23:04:57 WL
你等等
2009-07-17 23:05:00 WL
等我看完
2009-07-17 23:05:03 ぃ_●壹頭猪
你搜以下
2009-07-17 23:05:09 ぃ_●壹頭猪
c++ primer有这个原话
2009-07-17 23:07:04 WL
呵呵
2009-07-17 23:07:08 WL
我有个程序
2009-07-17 23:07:17 WL
你可以拿去跑一下
2009-07-17 23:07:25 ぃ_●壹頭猪
你发给我看看
2009-07-17 23:07:55 WL
看一看继承之后再子类对象里面有没有父类private的踪影
2009-07-17 23:08:25 WL
// inheritance.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <iostream>
using namespace std;
class X
{
int i;
public:
X(){i=0;}
void set(int ii){i=ii;}
int read() const {return i;}
int permute(){return i=i*47;}
};
class Y: public X
{
int i;
public:
Y(){i=100;}
int change() {
i=permute();
return i;
}
void set(int ii){
i=ii;
X::set(ii);
}
int getI() const{
return i;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
cout<<"sizeof(X)"<<sizeof(X)<<endl;
cout<<"sizeof(Y)"<<sizeof(Y)<<endl;
Y D;
cout<<"D.getI"<<D.getI()<<endl;
cout<<"D.change()"<<D.change()<<endl;
cout<<"D.getI"<<D.getI()<<endl;
D.set(12);
cout<<"D.read()"<<D.read()<<endl;
cout<<"D.permute"<<D.permute()<<endl;
cout<<"D.change()"<<D.change()<<endl;
//D.set(12);
cout<<"D.getI"<<D.getI()<<endl;
system("pause");
return 0;
}
2009-07-17 23:08:58 WL
你在跑程序前可以先想一想按你的继承理解的俄结果
2009-07-17 23:09:04 ぃ_●壹頭猪
怎么这么复杂
2009-07-17 23:09:09 WL
再看看事实情况
2009-07-17 23:09:22 WL
我简化点给你吧
2009-07-17 23:09:30 WL
那是因为我还做过很多测试
2009-07-17 23:09:31 ぃ_●壹頭猪
你自己试试不就知道了
2009-07-17 23:09:40 WL
我试过几百遍了
2009-07-17 23:09:42 WL
。。
2009-07-17 23:09:48 ぃ_●壹頭猪
class Y: public X
{
int i;、
2009-07-17 23:09:56 ぃ_●壹頭猪
你把这个int i;去掉试试能运行补
2009-07-17 23:10:02 ぃ_●壹頭猪
你这是把i重载了
2009-07-17 23:10:17 WL
没有重载
2009-07-17 23:10:18 WL
。。。
2009-07-17 23:10:35 WL
这两个i根本就问毫无关系
2009-07-17 23:10:45 WL
相互没有任何影响和
2009-07-17 23:11:01 WL
你拿我的程序跑跑就知道了
2009-07-17 23:11:05 ぃ_●壹頭猪
那你怎么说private被继承了?
2009-07-17 23:11:11 ぃ_●壹頭猪
我没看到有其他的private
2009-07-17 23:11:23 WL
。。。
2009-07-17 23:11:25 WL
首先
2009-07-17 23:11:29 WL
从空间上看
2009-07-17 23:11:42 WL
Y的对象的空间是X的两倍
2009-07-17 23:12:02 WL
因为Y的对象里面有一个自己的i有一个X的i
2009-07-17 23:12:10 ぃ_●壹頭猪
我不管你说什么空间,但是你这个程序没有继承 private
2009-07-17 23:12:18 ぃ_●壹頭猪
有是有,但是不能访问
2009-07-17 23:12:21 WL
还有
2009-07-17 23:12:27 ぃ_●壹頭猪
内存是肯定分配了
2009-07-17 23:12:34 WL
你听我说完OK?
2009-07-17 23:13:02 WL
我可以在Y的对象里面通过从X继承来的方法访问X里的i
2009-07-17 23:13:29 WL
对X里的i 通过继承来的方法进行访问
2009-07-17 23:13:43 WL
我可以改变那个i 的值
2009-07-17 23:13:56 WL
变且整个过程没有生成任何X的对象
2009-07-17 23:14:00 ぃ_●壹頭猪
我知道你什么意思了
2009-07-17 23:14:03 ぃ_●壹頭猪
你理解错了
2009-07-17 23:14:12 WL
那你说怎么理解
2009-07-17 23:14:16 ぃ_●壹頭猪
你面向对象理解补透彻
2009-07-17 23:14:33 ぃ_●壹頭猪
继承是什么意思
2009-07-17 23:14:44 WL
继承就是对代码的复用
2009-07-17 23:14:50 ぃ_●壹頭猪
我跟你语音把
2009-07-17 23:14:57 WL
嗯。
2009-07-17 23:15:00 ぃ_●壹頭猪
这个问题我一定得纠正你
2009-07-17 23:15:35 WL
我这没有MI
2009-07-17 23:15:46 WL
听不到
2009-07-17 23:15:50 ぃ_●壹頭猪
我这MIC烂了
2009-07-17 23:15:57 WL
嗯
2009-07-17 23:16:00 WL
与您进行语音聊天,时长37秒。
2009-07-17 23:16:21 WL
而且我告诉你我的书上给的继承是在自身对象的空间里面
2009-07-17 23:16:24 ぃ_●壹頭猪
我这样跟你说吧
2009-07-17 23:16:40 WL
先开辟出一块父类对象的空间
2009-07-17 23:17:08 ぃ_●壹頭猪
继承是会在内存分配一块地方给基类的私有成员
2009-07-17 23:17:11 WL
在这块空间继承了所有的父类成员
2009-07-17 23:17:14 ぃ_●壹頭猪
或者私有函数
2009-07-17 23:17:15 WL
嗯
2009-07-17 23:17:26 ぃ_●壹頭猪
但是派生类不能直接访问这些私有成员
2009-07-17 23:17:38 WL
并且可以通过public来方法访问到
2009-07-17 23:17:43 ぃ_●壹頭猪
但是,可以通过继承而来的公有接口来访问
2009-07-17 23:17:55 ぃ_●壹頭猪
因为公有接口是属于基类
2009-07-17 23:18:06 ぃ_●壹頭猪
所以自己的private是可见的
2009-07-17 23:18:27 ぃ_●壹頭猪
如果是可以继承private的意思就是
2009-07-17 23:18:31 ぃ_●壹頭猪
可以直接访问
2009-07-17 23:19:09 ぃ_●壹頭猪
基类的私有成员
2009-07-17 23:19:13 ぃ_●壹頭猪
这样是不行的
2009-07-17 23:19:29 WL
谁说继承的意思就是可以直接访问
2009-07-17 23:19:37 ぃ_●壹頭猪
书上的原话 private 是不能被继承的
2009-07-17 23:19:54 WL
我看的thinking in c++书上的原话不是这样的
2009-07-17 23:20:06 ぃ_●壹頭猪
就是这么定义的,被继承的方法或者参数是可以在该类范围内直接访问的
2009-07-17 23:20:14 ぃ_●壹頭猪
你那个例子只是继承了那些公有接口
2009-07-17 23:20:30 ぃ_●壹頭猪
定义可能有差别
2009-07-17 23:20:32 WL
我告诉你我书上怎么写的继承
2009-07-17 23:20:34 ぃ_●壹頭猪
我的意思是可以这么理解的
2009-07-17 23:22:35 WL
所有的X中的私有成员在Y中仍然是私有的,这是因为Y对X进行了继承不不意味着Ykeyi 不遵守保护机制。X中的私有成员仍占存储空间,只是不能直接访问他们罢了。
2009-07-17 23:22:52 ぃ_●壹頭猪
哦
2009-07-17 23:23:03 ぃ_●壹頭猪
我知道了
2009-07-17 23:23:06 ぃ_●壹頭猪
有两种说法
2009-07-17 23:23:12 ぃ_●壹頭猪
都有自己的道理
2009-07-17 23:23:19 ぃ_●壹頭猪
会,但是不能被访问。所以看上去他们似乎是不能被继承的,但实际上确实被继承了。
2009-07-17 23:23:29 ぃ_●壹頭猪
这是一种说法
2009-07-17 23:23:31 WL
我们看到Y对X进行了继承,这意味着Y将包含X中的所有数据成员和成员函数
2009-07-17 23:23:33 ぃ_●壹頭猪
嗯
2009-07-17 23:23:36 ぃ_●壹頭猪
都有道理
2009-07-17 23:23:38 WL
这是原话
2009-07-17 23:23:45 WL
一字不漏
2009-07-17 23:23:52 ぃ_●壹頭猪
但是c++ primer上写了原话 private不能被继承
2009-07-17 23:24:01 ぃ_●壹頭猪
可能是翻译者的理解不同
2009-07-17 23:24:14 WL
空间都开辟了
2009-07-17 23:24:18 ぃ_●壹頭猪
嗯
2009-07-17 23:24:19 WL
并且可以使用
2009-07-17 23:24:29 WL
你不管他是不是直接访问
2009-07-17 23:24:41 WL
总之1他开空间了
2009-07-17 23:24:49 WL
2这块空间可以用
2009-07-17 23:25:20 WL
3这个对象消失了这里面的东西也就消失了
2009-07-17 23:25:36 WL
如果这都不算继承了
2009-07-17 23:25:53 WL
那继承理解的就很狭隘了
2009-07-17 23:26:06 WL
或者说继承的定义很窄
2009-07-17 23:26:15 ぃ_●壹頭猪
我决定懒得跟你讨论这个问题了,不过我很理解。无所谓定义了,自己会用就行
2009-07-17 23:26:41 WL
嗯
2009-07-17 23:27:05 ぃ_●壹頭猪
不过确实我公司那几个人不该那样
2009-07-17 23:27:11 ぃ_●壹頭猪
不同理解方式而已
2009-07-17 23:27:13 WL
呵呵
2009-07-17 23:27:31 WL
难免的