一段我和同學有意思的爭論

來源:互聯網
上載者:User

物件導向最簡單的問題,

 

網上甚至一些教材卻給了形形色色的回答。

 

關於私人成員和繼承之間的關係的問題。

 

今天我和同學在網上就這個問題爭論了一下,

 

最終發現咱們倆的理解都是對的。

 

哈哈。

 

記錄一下這段有意義的對話。

 

我是 “一頭豬”……

 

 

 

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

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.