日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > java >内容正文

java

Java探索之旅(11)——抽象类与接口

發(fā)布時(shí)間:2023/12/10 java 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java探索之旅(11)——抽象类与接口 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

1.Java數(shù)據(jù)類型

? ? ? ?不可變類,是指當(dāng)創(chuàng)建了這個(gè)類的實(shí)例后,就不允許修改它的屬性值。 它包括: ? ? ? ??Primitive變量boolean,byte, char, double ,float, integer, long, short ? ? ? ? JDK不可變類Boolean, Byte, Character, Double, Float, Integer, Long, Short, String (java.lang包中) ? ? ??可變類,是當(dāng)你獲得這個(gè)類的一個(gè)實(shí)例引用時(shí),你可以改變這個(gè)實(shí)例的內(nèi)容。 可變類對(duì)象間用“=”賦值,則會(huì)是使兩個(gè)對(duì)象實(shí)際上會(huì)引用同一個(gè)實(shí)例。所以,只有實(shí)現(xiàn)深度clone才能使可變類對(duì)象的修改不影響原始對(duì)象的值。

? ? ??對(duì)于不可變類,可變類的特性也有意義,有的時(shí)候我們不希望重復(fù)創(chuàng)建相同的內(nèi)容的實(shí)例。因此,我們也可以利用不可變類獲得實(shí)例緩存。如:

? Integer a=Integer.valueOf(10); Integer b= Integer.valueOf(10);

? ? 只會(huì)在第一次創(chuàng)建取值為10的Integer對(duì)象。也就是說(shuō)a和b指向同一處內(nèi)存上的內(nèi)容。


2.抽象類

? ? ?繼承層次結(jié)構(gòu)中。父類通用而不明確,子類越來(lái)越明確和具體。接口是定義多個(gè)類的共同行為。

? ? ?抽象關(guān)鍵字abstract,位置緊隨訪問(wèn)修飾符(public,protected,private)之后。

? ? ?抽象類的構(gòu)造函數(shù)一律定義為protected。抽象方法只有定義沒(méi)有實(shí)現(xiàn)(一般定義為public,且抽象方法禁止定義為靜態(tài)方法)。

? ? ?包含抽象方法的類必須定義為抽象類。抽象類不一定需要包含抽象方法。

? ? ?若子類沒(méi)有實(shí)現(xiàn)父類的抽象方法。子類仍需要定義為抽象類。即,抽象類派生出的非抽象子類,必須實(shí)現(xiàn)所有基類的抽象方法,即使它沒(méi)有使用

? ? ?父類為具體類,子類可以是抽象類。子類可以覆蓋父類的方法并將其定義為抽象方法,當(dāng)然前提是子類定義為抽象類。

? ? ?new無(wú)法作用抽象類創(chuàng)建實(shí)例,但是可以作為一種數(shù)據(jù)類型,創(chuàng)建引用變量(或者引用數(shù)組),然后指向子類對(duì)象。當(dāng)然其引用類型也可以作為函數(shù)參數(shù)。

? ? ?如下定義抽象類Gobject。定義兩個(gè)擴(kuò)展類圓Circle和長(zhǎng)方形rectangle。定義抽象方法getArea()返回面積

package GeometricObject; public abstract class Gobject {private String color="white";private boolean filled;private java.util.Date dateCreated;//時(shí)間類//構(gòu)造函數(shù)必須定義protectedprotected Gobject(){dateCreated=new java.util.Date();}protected Gobject(String s,boolean f){this();filled=f;color=s;}public String toString(){return "Created on:"+dateCreated+"\ncolor:"+color+"\nfilled with?--"+filled;}public void setColor(final String s){color=s;}public String getColor(){return color;}public abstract double getArea();//抽象方法 }//圓類 class Circle extends Gobject implements Comparable,Cloneable{double radius;final static double PI=3.1415;Circle(){radius=1.0;}//隱含調(diào)用super();Circle(double r,String s,boolean f){super(s,f);//調(diào)用父類構(gòu)造函數(shù)radius=r;}public String toString(){return super.toString()+"\nArea--"+getArea();} }//長(zhǎng)方形類 class rectangle extends Gobject implements Comparable,Cloneable{//常用方法,從虛函數(shù)中擴(kuò)展double width,height;rectangle (){width=height=1.0;}//隱含調(diào)用super();rectangle(double w,double h,String s,boolean f){super(s,f);//調(diào)用父類構(gòu)造函數(shù)width=w;height=h;}public double getArea(){return width*height;} }


? 測(cè)試如下:

public class test {public static void main(String[] args){Gobject[] p=new Gobject[2];//抽象類作為數(shù)據(jù)類型定義數(shù)組p[0]=new Circle(2.3,"Blue",true);p[1]=new rectangle(4.0,5.0,"Red",false);System.out.println(p[0].toString());System.out.println(p[1].toString());System.out.println("The two Object have "+equalArea(p[0],p[1])+" area");public static String equalArea(Gobject o1,Gobject o2)//抽象類引用類型作為函數(shù)參數(shù){if(o1.getArea()==o2.getArea())//JVM動(dòng)態(tài)調(diào)用實(shí)例的函數(shù)return "same";elsereturn "different";} }


3.接口

? ??類似于類,目的是指明多個(gè)對(duì)象的共同行為。

? ??接口類似于抽象類。編譯為單獨(dú)的字節(jié)碼文件。不能使用new創(chuàng)建實(shí)例,但是可以聲明引用變量或者作為類型轉(zhuǎn)換的結(jié)果。

? ??接口僅僅包括常量和抽象方法或者完全為空(所謂的標(biāo)記接口maker interface)。即所有的方法默認(rèn)都是public abstract,所有的變量都是public final static<

? ??接口類定義的常量可以使用“接口名.變量名”訪問(wèn)。


4.可比較接口 Comparable

? ? ? ??Java中的許多類,比如String和Data實(shí)現(xiàn)(implements)Comparable接口,以比較自然對(duì)象的大小。

? ??接口引用變量可作函數(shù)參數(shù)類型和返回類型。聲明如下:

public interface Comparable //比較接口{int comparaTo(Object o);//判斷當(dāng)前對(duì)象與目標(biāo)對(duì)象的大小} ? ?定義的通用求最大值的Max函數(shù)如下:

//通用的求最大值的類 //接口引用作為函數(shù)參數(shù)和返回參數(shù),此時(shí)類似虛函數(shù) public class Max {public static Comparable max(Comparable a,Comparable b){if(a.comparaTo(b)>0)//調(diào)用具體的比較函數(shù)return a;elsereturn b;} }

? ?Circlerectangle分別實(shí)現(xiàn)了該接口,即繼承了接口的抽象方法,并具體實(shí)現(xiàn)。如下:

class Circle extends Gobject implements Comparable,Cloneable{......................public int comparaTo(Object o){//繼承并且實(shí)現(xiàn)camparaTo函數(shù)if(getArea()>((Gobject)o).getArea())//顯式轉(zhuǎn)換return 1;else if(getArea()<((Gobject)o).getArea())return -1;elsereturn 0;}................. }class rectangle extends Gobject implements Comparable,Cloneable{//常用方法,從虛函數(shù)中擴(kuò)展..................public int comparaTo(Object o){//繼承并且實(shí)現(xiàn)camparaTo函數(shù)if(getArea()>((Gobject)o).getArea())return 1;else if(getArea()<((Gobject)o).getArea())return -1;elsereturn 0;}..................... }

? ? 利用Max求兩個(gè)圓或者兩個(gè)長(zhǎng)方體最大的面積的代碼片段為

//Comparable 接口//使用通用的Max類,比較任意擴(kuò)展了comparable的對(duì)象Circle[] cp=new Circle[2];cp[0]=new Circle(1.56,"Blue",true);cp[1]=new Circle(3.45,"Green",false);Comparable max=Max.max(cp[0], cp[1]);//接口類型引用System.out.println("The max Area of 2 Circle is "+((Circle)max).getArea());//顯式轉(zhuǎn)換rectangle[] rp=new rectangle[2];rp[0]=new rectangle(1.56,12.0,"Blue",true);rp[1]=new rectangle(3.45,6.7,"Green",false);Comparable max1=Max.max(rp[0], rp[1]);//接口類型引用System.out.println("The max Area of 2 rectangle is "+((rectangle)max1).getArea());//顯式轉(zhuǎn)換

? ?由于max輸出的類型為Comparable類型,所以調(diào)用Circle或者rectangle的getArea()函數(shù)必須顯式轉(zhuǎn)換


5.可克隆接口?Cloneable

? ??該接口為標(biāo)記接口,即無(wú)常量和方法。標(biāo)記用來(lái)表示類擁有某種屬性。定義如下:

public interface Cloneable {}

? ? ?對(duì)于可復(fù)制的類,必須滿足: 實(shí)現(xiàn)Cloneable接口。這樣才有資格調(diào)用Object.clone()方法 覆蓋Object的clone()方法。Object.clone()方法是protected的,覆蓋并改為public

? ??Object的clone的行為是最簡(jiǎn)單的。以堆上的內(nèi)存存儲(chǔ)解釋的話(不計(jì)內(nèi)存),對(duì)一個(gè)對(duì)象a的clone就是在堆上分配一個(gè)和a在堆上所占存儲(chǔ)空間一樣大的一塊地方,然后把a(bǔ)的堆內(nèi)存的內(nèi)容按位(bit-wise)復(fù)制到這個(gè)新分配的內(nèi)存。

? ??Primitive數(shù)據(jù)類型(如int,double)為深拷貝,引用類型(包括可變類和不可變類)均為淺拷貝,淺拷貝指拷貝前后引用變量指向同一對(duì)象。深拷貝或者克隆的目的在數(shù)據(jù)前后隔離,默認(rèn)的淺copy不是隔離的——即改變copy的東西,會(huì)影響到原型的內(nèi)部。

? ??改變拷貝對(duì)象的Primitive數(shù)據(jù)值或者不可變類引用變量(如String)的指向?qū)ο?#xff0c;不影響源對(duì)象的對(duì)應(yīng)數(shù)據(jù),即滿足數(shù)據(jù)隔離。前者的原因顯而易見(jiàn),后者的原因是因?yàn)?--不可變類不能通過(guò)【對(duì)象名+"."方法(數(shù)據(jù))】改變數(shù)據(jù)域,只能通過(guò)將其指向其他對(duì)象改變其數(shù)據(jù)域,如此一來(lái),肯定不影響。具體點(diǎn)擊

? ?對(duì)于前面定義的Circle,rectangle類,實(shí)現(xiàn)Coloneable接口如下:

class Circle extends Gobject implements Comparable,Cloneable{......................public Object clone() throws CloneNotSupportedException{return super.clone();}......................}//長(zhǎng)方形類 class rectangle extends Gobject implements Comparable,Cloneable{//常用方法,從虛函數(shù)中擴(kuò)展.......................public Object clone() throws CloneNotSupportedException{return super.clone();}....................... }?注意

? ? ①由于返回的為Object,可能需要顯式轉(zhuǎn)換。

? ? ②使用super.clone()而非this.clone()的原因。Object中的clone執(zhí)行的時(shí)候使用了RTTI(run-time type identification)的機(jī)制,動(dòng)態(tài)得找到目前正在調(diào)用clone方法的reference,根據(jù)它的大小申請(qǐng)內(nèi)存空間,然后進(jìn)行bitwise的復(fù)制,將該對(duì)象的內(nèi)存空間完全復(fù)制到新的空間中去,從而達(dá)到shallowcopy的目的。所以調(diào)用super.clone() 得到的是當(dāng)前調(diào)用類的副本,而不是父類的副本。根本沒(méi)有必用調(diào)用this.clone()

? ? ③如果需要克隆的類引用到了其它的類的對(duì)象,甚至這個(gè)對(duì)象也引用到了別的對(duì)象,那么在必要情況下,你需要將這個(gè)對(duì)象樹(shù)進(jìn)行完整的克隆。如下:

class User implements Cloneable {String name;int age;@Overridepublic User clone() throws CloneNotSupportedException {return (User) super.clone();} }class Account implements Cloneable {User user;long balance;@Overridepublic Account clone() throws CloneNotSupportedException {Account account = (Account) super.clone();if (user != null) {account.user = user.clone();//顯式深拷貝}return account;} }

6.抽象類和接口的比較

? ??變量:抽象類無(wú)限制;接口必須為public static final ? ??構(gòu)造方法:抽象類子類經(jīng)過(guò)構(gòu)造鏈調(diào)用構(gòu)造法。接口無(wú)構(gòu)造方法。兩者均不能用new實(shí)例化 ? ??方法:抽象類無(wú)限制;接口必須是public abstract ? ??抽象類只能(被)單一擴(kuò)展;類可以同時(shí)實(shí)現(xiàn)多重接口,接口同時(shí)可以同時(shí)繼承多重接口而不是類。 ? ??所有類有公共根Object;而所有接口沒(méi)有公共接口。 ? ??兩者均可以定義類型,且引用變量可以引用---任何實(shí)現(xiàn)了接口(或抽象類)的對(duì)象。 ? ? 一般而言,父子關(guān)系強(qiáng),使用抽象類;弱使用接口。接口可以定義不相關(guān)類共有的父類型(例如房屋可以比較面積,數(shù)值可以比較大小,使用comparable接口)。抽象類更加使用方便,接口更加靈活。 ? ?注意:?如果向一個(gè)抽象類里加入一個(gè)新的具體方法時(shí),那么它所有的子類都一下子都得到了這個(gè)新方法。接口做不到這一點(diǎn),如果向一個(gè)Java接口里加入一個(gè) 新方法,所有實(shí)現(xiàn)這個(gè)接口的類就無(wú)法成功通過(guò)編譯了,因?yàn)槟惚仨氉屆恳粋€(gè)類都再實(shí)現(xiàn)這個(gè)方法才行,這顯然是Java接口的缺點(diǎn)之一。? ? ? ? ? ? ? ? ?經(jīng)典的使用方法 A extends AbstractB implements interfaceC 詳細(xì)可點(diǎn)擊:Java 接口和抽象類區(qū)別



參考: ? ? 1.深入理解java的clone ? ? 2.java.lang.Cloneable接口 ? ? 3.Java的clone機(jī)制及其可變類與不可變類

轉(zhuǎn)載于:https://www.cnblogs.com/engineerLF/p/5393089.html

總結(jié)

以上是生活随笔為你收集整理的Java探索之旅(11)——抽象类与接口的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。