1. 程式人生 > >淺談將子類物件賦值給父類物件

淺談將子類物件賦值給父類物件

最近對將子類物件賦值給父類物件有點心得,想和大家分享一下,但本人水平有限,請各位指正和批評。言歸正傳,下面是幾個小例子,請大家看一看。

測試一
父類:

public class Supclass {
    public void print() {
        System.out.println("this is 父類print()方法" + "——此時物件" + this.toString());
    }
}

子類:

public class Subclass extends Supclass {
    public static void main(String[] args) {
        Supclass sup = new
Subclass(); sup.print(); System.out.println("此時物件" + sup.toString()); } }

  結果:this is 父類print()方法——此時物件是[email protected]
   此時物件是[email protected]

   說明:
   Supclass sup=new Subclass();
   雖然宣告的物件是父類物件,但實際的記憶體空間是子類物件的。
   繼承父類的方法public void print()被呼叫,輸出的是子類物件名字解析。

  結論:編譯時宣告的物件是父類物件,但執行時卻是子類物件.子類沒有重寫父類的方法,則此時的物件呼叫繼承父類的方法。

測試二
父類:

public class Supclass {
    public void print() {
        System.out.println("this is 父類print()方法" + "——此時物件" + this.toString());
    }
}

子類:

public class Subclass extends Supclass {
    public void print() {
        System.out.println("this is 子類print()方法"
+ "——此時物件" + this.toString()); } public static void main(String[] args) { Supclass sup = new Subclass(); sup.print(); System.out.println("此時物件" + sup.toString()); } }

  結果:this is 子類print()方法——此時物件是[email protected]
   此時物件是[email protected]
   說明:
   我在上個例子的基礎上,重寫了父類的print()方法,此時的呼叫的是子類的print()方法。

  結論:在上個例子結論的基礎上,我得到了一個結論:此時物件執行時確實子類物件,如果子類沒有從寫父類的方法,
   則此時的物件呼叫繼承父類的方法;否則,此時的物件呼叫子類方法.

  問題: 我們是不是可以從上面的測試得到的這樣結論: 將子類物件賦值給父類物件(即Supclass sup=new Subclass()),
   我們得到的就是子類物件,即sup就是子類物件??????

測試三
父類:

public class Supclass {
    protected String className = "父類屬性";

    public void print() {
        System.out.println("this is 父類print()方法" + "——此時物件" + this.toString());
    }
}

子類:

public class Subclass extends Supclass {
    protected String className = "子類屬性";

    public void print() {
        System.out.println("this is 子類print()方法" + "——此時物件" + this.toString());

    }

    public static void main(String[] args) {
        Supclass sup = new Subclass();
        System.out.println("此時的屬性時:" + sup.className);
    }
}

  結果:此時的屬性時:父類屬性

  說明:我在第一個測試的基礎上,給父類添了一個屬性className,在子類重寫了這個屬性.
   但我輸出此時物件的屬性時,卻是父類的屬性.
   結論: 將子類物件賦值給父類物件,方法和屬性和我們正統的繼承關係很不一樣.
   問題:
   此時物件究竟是子類物件,還是父類物件?

  開始推測:

   我在推測之前有幾點須宣告:

   1.當我們new一個子類物件時,父類物件的建構函式同時也被執行,即父類的一些必要資訊和子類物件共佔一個記憶體空間,
   當我們方法重寫時,於是我們就能使用super這個指代父類的物件.

  2.java中物件並不是完全的面向物件思想做的,即不是把一個物件的屬性和方法同時封裝到物件中.
   而是物件有自己的屬性,方法卻是引用類中的方法,可以說它是把屬性和類中方法的引用封裝到物件中.
   於是物件呼叫的方法不是自己的方法,而是類中方法.至於java為什麼要這樣做,我就不知道了.

  3.當物件被載入到記憶體時,類先被載入到記憶體中,此後類應是一隻留在記憶體中.至於類什麼時候從記憶體中消失,我也不知道.
   我想java一定有自己的回收機制,就像回收物件一樣.

  4.編譯和與執行是完全不同的事.編譯時主要做的是宣告物件的型別,分配屬性,檢查語法錯誤等
   執行時做的是,將物件載入記憶體(一般用new,反射也常用), 執行程式碼執行功能等.
  
   5.若是讀者您和我在這幾點沒有產生共鳴的話,或者說我們在這幾點沒用相同的認識的話,你會覺得我在胡說.
   也許你會覺得我的部落格等級太低,就覺得我的可信程度就低.但我想說的是學不分先後,達者為先.
   呵呵,我已準備好將我的部落格等級為負值了,哈哈哈,我們繼續.

  推測:
   1.當我們編譯Supclass sup=new Subclass()時,sup物件被宣告為Supclass類,於是sup物件的屬性便是父類物件的屬性的值,
 它是編譯時被確定好的.(宣告4,可以對這段進行解釋).這段話可以對測試三進行解釋,即為什麼此時物件的屬性是父類物件的屬性.
  
   2.當我們執行Supclass sup=new Subclass()時,此時sup物件的記憶體空間是子類物件的記憶體空間(宣告4,可以對這段進行解釋),
   注意此時sup物件的記憶體空間由兩部分組成父類的一些必要資訊和子類物件資訊(宣告1,可以對這段進行解釋).
   當我們不重寫父類的方法時,由於此時記憶體空間已有父類的一些必要資訊,所以繼承父類的方法public void print()當然能被呼叫。
   這段話可以對測試一進行解釋.
  3.接著2繼續,若我們重寫父類的方法時,由於sup物件的記憶體空間是子類物件的記憶體空間,子類的方法public void print()已被載入到記憶體中.
   所以我們呼叫的是子類的方法public void print();如果你需要呼叫父類的被重寫方法,需要用super.
   這段話可以對測試二進行解釋.
   總結:
   以下純是個人觀點:
   將子類物件賦值給父類物件,所得到物件是這樣的一個物件:
   它是一個編譯是為父類物件,但執行卻是一個子類物件,具體特徵如下.
   1.被宣告為父類物件
   2.擁有父類屬性
   3.佔用子類的記憶體空間
   4.子類方法覆蓋父類的方法時,此時物件呼叫的是子類的方法;否則,自動呼叫繼承父類的方法.
   5.我人認為這個物件既不是父類物件,也不是子類物件.當我們用到它的方法時,
   我便把它看成子類物件;若用到它的屬性時,我把它看成父類物件.
   它是一個佔用父類屬性,而使用子類方法的物件.至於到底是什麼物件,我認為還是得根據宣告來,它應算是父類物件,但擁有子類方法.
  
   想一想:
   在測試三的基礎上,我們如何取出子類的屬性?????

=================================================================

相關推薦

物件物件

最近對將子類物件賦值給父類物件有點心得,想和大家分享一下,但本人水平有限,請各位指正和批評。言歸正傳,下面是幾個小例子,請大家看一看。 測試一 父類: public class Supclass { public void print() {

[技術]初始化語義與語義

真的 class 基本 復制構造函數 spa 數值 復制構造 得到 對數 背景 博主是一個常年使用初始化語義的coder= =,所以經常會遇到這樣的對話 int tmp(0); XXX:誒,你這tmp函數是幹什麽的啊 博主:蛤?我哪裏定義了tmp函數了

map中的一個java物件

Map tag=new HashMap(); tag.put("001"," 張三"); tag.put("002","李四"); my_UpInfoVo my_UpInfoVo = new My_UpInfoVo(); BeanUtils.populate(my_UpInfoVo, tag); &n

js獲取元素下所有元素總寬度元素

網上 () func back 賦值 click button article ack 這個問題是今天在網上看到有人提的。 想要獲取#box下面所有div的寬度之和,然後賦值給#box,不論加多少個div,#box的寬都會隨著div的增加而改變。 <styl

實驗2-1-5 x的平方y

write .com pan company ati system rgs ack args package com.company; public class Main { public static void main(String[] args) {

解決vue A物件B物件,修改B屬性會影響到A的問題

實際在vue中 this.A = this.B,沒有進行深層賦值,只是把this.A的地址指向了與this.B相同的地址,所有對於A的修改會影響到B。 解決相互影響的思路是在this.A必須是新建的一個物件,這樣才能保證不被指向同一地址,屬性修改不會相互影響。 解決方式: 前端精品教程:百度網盤下載

hibernate映射實體查詢時數據庫空字段實體報錯的問題

config 設置 lan 實體 網上 pre ava more val   因為一直報實體類空異常,去網上查了資料只查到了並沒有查到數據庫空值時不給實體類賦值的屬性,只有這兩個屬性   這兩個屬性時設置 實體類有空字段插入或更新 數據庫時空屬性為默認值 異常 org.

python 基礎知識點(三)解壓可迭代物件多個變數

問題 如果一個可迭代物件的元素個數超過變數個數時,會丟擲一個 ValueError 。 那麼怎樣才能從這個可迭代物件中解壓出 N 個元素出來? 解決方案 Python 的星號表示式可以用來解決這個問題。比如,你在學習一門課程,在學期末的時候, 你想統計下家庭作業的平均成績,但是排除掉

Matlab獲取資料夾下所有檔名並資料按矩陣變數

fileFolder=fullfile('D:\MATLAB\bin\trc'); dirOutput=dir(fullfile(fileFolder,'*.trc')); fileNames={dirOutput.name}; n = 1; for i=fileNames

JAVA開發12--oracle查詢結果JAVA變數

        List<String> account_filter=new ArrayList<String>();  //陣列         String sql_a

js 物件複製 物件原型操作 把一個物件A另一個物件B 並且物件B 修改 不會影響 A物件

我最近在做一個vue + element-UI + vue-resource + vuex專案的時候,遇到了一個物件的問題。當我們在專案需要 複製一個物件到另一個物件並且  被複制的物件不能受複製後的物件的影響。我先總結下 我們哪些方法可以複製物件12345678910111

C++本質:運算符=的重載,以及深拷貝和拷貝

fin 過程 種類 解決 對象的引用 執行 面向 鏈式 alt 關鍵詞:構造函數,淺拷貝,深拷貝,堆棧(stack),堆heap,賦值運算符摘要: 在面向對象程序設計中,對象間的相互拷貝和賦值是經常進行的操作。 如果對象在申明的同時馬上進行的初始化操作,則

python中的物件(等號、深複製、複製)

程式碼: import copy class Obj(): def __init__(self,arg): self.x=arg if __name__ == '__main__': obj1=Obj(1) obj2=Obj(2)

Java向上轉型與向下轉型(物件的)

一.定義:    通俗理解向上轉型:    就是子類轉型成父類。   classA   {   }   classBextendsA   {   }   A b=new B();   這個就是向上轉型。   向上轉型可以像下面這條語句這麼簡單:   Shape s =new Circle();   這裡,建

物件繼承和沿用物件的屬性和屬性

子類物件繼承和沿用父類物件的屬性和屬性值 如果在父類中,直接給屬性賦值或者是在無參建構函式中給屬性賦值,那麼如果子類物件中沒有給自己的屬性賦值,那子類物件就會沿用父類物件的屬性值,即子類物件直接把父類物件的屬性的值沿用下來了! /** * 父類物件和子類物件的問題 */ pu

java中將物件物件

例子一 父類: public class Supclass   {   public void print()   {   System.out.println("this is 父類print()方法"+"——此時物件"+this.toString());   }   

怎樣中定義的CStringArray一個CStringArray

在同一個類裡邊你可以直接使用CStringArray &M = IP就可以了,如果想做一個拷貝的話,只能用迴圈了, for(int i=0; ii<IP.GetSize();   i++)  {           M.Add(IP.Get

如何字符串分割多個shell變量

lock ext shell變量 宋體 for prev spa str -a 如何將字符串分割賦值給多個shell變量shellTarget Target 比如字符串"111|222|333"分割分別賦值給三個shell變量 $ a=‘111|222|333

一個對象相同的屬性(不區分大小寫)一個新對象

spa name OS null tty return 賦值 AR val 1 public static T Mapper<S, T>(S source) 2 { 3 T t = Activator.Create