一段我和同学有意思的争论

面向对象最简单的问题,

 

网上甚至一些教材却给了形形色色的回答。

 

关于私有成员和继承之间的关系的问题。

 

今天我和同学在网上就这个问题争论了一下,

 

最终发现咱们俩的理解都是对的。

 

哈哈。

 

记录一下这段有意义的对话。

 

我是 “一头猪”……

 

 

 


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
难免的

 

你可能感兴趣的:(一段我和同学有意思的争论)