ReusingClasses
有两种常用方式实现类的重用,组件(在新类中创建存在类的对象)和继承。
Compositionsyntax
Everynon-PRimitiveobjecthasatoString()method,andit’scalledinspecialsituationswhenthecompilerwantsaStringbutithasanobject.
Inheritancesyntax
You’realwaysdoinginheritancewhenyoucreateaclass,becauseunlessyouexplicitlyinheritfromsomeotherclass,youimplicitlyinheritfromjava’sstandardrootclassObject.
Toallowforinheritance,asageneralrulemakeallfieldsprivateandallmethodspublic.Ofcourse,inparticularcasesyoumustadjustments,butthisisausefulguideline.
|_Initializingthebaseclass
Evenifyoudon’tcreateaconstructorforderived-class,thecompilerwillsynthesizeadefaultconstructorforyouthatcallsthebaseconstructor.
Ifyourclassdoesn’thavedefaultarguments,orifyouwanttocallabase-classconstructorthathasanargument,youmustexplicitlywritethecallstothebase-classconstructorusingthesuperkeyWordandtheappropriateargumentlist.Inaddition,thecalltothebase-classconstructormustbethefirstthingyoudointhederived-classconstructor.
Delegation
委托是重用类的第三种方式,介于继承和组件之间。在新建类中放置成员对象(像组件),同时暴露该对象的所有方法(像继承)。Youhavemorecontrolwithdelegationbecauseyoucanchoosetoprovideonlyasubsetofthemethodsinthememberobject.
Combiningcompositionandinherit
|_Guaranteeingpropercleanup
Notethatinyourcleanupmethod,youmustalsopayattentiontothecallingorderforthebase-classandmember-objectcleanupmethodsincaSEOnesubobjectdependsonanother.Ingeneral,youshouldfollowthesameformthatisimposedbyaC++compileronitsdestructors:Firstperformallofthecleanupworkspecifictoyourclass,inthereverseorderofcreation.
Therecanbemanycasesinwhichthecleanupissueisnotaproblem;youjustletthegarbagecollectordothework.Butwhenyoumustdoitexplicitly,diligenceandattentionarerequired,becausethere’snotmuchyoucanrelyonwhenitcomestogarbagecollection.Thegarbagecollectormightneverbecalled.Ifitis,itcanreclaimobjectsinanyorderitwants.Youcan’trelyongarbagecollectionforanythingbutmemoryreclamation.Ifyouwantcleanuptotakeplace,makeyourowncleanupmethodsanddon’tuseonfinalize().
Choosingcompositionvs.inheritance
Bothcompositionandinheritanceallowyoutoplacesubobjectinsideyournewclass(compositionexplicitlydoesthis-withinheritanceit’simplicit).
Theis-arelationshipisexpressedwithinheritance,andthehas-arelationshipisexpressedwithcomposition.
Upcasting
Inobject-orientedprogramming,themostlikelywaythatyou’llcreateandusecodeisbysimplypackagingdataandmethodstogetherintoaclass,andusingobjectsofthatclass.You’llalsouseexistingclassestobuildnewclasseswithcomposition.Lessfrequently,you’lluseinheritance.SoalthoughinheritancegetsalotofemphasiswhilelearningOOP,itdoesn’tmeanthatyoushoulduseiteverywhereyoupossiblycan.Onthecontrary,youshoulduseitsparingly,onlywhenit’sclearthatinheritanceisuseful.Oneoftheclearestwaystodeterminewhetheryoushouldusecompositionorinheritanceistoaskwhetheryou’lleverneedtoupcastfromyournewclasstothebaseclass.Ifyoumustupcast,theninheritanceisnecessary.ThePolymorphismprovidesoneofthemostcompellingreasonsforupcasting,butifyouremembertoask“DoIneedtoupcast?”you’llhavaagoodtoolfordecidingbetweencompositionandinheritance.
Thefinalkeyword
Therearethereplaceswherefinalcanbeused:fordata,methodsandclasses.
|_finaldata
Thatapieceofdataisconstantisusefulfortworeasons:
1.Itcanbeacompile-timeconstantthatwon’teverchange.
2.Itcanbeavalueinitializedatruntimethatyoudon’twantchanged.
Inthecaseofacompile-timeconstant,thecompilerisallowedto“fold”theconstantvalueintoanycalculationsinwhichit’sused;thatis,thecalculationcanbeperformedatcompiletime,eliminatingsomerun-timeoverhead.InJava,thesesortsofconstantsmustbeprimitivesandareexpressedwiththefinalkeyword.Avaluemustbegivenatthetimeofdefinitionofsuchaconstant.
当final被用于对象引用上时,对象的引用不能被更改,即该引用不能指向其他对象,但是对象本身可以被修改。这个规则对隶属于对象的数组引用同样适用。
在定义时不赋初值的final变量必须在使用之前被初始化(比如在构造体中初始化,staticfinal不能在构造体中初始化,因为static不依赖于对象而存在),否则编译报错。You’reforcedtoperformassignmentstofinalseitherwithanexpressionatthepointofdefinitionofthefieldorineveryconstructor.Thatwayit’sguaranteedthatthefinalfieldisalwaysinitializedbeforeuse.
|_finalarguments
参数被final修饰时可读不可写。Thisfeatureisprimarilyusedtopassdatatoanonymousinnerclasses.
|_finalmethods
用final修饰的方法不能被重写。
|_finalandprivate
Anyprivatemethodsinaclassareimplicitlyfinal.Becauseyoucan’taccessaprivatemethod,youcan’toverrideit.Youcanaddthefinalspecifiertoaprivatemethod,butitdoesn’tgivethatmethodanyextrameaning.
“Overriding”canonlyoccurifsomethingispartofthebase-classinterface.Thatis,youmustbeabletoupcastanobjecttoitsbasetypeandcallthesamemethod.Ifamethodisprivate,itisn’tpartofthebase-classinterface.Itisjustsomecodethat’shiddenawayinsidetheclass,anditjusthappenstohavathename,butifyoucreateapublic,protected,orpackage-accessmethodwiththesamenameinthederivedclass,there’snoconnectiontothemethodthatmighthappentohavethatnameinthebaseclass.Youhaven’toverriddenthemethod;you’vejustcreatedanewmethod.Sinceaprivatemethodisunreachableandeffectivelyinvisible,itdoesn’tfactorintoanythingexceptforthecodeorganizationoftheclassforwhichitwasdefined.
|_finalclasses
Whenyousaythatanentireclassisfinal(byprecedingitsdefinitionwiththefinalkeyword),youstatethatyoudon’twanttoinheritfromthisclassorallowanyoneelsetodoso.Inotherwords,forsomereasonthedesignofyourclassissuchthatthereisneveraneedtomakeanychanges,orforsafetyorsecurityreasonsyoudon’twantsubclassing.
Notethatthefieldofafinalclasscanbefinalornot,asyouchoose.Thesamerulesapplytofinalforfieldsregardlessofwhethertheclassisdefinedasfinal.However,becauseitpreventsinheritance,allmethodsinafinalclassareimplicitlyfinal,sincethere’snowaytooverridethem.Youcanaddthefinalspecifiertoamethodinafinalclass,butitdoesn’taddanymeaning.
Initializationandclassloading
InJava,thecompiledcodeforeachclassexistsinitsownseparatefile.Thatfileisn’tloadeduntilthecodeisneeded.Ingeneral,youcansaythat“classcodeisloadedatthepointoffirstuse.”Thisisusuallywhenthefirstobjectofthatclassisconstructed,butloadingalsooccurswhenastaticfieldorstaticmethodisaccessed(Theconstructorisalsoastaticmethodseventhoughthestatickeywordisnotexplicit.Sotobeprecise,aclassisfirstloadedwhenanyoneofitsstaticmembersisaccessed.).
|_Initializationwithinheritance
第一次运行主类的main方法时,装载器找到该类对应的class文件,在装载的过程中如果发现它有父类,则继续装载其父类,父类还有父类,继续装载。接下来,在根类开始执行静态初始化,接下来是其派生类,等等。这是重要的,因为派生类静态初始化可能依赖父类成员被合理的初始化。
Atthispoint,thenecessaryclasseshavaallbeenloadedsotheobjectcanbecreated.First,alltheprimitivesinthisobjectaresettotheirdefaultvaluesandtheobjectreferencesaresettonull-thishappensinonefellswoopbysettingthememoryintheobjecttobinaryzero.Thenthebase-classconstructorwillbecalled.Inthiscasethecallisautomatic,butyoucanalsospecifythebase-classconstructorcallbyusingsuper.Thebaseclassconstructiongoesthroughthesameprocessinthesameorderasthederived-classconstructor.Afterthebase-classconstructorcompletes,theinstancevariablesareinitializedintextualorder.Finally,therestofthebodyoftheconstructorisexecuted.
Summary
Bothinheritanceandcompositionallowyoutocreateanewtypefromexistingtypes.Compositionreusesexistingtypesaspartoftheunderlyingimplementationofthenewtype,andinheritancereusestheinterface.
(END_XPJIANG)
新闻热点
疑难解答