亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Java多態(tài)的使用注意事項(xiàng)

 更新時(shí)間:2013年11月14日 14:38:11   作者:  
本文講解了什么是JAVA多態(tài)和Java多態(tài)是如何實(shí)現(xiàn)的,在使用Java多態(tài)時(shí)需要注意什么,具體大家看下面的內(nèi)容

Java多態(tài)是如何實(shí)現(xiàn)的?
Java的多態(tài)和C++一樣,是通過延時(shí)綁定(late binding)或者說運(yùn)行時(shí)綁定(runtime binding)來實(shí)現(xiàn)的。當(dāng)調(diào)用某一個(gè)對象引用的方法時(shí),因?yàn)榫幾g器并不知道這個(gè)引用到底指向的是變量聲明時(shí)說明的類型對象,還是該類型子類的對象。因此編譯器無法為這次調(diào)用綁定到具體的某個(gè)方法。只有通過java中的運(yùn)行時(shí)類型識別(RTTI, Runtime type identification)在運(yùn)行時(shí)綁定到具體的方法。下面是一個(gè)具體的例子:

復(fù)制代碼 代碼如下:

class shape
{
    public void draw()
    {

   print("shape");
    }
}
class triangle extends shape
{
    public void draw()
    {

   print("triangle");
    }
}
public class Polymorphism {
public static void main(String[] args)
{
    shape s=new triangle();
    s.draw();
}


結(jié)果是triangle
s是一個(gè)shape引用,但是在運(yùn)行時(shí)因?yàn)槭莟riangle對象,所以還是調(diào)用了triangle的draw方法。

Java多態(tài)中的一些陷阱

重寫私有方法?
Java里面是不能重寫私有方法的,這個(gè)其實(shí)很好理解,因?yàn)樗接蟹椒ㄔ谧宇愂遣豢梢姷?。子類沒有繼承父類的私有方法,更談不上重寫了。因此在子類中的同名方法是一個(gè)全新的方法。

復(fù)制代碼 代碼如下:

public class Polymorphism {
    private void show()
    {

   print("show parent");
    }
public static void main(String[] args)
{
    Polymorphism p=new privateMethod();
    p.show();
}
}
class privateMethod extends Polymorphism
{
    public void show()
    {

   print("show derived");
    }
}


結(jié)果是 show parent

字段和靜態(tài)方法的多態(tài)?
子類可以繼承父類的非私有字段,子類的字段是否也具有多態(tài)性呢?我們來看一個(gè)實(shí)際的例子:

復(fù)制代碼 代碼如下:

class shape
{
    protected int perimeter=1;
    public void draw()
    {

   print("shape");
    }
    public int getPerimeter()
    {

   return perimeter;
    }
}
class triangle extends shape
{

int perimeter=3;
    public void draw()
    {

   print("triangle");
    }
    public int getPerimeter()
    {

   return perimeter;
    }
    public int getSuperPerimeter()
    {

   return super.perimeter;
    }
}
public class Polymorphism {

public static void main(String[] args)
{
    shape s=new triangle();
    print("s.perimeter:"+s.perimeter);
    print("s.getperimeter:"+s.getPerimeter());
    triangle t=new triangle();
    print("t.perimeter:"+t.perimeter);
    print("t.getperimeter:"+t.getPerimeter());
    print("t.getsuperperimeter:"+t.getSuperPerimeter());
}
}


以下是運(yùn)行結(jié)果:

這個(gè)運(yùn)行結(jié)果包含了以下信息:
1.triangle對象向上轉(zhuǎn)型成shape后字段直接訪問都是由編譯器確定的,因此不會(huì)表現(xiàn)出多態(tài)性,返回的是1。
2.triangle對象向上轉(zhuǎn)型成shape后調(diào)用方法訪問字段是根據(jù)運(yùn)行時(shí)對象類型延時(shí)綁定調(diào)用了triangle的getperimeter方法,返回的是3
3.t對象中包含了兩個(gè)perimeter字段,一個(gè)來自于他本身,一個(gè)來自于他的父類。同時(shí)用字段名去調(diào)用該字段時(shí)默認(rèn)返回的是他本身的perimeter字段,要調(diào)用從父類繼承的該字段,要用super.perimeter的方法。
這個(gè)結(jié)果看起來多多少少讓人有些疑惑,為了避免這種情況出現(xiàn),我們一般都把字段聲明為private(子類就無法繼承),同時(shí)我們在子類中聲明的字段最好不要與從父類繼承的字段同名。
靜態(tài)方法是沒有多態(tài)性的,因?yàn)殪o態(tài)方法是和類綁定的,不會(huì)存在不知道具體類型的情況。

構(gòu)造函數(shù)的多態(tài)性?
構(gòu)造函數(shù)是不具有多態(tài)性的,因?yàn)闃?gòu)造方法本身是靜態(tài)方法(如果不是的話,就會(huì)陷入雞生蛋,蛋生雞的死循環(huán)了)。要引入我們的問題,先來看一下構(gòu)造函數(shù)的調(diào)用順序。
1.為這個(gè)對象分配的存儲空間都被初始化為0(對象初始化為null)
2.父類的構(gòu)造函數(shù)調(diào)用(這樣才能保證在子類的構(gòu)造函數(shù)中訪問的字段被初始化)
3.成員變量初始化
4.子類的構(gòu)造函數(shù)調(diào)用

現(xiàn)在假設(shè)如果在第二步中,我們在父類的構(gòu)造函數(shù)里調(diào)用了某個(gè)方法,這個(gè)方法是不是多態(tài)的?還是來看一個(gè)具體的例子:

復(fù)制代碼 代碼如下:

class shape
{
    protected int perimeter=1;
    public shape()
    {

   draw();

   print("shape created");
    }
    public void draw()
    {

   print("draw shape "+perimeter);
    }

}
class triangle extends shape
{

int perimeter=3;

public triangle()

{

    print("triangle created");

}
    public void draw()
    {

   print("draw triangle "+perimeter);
    }
    public int getPerimeter()
    {

   return perimeter;
    }
}

public class Polymorphism {

public static void main(String[] args)
{
    shape s=new triangle();
}
}


運(yùn)行結(jié)果:

 

我們可以看到雖然triangle對象還沒有構(gòu)造完畢,draw方法仍是動(dòng)態(tài)綁定到了triangle的draw方法。同時(shí)注意到perimeter的值還沒有初始化為3,而是0。

這樣的結(jié)果就是我們在triangle對象還沒有被初始化之前就訪問了其中的字段。因此我們在實(shí)際應(yīng)用中要避免在構(gòu)造函數(shù)中調(diào)用其他方法,或者只調(diào)用私有方法(不會(huì)被繼承,因此不會(huì)引發(fā)該問題)

相關(guān)文章

  • springboot框架的全局異常處理方案詳解

    springboot框架的全局異常處理方案詳解

    這篇文章主要介紹了springboot框架的全局異常處理方案,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-03-03
  • java動(dòng)態(tài)構(gòu)建數(shù)據(jù)庫復(fù)雜查詢教程

    java動(dòng)態(tài)構(gòu)建數(shù)據(jù)庫復(fù)雜查詢教程

    這篇文章主要介紹了java動(dòng)態(tài)構(gòu)建數(shù)據(jù)庫復(fù)雜查詢的實(shí)現(xiàn)示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2021-11-11
  • springboot集成nacos的配置方法

    springboot集成nacos的配置方法

    這篇文章主要介紹了springboot集成nacos的配置方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-03-03
  • Java面向?qū)ο笾^承的概念詳解

    Java面向?qū)ο笾^承的概念詳解

    這篇文章主要介紹了Java面向?qū)ο笾^承的概念詳解,Java是一種面向?qū)ο蟮木幊陶Z言,繼承是實(shí)現(xiàn)面向?qū)ο缶幊痰幕A(chǔ)之一。通過繼承,我們可以使代碼更具可讀性、可重用性和可維護(hù)性,從而提高程序的效率和可靠性,需要的朋友可以參考下
    2023-04-04
  • java swing實(shí)現(xiàn)電影購票系統(tǒng)

    java swing實(shí)現(xiàn)電影購票系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了java swing實(shí)現(xiàn)電影購票系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-01-01
  • 官方詳解HDFS?Balancer工具主要調(diào)優(yōu)參數(shù)

    官方詳解HDFS?Balancer工具主要調(diào)優(yōu)參數(shù)

    這篇文章主要為大家介紹了HDFS?Balancer工具主要調(diào)優(yōu)參數(shù)的?官方詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-03-03
  • 如何使用Java操作Zookeeper

    如何使用Java操作Zookeeper

    這篇文章主要介紹了如何使用Java操作Zookeeper,幫助大家更好的理解和學(xué)習(xí)使用Java,感興趣的朋友可以了解下
    2021-04-04
  • Java案例使用比較排序器comparator實(shí)現(xiàn)成績排序

    Java案例使用比較排序器comparator實(shí)現(xiàn)成績排序

    這篇文章主要介紹了Java案例使用比較排序器comparator實(shí)現(xiàn)成績排序,主要通過案例用TreeSet集合存儲多個(gè)學(xué)生信息,并遍歷該集合,要按照總分從高到低進(jìn)行排序,下文介紹需要的朋友可以參考一下
    2022-04-04
  • Java枚舉學(xué)習(xí)之定義和基本特性詳解

    Java枚舉學(xué)習(xí)之定義和基本特性詳解

    枚舉是JAVA?5.0后增加的一個(gè)重要類型??梢杂脕肀硎疽唤M取值范圍固定的變量。本文將通過示例為大家詳細(xì)講解枚舉的定義和基本特性,感興趣的可以了解一下
    2022-08-08
  • 解決Spring Security 用戶帳號已被鎖定問題

    解決Spring Security 用戶帳號已被鎖定問題

    這篇文章主要介紹了解決Spring Security 用戶帳號已被鎖定問題,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-01-01

最新評論