[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"\u002Fresource\u002Fdocument\u002Flist?undefined":3,"\u002Fresource\u002Fdocument\u002Fquery\u002Fc93u3v37br7hgn1q?undefined":462,"\u002Fresource\u002Fadvertise\u002Flist?type=all?undefined":465},{"data":4,"status":460,"success":461},[5,148,202,291,332,370,420],{"books":6,"desc":145,"id":8,"image":146,"title":147},[7,40,63,78,93,105,117],{"cateId":8,"chapters":9,"desc":36,"id":11,"time":37,"title":38,"video":39},1,[10,15,18,21,24,27,30,33],{"bookId":11,"id":12,"indexOrder":13,"name":14},24,"8egfulw98v3h680j",0,"JavaSE 笔记（一）走进Java语言",{"bookId":11,"id":16,"indexOrder":13,"name":17},"pew6po6wrou23pk3","JavaSE 笔记（二）面向过程编程",{"bookId":11,"id":19,"indexOrder":13,"name":20},"eldst1fgrbdkmfs7","JavaSE 笔记（三）面向对象基础",{"bookId":11,"id":22,"indexOrder":13,"name":23},"48zphgkpjto8cath","JavaSE 笔记（四）面向对象高级篇",{"bookId":11,"id":25,"indexOrder":13,"name":26},"6r4llai92yc15j98","JavaSE 笔记（五）泛型程序设计",{"bookId":11,"id":28,"indexOrder":13,"name":29},"k6fmxd6qabgkwm9i","JavaSE 笔记（六）集合类与IO",{"bookId":11,"id":31,"indexOrder":13,"name":32},"qrd0xfttsz32gpqg","JavaSE 笔记（七）多线程与反射",{"bookId":11,"id":34,"indexOrder":13,"name":35},"td5tgn04nqmkrryt","JavaSE 笔记（八）GUI程序开发","基于Java25全新录制的SE课程",2025,"JavaSE 核心内容","https:\u002F\u002Fwww.bilibili.com\u002Fvideo\u002FBV163GGz2E8c",{"cateId":8,"chapters":41,"desc":59,"id":8,"time":60,"title":61,"video":62},[42,44,46,49,51,53,55,57],{"bookId":8,"id":43,"indexOrder":13,"name":14},"ibeeuwsbbi00undq",{"bookId":8,"id":45,"indexOrder":13,"name":17},"dncxjecdv4wciqcp",{"bookId":8,"id":47,"indexOrder":13,"name":48},"jviyz2hsht9ete5k","JavaSE 笔记（三）面向对象基础篇",{"bookId":8,"id":50,"indexOrder":13,"name":23},"qb9i6q9fap7bg1cc",{"bookId":8,"id":52,"indexOrder":13,"name":26},"hnkrjrkm3hjzeq6s",{"bookId":8,"id":54,"indexOrder":13,"name":29},"erpm32wduoaaqmrx",{"bookId":8,"id":56,"indexOrder":13,"name":32},"lfqtvxr7azumcwja",{"bookId":8,"id":58,"indexOrder":13,"name":35},"qs7gqok56gzc6idr","2022年制作的JavaSE版本",2022,"JavaSE 22年旧版","https:\u002F\u002Fwww.bilibili.com\u002Fvideo\u002FBV1YP4y1o75f\u002F",{"cateId":8,"chapters":64,"desc":75,"id":66,"time":60,"title":76,"video":77},[65,69,72],{"bookId":66,"id":67,"indexOrder":13,"name":68},2,"g96k66kczovvbm1i","JVM 笔记（一）走进JVM",{"bookId":66,"id":70,"indexOrder":13,"name":71},"ydd7n3jg8unc3clg","JVM 笔记（二）内存管理",{"bookId":66,"id":73,"indexOrder":13,"name":74},"r9dq37de0kaeauoi","JVM 笔记（三）类与类加载","了解Java的底层运作机制","Java JVM 虚拟机","https:\u002F\u002Fwww.bilibili.com\u002Fvideo\u002FBV1Er4y1r7as\u002F",{"cateId":8,"chapters":79,"desc":90,"id":81,"time":60,"title":91,"video":92},[80,84,87],{"bookId":81,"id":82,"indexOrder":13,"name":83},3,"asncyye9ya18gfar","JUC 笔记（一）再谈多线程",{"bookId":81,"id":85,"indexOrder":13,"name":86},"5tr1sm4ho6ygpt9q","JUC 笔记（二）并发编程核心",{"bookId":81,"id":88,"indexOrder":13,"name":89},"1scf51z5300mzxkh","JUC 笔记（三）并发编程进阶","你也可以成为多线程的主宰者","Java JUC 并发编程","https:\u002F\u002Fwww.bilibili.com\u002Fvideo\u002FBV1JT4y1S7K8\u002F",{"cateId":8,"chapters":94,"desc":102,"id":96,"time":60,"title":103,"video":104},[95,99],{"bookId":96,"id":97,"indexOrder":13,"name":98},4,"eedesc445ygiqhil","NIO 笔记（一）基础内容",{"bookId":96,"id":100,"indexOrder":13,"name":101},"ndz9t0uunrmfmv4n","NIO 笔记（二）Netty框架专题","编写畅快的高性能网络服务器","Java NIO 网络编程","https:\u002F\u002Fwww.bilibili.com\u002Fvideo\u002FBV1ar4y1J7mC\u002F",{"cateId":8,"chapters":106,"desc":114,"id":108,"time":60,"title":115,"video":116},[107,111],{"bookId":108,"id":109,"indexOrder":13,"name":110},5,"9890i8ofuadpwy2b","[扩展篇] Java 9-17新特性介绍",{"bookId":108,"id":112,"indexOrder":13,"name":113},"tsrkqvb6zpmtwh0n","[扩展篇] JavaSE关键字总结 笔记","精彩仍在继续，不要停止脚步","其他内容","https:\u002F\u002Fwww.bilibili.com\u002Fvideo\u002FBV1tU4y1y7Fg\u002F",{"cateId":8,"chapters":118,"desc":141,"id":120,"time":142,"title":143,"video":144},[119,123,126,129,132,135,138],{"bookId":120,"id":121,"indexOrder":13,"name":122},6,"4db9h32opv7imszh","JavaSE 笔记（一）面向过程编程",{"bookId":120,"id":124,"indexOrder":13,"name":125},"c93u3v37br7hgn1q","JavaSE 笔记（二）面向对象基础篇",{"bookId":120,"id":127,"indexOrder":13,"name":128},"yglsjde9gi1jxkcb","JavaSE 笔记（三）泛型与集合类",{"bookId":120,"id":130,"indexOrder":13,"name":131},"ilhi987n986rmvo3","JavaSE 笔记（四）异常机制",{"bookId":120,"id":133,"indexOrder":13,"name":134},"pqv38vexmenglk4k","JavaSE 笔记（五）IO",{"bookId":120,"id":136,"indexOrder":13,"name":137},"jiq41n87i9ia7ilw","JavaSE 笔记（六）多线程",{"bookId":120,"id":139,"indexOrder":13,"name":140},"wn7x2mge9ws79zps","JavaSE 笔记（七）反射","此版本为早期录制的旧版本",2021,"JavaSE 21年旧版","https:\u002F\u002Fwww.bilibili.com\u002Fvideo\u002FBV1Gv411T7pi\u002F","包含JavaSE基础路线全部教程笔记，打下坚实的基础","https:\u002F\u002Fpic2.zhimg.com\u002F80\u002Fv2-bf1a927f037a79f4d57d9ae543430a0d_1440w.webp","JavaSE 系列笔记 ☕️",{"books":149,"desc":199,"id":66,"image":200,"title":201},[150,166,178],{"cateId":66,"chapters":151,"desc":162,"id":153,"time":163,"title":164,"video":165},[152,156,159],{"bookId":153,"id":154,"indexOrder":13,"name":155},21,"iqbc2haub31bwqtz","Lombok 极速上手",{"bookId":153,"id":157,"indexOrder":13,"name":158},"ijay2hay19kn1k031","Mybatis 快速上手",{"bookId":153,"id":160,"indexOrder":13,"name":161},"ru4ogh2waocpn4jo","Maven 快速上手","JavaWeb阶段必须扩展知识点",2024,"常用知识讲解","https:\u002F\u002Fwww.bilibili.com\u002Fvideo\u002FBV1gb421J7ok\u002F",{"cateId":66,"chapters":167,"desc":175,"id":169,"time":163,"title":176,"video":177},[168,172],{"bookId":169,"id":170,"indexOrder":13,"name":171},22,"ek20yvb6huhxizx7","JavaWeb 笔记（一）计算机网络基础",{"bookId":169,"id":173,"indexOrder":13,"name":174},"pgevws6w2krkffa4","JavaWeb笔记（二）Java与数据库","全面升级的JavaWeb课程","JavaWeb 网站开发","https:\u002F\u002Fwww.bilibili.com\u002Fvideo\u002FBV1kS421X7rq\u002F",{"cateId":66,"chapters":179,"desc":196,"id":181,"time":142,"title":197,"video":198},[180,184,187,190,193],{"bookId":181,"id":182,"indexOrder":13,"name":183},7,"ggwwj09j2vkfftvd","JavaWeb 笔记（一）Java网络编程",{"bookId":181,"id":185,"indexOrder":13,"name":186},"sauvq105istskjaz","JavaWeb 笔记（二）数据库基础",{"bookId":181,"id":188,"indexOrder":13,"name":189},"xgbeasmvrhxx9tn4","JavaWeb 笔记（三）Java与数据库",{"bookId":181,"id":191,"indexOrder":13,"name":192},"k7dfwua3bsezvw9q","JavaWeb 笔记（四）前端基础",{"bookId":181,"id":194,"indexOrder":13,"name":195},"ycpagby2v7j4p728","JavaWeb 笔记（五）后端开发","搭建属于自己的Web网站","JavaWeb 旧版","https:\u002F\u002Fwww.bilibili.com\u002Fvideo\u002FBV1CL4y1i7qR\u002F","包含JavaWeb路线全套笔记，从零开始搭建自己的网站！","https:\u002F\u002Fpic3.zhimg.com\u002F80\u002Fv2-df3b38e3012258ed70c23b586309e3f6_1440w.webp","JavaWeb 系列笔记 🚛",{"books":203,"desc":288,"id":81,"image":289,"title":290},[204,220,235,255,273],{"cateId":81,"chapters":205,"desc":216,"id":207,"time":217,"title":218,"video":219},[206,210,213],{"bookId":207,"id":208,"indexOrder":13,"name":209},8,"h7sjo5oy0l03607e","SSM笔记（一）Spring基础",{"bookId":207,"id":211,"indexOrder":13,"name":212},"eve8gq72qmdb46sg","SSM笔记（二）SpringMvc基础",{"bookId":207,"id":214,"indexOrder":13,"name":215},"63v73g0zh1qlr6fk","SSM笔记（三）SpringSecurity基础","Spring的探索之路从这里开始",2023,"JavaSSM 基础部分","[\"https:\u002F\u002Fwww.bilibili.com\u002Fvideo\u002FBV1Kv4y1x7is\u002F\", \"https:\u002F\u002Fwww.bilibili.com\u002Fvideo\u002FBV1Lh4y1M7kx\u002F\", \"https:\u002F\u002Fwww.bilibili.com\u002Fvideo\u002FBV1fV411M7aS\u002F\"]",{"cateId":81,"chapters":221,"desc":232,"id":223,"time":217,"title":233,"video":234},[222,226,229],{"bookId":223,"id":224,"indexOrder":13,"name":225},16,"0k66v5r6slsfuog4","SpringBoot笔记（一）核心内容",{"bookId":223,"id":227,"indexOrder":13,"name":228},"bqlrnc2yvkaxo8s1","SpringBoot笔记（二）数据交互",{"bookId":223,"id":230,"indexOrder":13,"name":231},"wci9lb9tgea866jt","SpringBoot笔记（三）前后端分离","SpringBoot全新重制版","SpringBoot 新版","https:\u002F\u002Fwww.bilibili.com\u002Fvideo\u002FBV1xu4y1m7UP\u002F",{"cateId":81,"chapters":236,"desc":252,"id":238,"time":60,"title":253,"video":254},[237,240,243,246,249],{"bookId":238,"id":239,"indexOrder":13,"name":225},9,"e43gl1ilygps032v",{"bookId":238,"id":241,"indexOrder":13,"name":242},"emnmd8nzfdb3hr50","SpringBoot笔记（二）Git版本控制",{"bookId":238,"id":244,"indexOrder":13,"name":245},"jjlolj5igvttvyhv","SpringBoot笔记（三）Redis数据库",{"bookId":238,"id":247,"indexOrder":13,"name":248},"skgr4ivb5curdoux","SpringBoot笔记（四）其他框架介绍",{"bookId":238,"id":250,"indexOrder":13,"name":251},"le91fqhu4dqui1k4","SpringBoot笔记（五）Linux系统","逐步走向企业级开发","SpringBoot 旧版","https:\u002F\u002Fwww.bilibili.com\u002Fvideo\u002FBV1UL411V7f3\u002F",{"cateId":81,"chapters":256,"desc":270,"id":258,"time":60,"title":271,"video":272},[257,261,264,267],{"bookId":258,"id":259,"indexOrder":13,"name":260},10,"oejzo0l77zeb6a7e","SpringCloud笔记（一）微服务基础",{"bookId":258,"id":262,"indexOrder":13,"name":263},"f6eya9taaelsl35p","SpringCloud笔记（二）微服务进阶",{"bookId":258,"id":265,"indexOrder":13,"name":266},"35v1hbsfcdgagdnw","SpringCloud笔记（三）微服务应用",{"bookId":258,"id":268,"indexOrder":13,"name":269},"a782u84512tyuo1m","SpringCloud笔记（四）消息队列","体验微服务架构带来的魅力","SpringCloud 进阶","https:\u002F\u002Fwww.bilibili.com\u002Fvideo\u002FBV1AL4y1j7RY\u002F",{"cateId":81,"chapters":274,"desc":285,"id":276,"time":142,"title":286,"video":287},[275,278,280,282],{"bookId":276,"id":277,"indexOrder":13,"name":209},11,"efjw75u8a251qxk5",{"bookId":276,"id":279,"indexOrder":13,"name":212},"guc134xb7sl78vju",{"bookId":276,"id":281,"indexOrder":13,"name":215},"u8ekxxucowr2b1tm",{"bookId":276,"id":283,"indexOrder":13,"name":284},"vkpmw9wbej21nei6","SSM笔记（四）MySQL进阶","此教程为2021年旧版教程","JavaSSM 旧版","https:\u002F\u002Fwww.bilibili.com\u002Fvideo\u002FBV1xL4y1H7Tq\u002F","包含Spring全套框架笔记，从开始到Spring Boot，以及众多运维小知识。","https:\u002F\u002Fpic4.zhimg.com\u002F80\u002Fv2-28c3144421220d7c048703281bc34f63_1440w.webp","Spring 系列笔记 🍏",{"books":292,"desc":329,"id":96,"image":330,"title":331},[293,308],{"cateId":96,"chapters":294,"desc":305,"id":296,"time":60,"title":306,"video":307},[295,299,302],{"bookId":296,"id":297,"indexOrder":13,"name":298},12,"jd3e8u5cmvx5gco6","C语言（一）计算机思维导论",{"bookId":296,"id":300,"indexOrder":13,"name":301},"lqv77apvx82nkkio","C语言（二）基础语法",{"bookId":296,"id":303,"indexOrder":13,"name":304},"xb0b9t37gyv96xns","C语言（三）高级特性","包含高等院校需要教授的全部内容","C语言程序设计","https:\u002F\u002Fwww.bilibili.com\u002Fvideo\u002FBV1Cr4y137os\u002F",{"cateId":96,"chapters":309,"desc":326,"id":311,"time":60,"title":327,"video":328},[310,314,317,320,323],{"bookId":311,"id":312,"indexOrder":13,"name":313},13,"8a046ps2e4w6k4py","数据结构与算法（一）线性结构篇",{"bookId":311,"id":315,"indexOrder":13,"name":316},"3ma8db91f9zrnkja","数据结构与算法（二）树形结构篇",{"bookId":311,"id":318,"indexOrder":13,"name":319},"0lsjm59k7cgu4tpr","数据结构与算法（三）散列表篇",{"bookId":311,"id":321,"indexOrder":13,"name":322},"0qzy7bogo0g2pusa","数据结构与算法（四）图结构篇",{"bookId":311,"id":324,"indexOrder":13,"name":325},"6gmcxcikcilyxblj","数据结构与算法（五）排序算法篇","虽然很难，但是它是考研必学科目","数据结构与算法","https:\u002F\u002Fwww.bilibili.com\u002Fvideo\u002FBV13W4y127Ey\u002F","你的内心一直有一个坚定的声音在告诉你，一定要考上一名研究生，向着未来前进吧！","https:\u002F\u002Fpic2.zhimg.com\u002F80\u002Fv2-ac128404efb29ce1c9d1ccc61024f1d1_1440w.webp","C语言 系列笔记 🥬",{"books":333,"desc":367,"id":108,"image":368,"title":369},[334,349,358],{"cateId":108,"chapters":335,"desc":346,"id":337,"time":163,"title":347,"video":348},[336,340,343],{"bookId":337,"id":338,"indexOrder":13,"name":339},17,"urw2e6gg1lprv65w","Kotlin（一）基础语法",{"bookId":337,"id":341,"indexOrder":13,"name":342},"t7lnl87f74f3v1ju","Kotlin（二）类与对象",{"bookId":337,"id":344,"indexOrder":13,"name":345},"v1zzvki0knb1xvml","Kotlin（三）高级特性","包含Kotlin语言完整基础部分","Kotlin程序设计基础","https:\u002F\u002Fwww.bilibili.com\u002Fvideo\u002FBV1P94y1c7tV\u002F",{"cateId":108,"chapters":350,"desc":355,"id":352,"time":163,"title":356,"video":357},[351],{"bookId":352,"id":353,"indexOrder":13,"name":354},18,"ovbzpe7065bye1st","Kotlin扩展（一）","包含Kotlin额外扩展知识","Kotlin扩展篇","https:\u002F\u002Fwww.bilibili.com\u002Fvideo\u002FBV1Hg4y1m7Ca\u002F",{"cateId":108,"chapters":359,"desc":364,"id":361,"time":163,"title":365,"video":366},[360],{"bookId":361,"id":362,"indexOrder":13,"name":363},19,"3at7ybv04dmjc0wp","Gradle基础教程","Gradle配置教程（Kotlin）","Gradle教程","https:\u002F\u002Fwww.bilibili.com\u002Fvideo\u002FBV1Fc411x7xF\u002F","Kotlin让JVM平台焕发新的生机，让语言的表达更加优美","https:\u002F\u002Fpic2.zhimg.com\u002F80\u002Fv2-be815568f7c79c64cdaa171b0409786d_1440w.webp","Kotlin 系列笔记 ☘️",{"books":371,"desc":418,"id":120,"title":419},[372,391,403],{"cateId":120,"chapters":373,"desc":387,"id":375,"time":388,"title":389,"video":390},[374,378,381,384],{"bookId":375,"id":376,"indexOrder":13,"name":377},26,"zjf5qapwqtqiohcn","JavaScript笔记（一）基础语法",{"bookId":375,"id":379,"indexOrder":13,"name":380},"95jc6sjyjwcp9pvp","JavaScript笔记（二）核心知识",{"bookId":375,"id":382,"indexOrder":13,"name":383},"j35cdc1qz8dzq7pn","JavaScript笔记（三）进阶知识",{"bookId":375,"id":385,"indexOrder":13,"name":386},"sdhodlihphnpcg37","JavaScript笔记（四）前端基础","包含JavaScript最新语法规范讲解",2026,"JavaScript教程","https:\u002F\u002Fwww.bilibili.com\u002Fvideo\u002FBV1xq6gBgESU",{"cateId":120,"chapters":392,"desc":400,"id":394,"time":37,"title":401,"video":402},[393,397],{"bookId":394,"id":395,"indexOrder":13,"name":396},23,"bsisgazdftiz3o9c","HTML5笔记（一）基础内容",{"bookId":394,"id":398,"indexOrder":13,"name":399},"njol93fs34gfwuzf","HTML5笔记（二）高级内容","包含HTML基础内容和相关知识点","HTML5核心教程","https:\u002F\u002Fwww.bilibili.com\u002Fvideo\u002FBV1BrBiYNEWg",{"cateId":120,"chapters":404,"desc":415,"id":406,"time":37,"title":416,"video":417},[405,409,412],{"bookId":406,"id":407,"indexOrder":13,"name":408},25,"jo74ciirtg8wh90y","CSS笔记（一）基础入门",{"bookId":406,"id":410,"indexOrder":13,"name":411},"ap5ixyomoejuw4ue","CSS笔记（二）盒模型和布局",{"bookId":406,"id":413,"indexOrder":13,"name":414},"4djgk5xy1lzpiuf2","CSS笔记（三）变换和过渡","包含CSS3基础内容和相关知识点","CSS3核心教程","https:\u002F\u002Fwww.bilibili.com\u002Fvideo\u002FBV1sQeEzFEKi","包含Web前端学习路径全部教程笔记，打下坚实的基础","Web前端 系列笔记",{"books":421,"desc":458,"id":423,"image":368,"title":459},[422,432,450],{"cateId":423,"chapters":424,"desc":429,"id":426,"time":163,"title":430,"video":431},100,[425],{"bookId":426,"id":427,"indexOrder":13,"name":428},20,"o0ab271mkdsas87","Markdown基础语法","编写简洁而又优美的文档","Markdown教程","https:\u002F\u002Fwww.bilibili.com\u002Fvideo\u002FBV1eJ4m157kC",{"cateId":423,"chapters":433,"desc":447,"id":435,"time":60,"title":448,"video":449},[434,438,441,444],{"bookId":435,"id":436,"indexOrder":13,"name":437},14,"6386mh7anqt4tzyv","设计模式（一）面向对象设计原则",{"bookId":435,"id":439,"indexOrder":13,"name":440},"8ftkb38wfn6ox0ug","设计模式（二）创建型",{"bookId":435,"id":442,"indexOrder":13,"name":443},"i1msql1k8y70etey","设计模式（三）结构型",{"bookId":435,"id":445,"indexOrder":13,"name":446},"5434a3cyyjvwhs8s","设计模式（四）行为型","使你的编码水平得到质的飞跃","设计模式系列","https:\u002F\u002Fwww.bilibili.com\u002Fvideo\u002FBV1u3411P7Na\u002F",{"cateId":423,"chapters":451,"desc":456,"id":453,"time":60,"title":457},[452],{"bookId":453,"id":454,"indexOrder":13,"name":455},15,"zj9uvg0sp3b0sok8","Docker 容器技术 笔记","这里包含其他中间件课程笔记","其他中间件笔记","我们对知识的探索从未停止，只有不断地学习，才能走向美好的未来！","其他笔记分类 🌽",200,true,{"data":463,"status":460,"success":461},{"bookId":120,"content":464,"id":124,"indexOrder":66,"name":125},"# Java对象和多态 （面向对象）\n\n## 面向对象基础\n\n面向对象程序设计(Object Oriented Programming)\n\n对象基于类创建，类相当于一个模板，对象就是根据模板创建出来的实体（就像做月饼，我们要做一个月饼首先需要一个模具，模具就是我们的类，而做出来的月饼，就是类的实现，也叫做对象），类是抽象的数据类型，并不能代表某一个具体的事物，类是对象的一个模板。类具有自己的属性，包括成员变量、成员方法等，我们可以调用类的成员方法来让类进行一些操作。\n\n```java\nScanner sc = new Scanner(System.in);\nString str = sc.nextLine();\nSystem.out.println(\"你输入了：\"+str);\nsc.close();\n```\n\n所有的对象，都需要通过`new`关键字创建，基本数据类型不是对象！Java不是纯面对对象语言！\n\n不是基本类型的变量，都是引用类型，引用类型变量代表一个对象，而基本数据类型变量，保存的是基本数据类型的值，我们可以通过引用来对对象进行操作。（最好不要理解为引用指向对象的地址，初学者不要谈内存，学到JVM时再来讨论）\n\n对象占用的内存由JVM统一管理，不需要手动释放内存，当一个对象不再使用时（比如失去引用或是离开了作用域）会被JVM自动清理，内存管理更方便！\n\n***\n\n## 类的基本结构\n\n为了快速掌握，我们自己创建一个自己的类，创建的类文件名称应该和类名一致。\n\n### 成员变量\n\n在类中，可以包含许多的成员变量，也叫成员属性，成员字段(field)通过`.`来访问我们类中的成员变量，我们可以通过类创建的对象来访问和修改这些变量。成员变量是属于对象的！\n\n```java\npublic class Test {\n    int age;\n    String name;\n}\n\npublic static void main(String[] args) {\n    Test test = new Test();\n    test.name = \"奥利给\";\n    System.out.println(test.name);\n}\n```\n\n成员变量默认带有初始值，也可以自己定义初始值。\n\n### 成员方法\n\n我们之前的学习中接触过方法(Method)吗？主方法！\n\n```java\npublic static void main(String[] args) {\n  \u002F\u002FBody\n}\n```\n\n方法是语句的集合，是为了完成某件事情而存在的。完成某件事情，可以有结果，也可以做了就做了，不返回结果。比如计算两个数字的和，我们需要得到计算后的结果，所以说方法需要有返回值；又比如，我们只想吧数字打印在控制台，只需要打印就行，不用给我结果，所以说方法不需要有返回值。\n\n#### 方法的定义和使用\n\n在类中，我们可以定义自己的方法，格式如下：\n\n```java\n[返回值类型] 方法名称([参数]){\n  \u002F\u002F方法体\n  return 结果;\n}\n```\n\n* 返回值类型：可以是引用类型和基本类型，还可以是void，表示没有返回值\n* 方法名称：和标识符的规则一致，和变量一样，规范小写字母开头！\n* 参数：例如方法需要计算两个数的和，那么我们就要把两个数到底是什么告诉方法，那么它们就可以作为参数传入方法\n* 方法体：方法具体要干的事情\n* 结果：方法执行的结果通过return返回（如果返回类型为void，可以省略return）\n\n非void方法中，`return`关键字不一定需要放在最后，但是一定要保证方法在任何情况下都具有返回值！\n\n```java\nint test(int a){\n  if(a > 0){\n    \u002F\u002F缺少retrun语句！\n  }else{\n    return 0;\n  }\n}\n```\n\n`return`也能用来提前结束整个方法，无论此时程序执行到何处，无论return位于哪里，都会立即结束个方法！\n\n```java\nvoid main(String[] args) {\n   for (int i = 0; i \u003C 10; i++) {\n       if(i == 1) return;   \u002F\u002F在循环内返回了！和break区别？\n   }\n   System.out.println(\"淦\");   \u002F\u002F还会到这里吗？\n}\n```\n\n传入方法的参数，如果是基本类型，会在调用方法的时候，对参数的值进行复制，方法中的参数变量，不是我们传入的变量本身！\n\n```java\npublic static void main(String[] args) {\n    int a = 10, b = 20;\n  \tnew Test().swap(a, b);\n  \tSystem.out.println(\"a=\"+a+\", b=\"+b);\n}\n\npublic class Test{\n \tvoid swap(int a, int b){  \u002F\u002F传递的仅仅是值而已！\n  \t\tint temp = a;\n  \t\ta = b;\n \t\t\tb = temp;\n\t} \n}\n```\n\n传入方法的参数，如果是引用类型，那么传入的依然是该对象的引用！（类似于C语言的指针）\n\n```java\npublic class B{\n \tString name;\n}\n\npublic class A{\n \tvoid test(B b){  \u002F\u002F传递的是对象的引用，而不是值\n    System.out.println(b.name);\n  }\n}\n\npublic static void main(String[] args) {\n    int a = 10, b = 20;\n  \tB b = new B();\n  \tb.name = \"lbw\";\n  \tnew A().test(b);\n  \tSystem.out.println(\"a=\"+a+\", b=\"+b);\n}\n```\n\n方法之间可以相互调用\n\n```java\nvoid a(){\n  \u002F\u002Fxxxx\n}\n\nvoid b(){\n  a();\n}\n```\n\n当方法在自己内部调用自己时，称为递归调用（递归很危险，慎重！）\n\n```java\nint a(){\n  return a();\n}\n```\n\n成员方法和成员变量一样，是属于对象的，只能通过对象去调用！\n\n***\n\n### 对象设计练习\n\n* 学生应该具有以下属性：名字、年龄\n* 学生应该具有以下行为：学习、运动、说话\n\n***\n\n### 方法的重载\n\n一个类中可以包含多个同名的方法，但是需要的形式参数不一样。（补充：形式参数就是定义方法需要的参数，实际参数就传入的参数）方法的返回类型，可以相同，也可以不同，但是仅返回类型不同，是不允许的！\n\n```java\npublic class Test {\n    int a(){   \u002F\u002F原本的方法\n       return 1;\n    }\n\n    int a(int i){  \u002F\u002Fok，形参不同\n        return i;\n    }\n    \n    void a(byte i){  \u002F\u002Fok，返回类型和形参都不同\n        \n    }\n    \n    void a(){  \u002F\u002F错误，仅返回值类型名称不同不能重载\n        \n    }\n}\n```\n\n现在我们就可以使用不同的参数，但是支持调用同样的方法，执行一样的逻辑：\n\n```java\npublic class Test {\n    int sum(int a, int b){   \u002F\u002F只有int支持，不灵活！\n        return a+b;\n    }\n    \n    double sum(double a, double b){  \u002F\u002F重写一个double类型的，就支持小数计算了\n        return a+b;\n    }\n}\n```\n\n现在我们有很多种重写的方法，那么传入实参后，到底进了哪个方法呢？\n\n```java\npublic class Test {\n    void a(int i){\n        System.out.println(\"调用了int\");\n    }\n\n    void a(short i){\n        System.out.println(\"调用了short\");\n    }\n\n    void a(long i){\n        System.out.println(\"调用了long\");\n    }\n\n    void a(char i){\n        System.out.println(\"调用了char\");\n    }\n\n    void a(double i){\n        System.out.println(\"调用了double\");\n    }\n\n    void a(float i){\n        System.out.println(\"调用了float\");\n    }\n  \n  \tpublic static void main(String[] args) {\n        Test test = new Test();\n        test.a(1);   \u002F\u002F直接输入整数\n        test.a(1.0);  \u002F\u002F直接输入小数\n\n        short s = 2;\n        test.a(s);  \u002F\u002F会对号入座吗？\n        test.a(1.0F);\n    }\n}\n```\n\n### 构造方法\n\n构造方法（构造器）没有返回值，也可以理解为，返回的是当前对象的引用！每一个类都默认自带一个无参构造方法。\n\n```java\n\u002F\u002F反编译结果\npackage com.test;\n\npublic class Test {\n    public Test() {    \u002F\u002F即使你什么都不编写，也自带一个无参构造方法，只是默认是隐藏的\n    }\n}\n```\n\n反编译其实就是把我们编译好的class文件变回Java源代码。\n\n```java\nTest test = new Test();  \u002F\u002F实际上存在Test()这个的方法，new关键字就是用来创建并得到引用的\n\u002F\u002F new + 你想要使用的构造方法\n```\n\n这种方法没有写明返回值，但是每个类都必须具有这个方法！只有调用类的构造方法，才能创建类的对象！\n\n类要在一开始准备的所有东西，都会在构造方法里面执行，完成构造方法的内容后，才能创建出对象！\n\n一般最常用的就是给成员属性赋初始值：\n\n```java\npublic class Student {\n    String name;\n    \n    Student(){\n        name = \"伞兵一号\";\n    }\n}\n```\n\n我们可以手动指定有参构造，当遇到名称冲突时，需要用到this关键字\n\n```java\npublic class Student {\n    String name;\n\n    Student(String name){   \u002F\u002F形参和类成员变量冲突了，Java会优先使用形式参数定义的变量！\n        this.name = name;  \u002F\u002F通过this指代当前的对象属性，this就代表当前对象\n    }\n}\n\n\u002F\u002Fidea 右键快速生成！\n```\n\n注意，this只能用于指代当前对象的内容，因此，只有属于对象拥有的部分才可以使用this，也就是说，只能在类的成员方法中使用this，不能在静态方法中使用this关键字。\n\n在我们定义了新的有参构造之后，默认的无参构造会被覆盖！\n\n```java\n\u002F\u002F反编译后依然只有我们定义的有参构造！\n```\n\n如果同时需要有参和无参构造，那么就需要用到方法的重载！手动再去定义一个无参构造。\n\n```java\npublic class Student {\n    String name;\n\n    Student(){\n\n    }\n\n    Student(String name){\n        this.name = name;\n    }\n}\n```\n\n成员变量的初始化始终在构造方法执行之前\n\n```java\npublic class Student {\n    String a = \"sadasa\";\n\n    Student(){\n        System.out.println(a);\n    }\n\n    public static void main(String[] args) {\n        Student s = new Student();\n    }\n}\n```\n\n### 静态变量和静态方法\n\n静态变量和静态方法是类具有的属性（后面还会提到静态类、静态代码块），也可以理解为是所有对象共享的内容。我们通过使用`static`关键字来声明一个变量或一个方法为静态的，一旦被声明为静态，那么通过这个类创建的所有对象，操作的都是同一个目标，也就是说，对象再多，也只有这一个静态的变量或方法。那么，一个对象改变了静态变量的值，那么其他的对象读取的就是被改变的值。\n\n```java\npublic class Student {\n    static int a;\n}\n\npublic static void main(String[] args) {\n\tStudent s1 = new Student();\n\ts1.a = 10;\n\tStudent s2 = new Student();\n\tSystem.out.println(s2.a);\n}\n```\n\n不推荐使用对象来调用，被标记为静态的内容，可以直接通过`类名.xxx`的形式访问\n\n```java\npublic static void main(String[] args) {\n   Student.a = 10;\n   System.out.println(Student.a);\n}\n```\n\n#### 简述类加载机制\n\n类并不是在一开始就全部加载好，而是在需要时才会去加载（提升速度）以下情况会加载类：\n\n- 访问类的静态变量，或者为静态变量赋值\n- new 创建类的实例（隐式加载）\n- 调用类的静态方法\n- 子类初始化时\n- 其他的情况会在讲到反射时介绍\n\n所有被标记为静态的内容，会在类刚加载的时候就分配，而不是在对象创建的时候分配，所以说静态内容一定会在第一个对象初始化之前完成加载。\n\n```java\npublic class Student {\n    static int a = test();  \u002F\u002F直接调用静态方法，只能调用静态方法\n\n    Student(){\n        System.out.println(\"构造类对象\");\n    }\n\n    static int test(){   \u002F\u002F静态方法刚加载时就有了\n        System.out.println(\"初始化变量a\");\n        return 1;\n    }\n}\n```\n\n思考：下面这种情况下，程序能正常运行吗？如果能，会输出什么内容？\n\n```java\npublic class Student {\n    static int a = test();\n\n    static int test(){\n        return a;\n    }\n\n    public static void main(String[] args) {\n        System.out.println(Student.a);\n    }\n}\n```\n\n定义和赋值是两个阶段，在定义时会使用默认值（上面讲的，类的成员变量会有默认值）定义出来之后，如果发现有赋值语句，再进行赋值，而这时，调用了静态方法，所以说会先去加载静态方法，静态方法调用时拿到a，而a这时仅仅是刚定义，所以说还是初始值，最后得到0\n\n### 代码块和静态代码块\n\n代码块在对象创建时执行，也是属于类的内容，但是它在构造方法执行之前执行（和成员变量初始值一样），且每创建一个对象时，只执行一次！（相当于构造之前的准备工作）\n\n```java\npublic class Student {\n    {\n        System.out.println(\"我是代码块\");\n    }\n\n    Student(){\n        System.out.println(\"我是构造方法\");\n    }\n}\n```\n\n静态代码块和上面的静态方法和静态变量一样，在类刚加载时就会调用；\n\n```java\npublic class Student {\n    static int a;\n\n    static {\n        a = 10;\n    }\n    \n    public static void main(String[] args) {\n        System.out.println(Student.a);\n    }\n}\n```\n\n### String和StringBuilder类\n\n字符串类是一个比较特殊的类，他是Java中唯一重载运算符的类！(Java不支持运算符重载，String是特例)\n\nString的对象直接支持使用`+`或`+=`运算符来进行拼接，并形成新的String对象！（String的字符串是不可变的！）\n\n```java\nString a = \"dasdsa\", b = \"dasdasdsa\";\nString l = a+b;\nSystem.out.println(l);\n```\n\n大量进行字符串的拼接似乎不太好，编译器是很聪明的，String的拼接有可能会被编译器优化为StringBuilder来减少对象创建（对象频繁创建时很费时间同时占内存的！）\n\n```java\nString result=\"String\"+\"and\"; \u002F\u002F会被优化成一句！\n```\n\n```java\nString str1=\"String\";\nString str2=\"and\";\nString result=str1+str2;\n\u002F\u002F变量随时可变，在编译时无法确定result的值，那么只能在运行时再去确定\n```\n\n```java\nString str1=\"String\";\nString str2=\"and\";\nString result=(new StringBuilder(String.valueOf(str1))).append(str2).toString();\n\u002F\u002F使用StringBuilder，会采用类似于第一种实现，显然会更快！\n```\n\nStringBuilder也是一个类，但是它能够存储可变长度的字符串！\n\n```java\nStringBuilder builder = new StringBuilder();\nbuilder\n       .append(\"a\")\n       .append(\"bc\")\n       .append(\"d\");   \u002F\u002F链式调用\nString str = builder.toString();\nSystem.out.println(str);\n```\n\n***\n\n## 包和访问控制\n\n### 包声明和导入\n\n包其实就是用来区分类位置的东西，也可以用来将我们的类进行分类，类似于C++中的namespace！\n\n```java\npackage com.test;\n\npublic class Test{\n  \n}\n```\n\n包其实是文件夹，比如com.test就是一个com文件夹中包含一个test文件夹，再包含我们Test类。\n\n一般包按照个人或是公司域名的规则倒过来写 `顶级域名.一级域名.二级域名` `com.java.xxxx`\n\n如果需要使用其他包里面的类，那么我们需要`import`（类似于C\u002FC++中的include）\n\n```java\nimport com.test.Student;\n```\n\n也可以导入包下的全部（一般导入会由编译器自带帮我们补全，但是一定要记得我们需要导包！）\n\n```java\nimport com.test.*\n```\n\nJava默认为我们导入了以下的包，不需要去声明\n\n```java\nimport java.lang.*\n```\n\n### 静态导入\n\n静态导入可以直接导入某个类的静态方法或者是静态变量，导入后，相当于这个方法或是类在定义在当前类中，可以直接调用该方法。\n\n```java\nimport static com.test.ui.Student.test;\n\npublic class Main {\n    public static void main(String[] args) {\n        test();\n    }\n}\n```\n\n静态导入不会进行类的初始化！\n\n### 访问控制\n\nJava支持对类属性访问的保护，也就是说，不希望外部类访问类中的属性或是方法，只允许内部调用，这种情况下我们就需要用到权限控制符。\n\n![image-20230814155844604](https:\u002F\u002Fs2.loli.net\u002F2023\u002F08\u002F14\u002FfrImUTq9cLJQ1zY.png)\n\n权限控制符可以声明在方法、成员变量、类前面，一旦声明private，只能类内部访问！\n\n```java\npublic class Student {\n    private int a = 10;   \u002F\u002F具有私有访问权限，只能类内部访问\n}\n\npublic static void main(String[] args) {\n    Student s = new Student();\n    System.out.println(s.a);  \u002F\u002F还可以访问吗？\n}\n```\n\n和文件名称相同的类，只能是public，并且一个java文件中只能有一个public class！\n\n```java\n\u002F\u002F Student.java\npublic class Student {\n    \n}\nclass Test{   \u002F\u002F不能添加权限修饰符！只能是default\n\t\n}\n```\n\n***\n\n## 数组类型\n\n假设出现一种情况，我想记录100个数字，定义100个变量还可行吗？\n\n![img](https:\u002F\u002Fs2.loli.net\u002F2023\u002F08\u002F14\u002FuPIbAMznCQO4ryw.jpg)\n\n我们可以使用到数组，数组是相同类型数据的有序集合。数组可以代表任何相同类型的一组内容（包括引用类型和基本类型）其中存放的每一个数据称为数组的一个元素，数组的下标是从0开始，也就是第一个元素的索引是0！\n\n```java\nint[] arr = new int[10];  \u002F\u002F需要new关键字来创建！\nString[] arr2 = new String[10];\n```\n\n数组本身也是类（编程不可见，C++写的），不是基本数据类型！\n\n```java\nint[] arr = new int[10];\nSystem.out.println(arr.length);   \u002F\u002F数组有成员变量！\nSystem.out.println(arr.toString());   \u002F\u002F数组有成员方法！\n```\n\n### 一维数组\n\n一维数组中，元素是依次排列的（线性），每个数组元素可以通过下标来访问！声明格式如下：\n\n```  java\n类型[] 变量名称 = new 类型[数组大小];\n类型 变量名称n = new 类型[数组大小];  \u002F\u002F支持C语言样式，但不推荐！\n\n类型[] 变量名称 = new 类型[]{...};  \u002F\u002F静态初始化（直接指定值和大小）\n类型[] 变量名称 = {...};   \u002F\u002F同上，但是只能在定义时赋值\n```\n\n 创建出来的数组每个元素都有默认值（规则和类的成员变量一样，C语言创建的数组需要手动设置默认值），我们可以通过下标去访问：\n\n```java\nint[] arr = new int[10];\narr[0] = 626;\nSystem.out.println(arr[0]);\nSystem.out.println(arr[1]);\n```\n\n我们可以通过`数组变量名称.length`来获取当前数组长度：\n\n```java\nint[] arr = new int[]{1, 2, 3};\nSystem.out.println(arr.length);  \u002F\u002F打印length成员变量的值\n```\n\n数组在创建时，就固定长度，不可更改！访问超出数组长度的内容，会出现错误！\n\n```java\nString[] arr = new String[10];\nSystem.out.println(arr[10]);  \u002F\u002F出现异常！\n\n\u002F\u002FException in thread \"main\" java.lang.ArrayIndexOutOfBoundsException: 11\n\u002F\u002F\tat com.test.Application.main(Application.java:7)\n```\n\n思考：能不能直接修改length的值来实现动态扩容呢？\n\n```java\nint[] arr = new int[]{1, 2, 3};\narr.length = 10;\n```\n\n数组做实参，因为数组也是类，所以形参得到的是数组的引用而不是复制的数组，操作的依然是数组对象本身\n\n```java\npublic static void main(String[] args) {\n    int[] arr = new int[]{1, 2, 3};\n    test(arr);\n    System.out.println(arr[0]);\n}\n\nprivate static void test(int[] arr){\n    arr[0] = 2934;\n}\n```\n\n### 数组的遍历\n\n如果我们想要快速打印数组中的每一个元素，又怎么办呢？\n\n#### 传统for循环\n\n我们很容易就联想到for循环\n\n```java\nint[] arr = new int[]{1, 2, 3};\nfor (int i = 0; i \u003C arr.length; i++) {\n   System.out.println(arr[i]);\n}\n```\n\n#### foreach\n\n传统for循环虽然可控性高，但是不够省事，要写一大堆东西，有没有一种省事的写法呢？\n\n```java\nint[] arr = new int[]{1, 2, 3};\nfor (int i : arr) {\n    System.out.println(i);\n}\n```\n\nforeach属于增强型的for循环，它使得代码更简洁，同时我们能直接拿到数组中的每一个数字。\n\n### 二维数组\n\n二维数组其实就是存放数组的数组，每一个元素都存放一个数组的引用，也就相当于变成了一个平面。\n\n![img](https:\u002F\u002Fs2.loli.net\u002F2023\u002F08\u002F14\u002F7L9BwzRYtuApokl.jpg)\n\n```java\n\u002F\u002F三行两列\nint[][] arr = { {1, 2},\n                {3, 4},\n                {5, 6}};\nSystem.out.println(arr[2][1]);\n```\n\n二维数组的遍历同一维数组一样，只不过需要嵌套循环！\n\n```java\nint[][] arr = new int[][]{ {1, 2},\n                           {3, 4},\n                           {5, 6}};\nfor (int i = 0; i \u003C 3; i++) {\n     for (int j = 0; j \u003C 2; j++) {\n          System.out.println(arr[i][j]);\n     }\n}\n```\n\n### 多维数组\n\n不止二维数组，还存在三维数组，也就是存放数组的数组的数组，原理同二维数组一样，逐级访问即可。\n\n### 可变长参数\n\n可变长参数其实就是数组的一种应用，我们可以指定方法的形参为一个可变长参数，要求实参可以根据情况动态填入0个或多个，而不是固定的数量\n\n```java\npublic static void main(String[] args) {\n     test(\"AAA\", \"BBB\", \"CCC\");    \u002F\u002F可变长，最后都会被自动封装成一个数组\n}\n    \nprivate static void test(String... test){\n     System.out.println(test[0]);    \u002F\u002F其实参数就是一个数组\n}\n```\n\n由于是数组，所以说只能使用一种类型的可变长参数，并且可变长参数只能放在最后一位！\n\n### 实战：三大基本排序算法\n\n现在我们有一个数组，但是数组里面的数据是乱序排列的，如何使它变得有序？\n\n```java\nint[] arr = {8, 5, 0, 1, 4, 9, 2, 3, 6, 7};\n```\n\n排序是编程的一个重要技能，掌握排序算法，你的技术才能更上一层楼，很多的项目都需要用到排序！三大排序算法：\n\n* 冒泡排序\n\n冒泡排序就是冒泡，其实就是不断使得我们无序数组中的最大数向前移动，经历n轮循环逐渐将每一个数推向最前。\n\n* 插入排序\n\n插入排序其实就跟我们打牌是一样的，我们在摸牌的时候，牌堆是乱序的，但是我们一张一张摸到手中进行排序，使得它变成了有序的！\n\n![img](https:\u002F\u002Fs2.loli.net\u002F2023\u002F08\u002F14\u002F6JEtd8ifqDVAZ3c.jpg)\n\n* 选择排序\n\n选择排序其实就是每次都选择当前数组中最大的数排到最前面！\n\n***\n\n## 封装、继承和多态\n\n封装、继承和多态是面向对象编程的三大特性。\n\n### 封装\n\n封装的目的是为了保证变量的安全性，使用者不必在意具体实现细节，而只是通过外部接口即可访问类的成员，如果不进行封装，类中的实例变量可以直接查看和修改，可能给整个代码带来不好的影响，因此在编写类时一般将成员变量私有化，外部类需要同getter和setter方法来查看和设置变量。\n\n设想：学生小明已经创建成功，正常情况下能随便改他的名字和年龄吗？\n\n```java\npublic class Student {\n    private String name;\n    private int age;\n  \n    public Student(String name, int age) {\n        this.name = name;\n        this.age = age;\n    }\n\n    public int getAge() {\n        return age;\n    }\n\n    public String getName() {\n        return name;\n    }\n}\n```\n\n也就是说，外部现在只能通过调用我定义的方法来获取成员属性，而我们可以在这个方法中进行一些额外的操作，比如小明可以修改名字，但是名字中不能包含\"小\"这个字。\n\n```java\npublic void setName(String name) {\n    if(name.contains(\"小\")) return;\n    this.name = name;\n}\n```\n\n单独给外部开放设置名称的方法，因为我还需要做一些额外的处理，所以说不能给外部直接操作成员变量的权限！\n\n封装思想其实就是把实现细节给隐藏了，外部只需知道这个方法是什么作用，而无需关心实现。\n\n封装就是通过访问权限控制来实现的。\n\n### 继承\n\n继承属于非常重要的内容，在定义不同类的时候存在一些相同属性，为了方便使用可以将这些共同属性抽象成一个父类，在定义其他子类时可以继承自该父类，减少代码的重复定义，子类可以使用父类中**非私有**的成员。\n\n现在学生分为两种，艺术生和体育生，他们都是学生的分支，但是他们都有自己的方法：\n\n```java\npublic class SportsStudent extends Student{   \u002F\u002F通过extends关键字来继承父类\n\n    public SportsStudent(String name, int age) {\n        super(name, age);   \u002F\u002F必须先通过super关键字（指代父类），实现父类的构造方法！\n    }\n\n    public void exercise(){\n        System.out.println(\"我超勇的！\");\n    }\n}\n\npublic class ArtStudent extends Student{\n\n    public ArtStudent(String name, int age) {\n        super(name, age);\n    }\n\n    public void art(){\n        System.out.println(\"随手画个毕加索！\");\n    }\n}\n```\n\n子类具有父类的全部属性，protected可见但外部无法使用（包括`private`属性，不可见，无法使用），同时子类还能有自己的方法。继承只能继承一个父类，不支持多继承！\n\n每一个子类必须定义一个实现父类构造方法的构造方法，也就是需要在构造方法开始使用`super()`，如果父类使用的是默认构造方法，那么子类不用手动指明。\n\n所有类都默认继承自Object类，除非手动指定类型，但是依然改变不了最顶层的父类是Object类。所有类都包含Object类中的方法，比如：\n\n```java\npublic static void main(String[] args) {\nObject obj = new Object;\nSystem.out.println(obj.hashCode());  \u002F\u002F求对象的hashcode，默认是对象的内存地址\nSystem.out.println(obj.equals(obj));  \u002F\u002F比较对象是否相同，默认比较的是对象的内存地址，也就是等同于 ==\nSystem.out.println(obj.toString());  \u002F\u002F将对象转换为字符串，默认生成对象的类名称+hashcode\n}\n```\n\n关于Object类的其他方法，我们会在Java多线程中再来提及。\n\n### 多态\n\n多态是同一个行为具有多个不同表现形式或形态的能力。也就是同样的方法，由于实现类不同，执行的结果也不同！\n\n#### 方法的重写\n\n我们之前学习了方法的重载，方法的重写和重载是不一样的，重载是原有的方法逻辑不变的情况下，支持更多参数的实现，而重写是直接覆盖原有方法！\n\n```java\n\u002F\u002F父类中的study\npublic void study(){\n    System.out.println(\"学习\");\n}\n\n\u002F\u002F子类中的study\n@Override  \u002F\u002F声明这个方法是重写的，但是可以不要，我们现阶段不接触\npublic void study(){\n    System.out.println(\"给你看点好康的\");\n}\n```\n\n再次定义同样的方法后，父类的方法就被覆盖！子类还可以给父类方法提升访问权限！\n\n```java\npublic static void main(String[] args) {\n     SportsStudent student = new SportsStudent(\"lbw\", 20);\n     student.study();   \u002F\u002F输出子类定义的内容\n}\n```\n\n思考：静态方法能被重写吗？\n\n当我们在重写方法时，不仅想使用我们自己的逻辑，同时还希望执行父类的逻辑（也就是调用父类的方法）怎么办呢？\n\n```java\npublic void study(){\n    super.study();\n    System.out.println(\"给你看点好康的\");\n}\n```\n\n同理，如果想访问父类的成员变量，也可以使用super关键字来访问，注意，子类可以具有和父类相同的成员变量！而在方法中访问的默认是 形参列表中 > 当前类的成员变量 > 父类成员变量\n\n```java\npublic void setTest(int test){\n    test = 1;\n  \tthis.test = 1;\n  \tsuper.test = 1;\n}\n```\n\n#### 再谈类型转换\n\n我们曾经学习过基本数据类型的类型转换，支持一种数据类型转换为另一种数据类型，而我们的类也是支持类型转换的（仅限于存在亲缘关系的类之间进行转换）比如子类可以直接向上转型：\n\n```java\nStudent student = new SportsStudent(\"lbw\", 20);  \u002F\u002F父类变量引用子类实例\nstudent.study();     \u002F\u002F得到依然是具体实现的结果，而不是当前类型的结果\n```\n\n我们也可以把已经明确是由哪个类实现的父类引用，强制转换为对应的类型：\n\n```java\nStudent student = new SportsStudent(\"lbw\", 20);  \u002F\u002F是由SportsStudent进行实现的\n\u002F\u002F... do something...\n\nSportsStudent ps = (SportsStudent)student;  \u002F\u002F让它变成一个具体的子类\nps.sport();  \u002F\u002F调用具体实现类的方法\n```\n\n这样的类型转换称为向下转型。\n\n#### instanceof关键字\n\n那么我们如果只是得到一个父类引用，但是不知道它到底是哪一个子类的实现怎么办？我们可以使用instanceof关键字来实现，它能够进行类型判断！\n\n```java\nprivate static void test(Student student){\n    if (student instanceof SportsStudent){\n        SportsStudent sportsStudent = (SportsStudent) student;\n        sportsStudent.sport();\n    }else if (student instanceof ArtStudent){\n        ArtStudent artStudent = (ArtStudent) student;\n        artStudent.art();\n    }\n}\n```\n\n通过进行类型判断，我们就可以明确类的具体实现到底是哪个类！\n\n思考：`student instanceof Student`的结果是什么？\n\n#### 再谈final关键字\n\n我们目前只知道`final`关键字能够使得一个变量的值不可更改，那么如果在类前面声明final，会发生什么？\n\n```java\npublic final class Student {   \u002F\u002F类被声明为终态，那么它还能被继承吗\n  \t\n}\n```\n\n类一旦被声明为终态，将无法再被继承，不允许子类的存在！而方法被声明为final呢？\n\n```java\npublic final void study(){  \u002F\u002F还能重写吗\n    System.out.println(\"学习\");\n}\n```\n\n如果类的成员属性被声明为final，那么必须在构造方法中或是在定义时赋初始值！\n\n```java\nprivate final String name;   \u002F\u002F引用类型不允许再指向其他对象\nprivate final int age;    \u002F\u002F基本类型值不允许发生改变\n\npublic Student(String name, int age) {\n    this.name = name;\n    this.age = age;\n}\n```\n\n学习完封装继承和多态之后，我们推荐在不会再发生改变的成员属性上添加final关键字，JVM会对添加了final关键字的属性进行优化！\n\n#### 抽象类\n\n类本身就是一种抽象，而抽象类，把类还要抽象，也就是说，抽象类可以只保留特征，而不保留具体呈现形态，比如方法可以定义好，但是我可以不去实现它，而是交由子类来进行实现！\n\n```java\npublic abstract class Student {    \u002F\u002F抽象类\n\t\tpublic abstract void test();  \u002F\u002F抽象方法\n}\n```\n\n通过使用`abstract`关键字来表明一个类是一个抽象类，抽象类可以使用`abstract`关键字来表明一个方法为抽象方法，也可以定义普通方法，抽象方法不需要编写具体实现（无方法体）但是**必须**由子类实现（除非子类也是一个抽象类）！\n\n抽象类由于不是具体的类定义，因此无法直接通过new关键字来创建对象！\n\n```java\nStudent s = new Student(){    \u002F\u002F只能直接创建带实现的匿名内部类！\n  public void test(){\n    \n  }\n}\n```\n\n因此，抽象类一般只用作继承使用！抽象类使得继承关系之间更加明确：\n\n```java\npublic void study(){   \u002F\u002F现在只能由子类编写，父类没有定义，更加明确了多态的定义！同一个方法多种实现！\n    System.out.println(\"给你看点好康的\");\n}\n```\n\n#### 接口\n\n接口甚至比抽象类还抽象，他只代表某个确切的功能！也就是只包含方法的定义，甚至都不是一个类！接口包含了一些列方法的具体定义，类可以实现这个接口，表示类支持接口代表的功能（类似于一个插件，只能作为一个附属功能加在主体上，同时具体实现还需要由主体来实现）\n\n```java\npublic interface Eat {\n\tvoid eat(); \n}\n```\n\n通过使用`interface`关键字来表明是一个接口（注意，这里class关键字被替换为了interface）接口只能包含`public`权限的**抽象方法**！（Java8以后可以有默认实现）我们可以通过声明`default`关键字来给抽象方法一个默认实现：\n\n```java\npublic interface Eat {\n    default void eat(){\n        \u002F\u002Fdo something...\n    }\n}\n```\n\n接口中定义的变量，默认为public static final\n\n```java\npublic interface Eat {\n    int a = 1;\n    void eat();\n}\n```\n\n一个类可以实现很多个接口，但是不能理解为多继承！（实际上实现接口是附加功能，和继承的概念有一定出入，顶多说是多继承的一种替代方案）一个类可以附加很多个功能！\n\n```java\npublic class SportsStudent extends Student implements Eat, ...{\n\t\t@Override\n    public void eat() {\n        \n    }\n}\n```\n\n类通过`implements`关键字来声明实现的接口！每个接口之间用逗号隔开！\n\n实现接口的类也能通过instanceof关键字判断，也支持向上和向下转型！\n\n## 内部类\n\n类中可以存在一个类！各种各样的长相怪异的代码就是从这里开始出现的！\n\n### 成员内部类\n\n我们的类中可以在嵌套一个类：\n\n```java\npublic class Test {\n    class Inner{   \u002F\u002F类中定义的一个内部类\n        \n    }\n}\n```\n\n成员内部类和成员变量和成员方法一样，都是属于对象的，也就是说，必须存在外部对象，才能创建内部类的对象！\n\n```java\npublic static void main(String[] args) {\n    Test test = new Test();\n    Test.Inner inner = test.new Inner();   \u002F\u002F写法有那么一丝怪异，但是没毛病！\n}\n```\n\n### 静态内部类\n\n静态内部类其实就和类中的静态变量和静态方法一样，是属于类拥有的，我们可以直接通过`类名.`去访问:\n\n```java\npublic class Test {\n    static class Inner{\n\n    }\n}\n\npublic static void main(String[] args) {\n    Test.Inner inner = new Test.Inner();   \u002F\u002F不用再创建外部类对象了！\n}\n```\n\n### 局部内部类\n\n对，你没猜错，就是和局部变量一样哒~\n\n```java\npublic class Test {\n    public void test(){\n        class Inner{\n\n        }\n        \n        Inner inner = new Inner();\n    }\n}\n```\n\n反正我是没用过！内部类 -> 累不累 -> 反正我累了！\n\n### 匿名内部类\n\n匿名内部类才是我们的重点，也是实现lambda表达式的原理！匿名内部类其实就是在new的时候，直接对接口或是抽象类的实现：\n\n```java\npublic static void main(String[] args) {\n        Eat eat = new Eat() {\n            @Override\n            public void eat() {\n                \u002F\u002FDO something...\n            }\n        };\n    }\n```\n\n我们不用单独去创建一个类来实现，而是可以直接在new的时候写对应的实现！但是，这样写，无法实现复用，只能在这里使用！\n\n#### lambda表达式\n\n读作`λ`表达式，它其实就是我们接口匿名实现的简化，比如说：\n\n```java\npublic static void main(String[] args) {\n        Eat eat = new Eat() {\n            @Override\n            public void eat() {\n                \u002F\u002FDO something...\n            }\n        };\n    }\n\npublic static void main(String[] args) {\n        Eat eat = () -> {};   \u002F\u002F等价于上述内容\n    }\n```\n\nlambda表达式（匿名内部类）只能访问外部的final类型或是隐式final类型的局部变量！\n\n为了方便，JDK默认就为我们提供了专门写函数式的接口，这里只介绍Consumer\n\n## 枚举类\n\n假设现在我们想给小明添加一个状态（跑步、学习、睡觉），外部可以实时获取小明的状态：\n\n```java\npublic class Student {\n    private final String name;\n    private final int age;\n    private String status;\n  \n  \t\u002F\u002F...\n  \n  \tpublic void setStatus(String status) {\n        this.status = status;\n    }\n\n    public String getStatus() {\n        return status;\n    }\n}\n```\n\n但是这样会出现一个问题，如果我们仅仅是存储字符串，似乎外部可以不按照我们规则，传入一些其他的字符串。这显然是不够严谨的！\n\n有没有一种办法，能够更好地去实现这样的状态标记呢？我们希望开发者拿到使用的就是我们定义好的状态，我们可以使用枚举类！\n\n```java\npublic enum Status {\n    RUNNING, STUDY, SLEEP    \u002F\u002F直接写每个状态的名字即可，分号可以不打，但是推荐打上\n}\n```\n\n使用枚举类也非常方便，我们只需要直接访问即可\n\n```java\npublic class Student {\n    private final String name;\n    private final int age;\n    private Status status;\n  \n \t\t\u002F\u002F...\n  \n  \tpublic void setStatus(Status status) {   \u002F\u002F不再是String，而是我们指定的枚举类型\n        this.status = status;\n    }\n\n    public Status getStatus() {\n        return status;\n    }\n}\n\npublic static void main(String[] args) {\n    Student student = new Student(\"小明\", 18);\n    student.setStatus(Status.RUNNING);\n    System.out.println(student.getStatus());\n}\n```\n\n枚举类型使用起来就非常方便了，其实枚举类型的本质就是一个普通的类，但是它继承自`Enum`类，我们定义的每一个状态其实就是一个`public static final`的Status类型成员变量！\n\n```java\n\u002F\u002F Compiled from \"Status.java\"\npublic final class com.test.Status extends java.lang.Enum\u003Ccom.test.Status> {\n  public static final com.test.Status RUNNING;\n  public static final com.test.Status STUDY;\n  public static final com.test.Status SLEEP;\n  public static com.test.Status[] values();\n  public static com.test.Status valueOf(java.lang.String);\n  static {};\n}\n```\n\n既然枚举类型是普通的类，那么我们也可以给枚举类型添加独有的成员方法\n\n```java\npublic enum Status {\n    RUNNING(\"睡觉\"), STUDY(\"学习\"), SLEEP(\"睡觉\");   \u002F\u002F无参构造方法被覆盖，创建枚举需要添加参数（本质就是调用的构造方法！）\n\n    private final String name;    \u002F\u002F枚举的成员变量\n    Status(String name){    \u002F\u002F覆盖原有构造方法（默认private，只能内部使用！）\n        this.name = name;\n    }\n  \n  \tpublic String getName() {   \u002F\u002F获取封装的成员变量\n        return name;\n    }\n}\n\npublic static void main(String[] args) {\n    Student student = new Student(\"小明\", 18);\n    student.setStatus(Status.RUNNING);\n    System.out.println(student.getStatus().getName());\n}\n```\n\n枚举类还自带一些继承下来的实用方法\n\n```java\nStatus.valueOf(\"\")   \u002F\u002F将名称相同的字符串转换为枚举\nStatus.values()   \u002F\u002F快速获取所有的枚举\n```\n\n## 基本类型包装类\n\nJava并不是纯面向对象的语言，虽然Java语言是一个面向对象的语言，但是Java中的基本数据类型却不是面向对象的。在学习泛型和集合之前，基本类型的包装类是一定要讲解的内容！\n\n我们的基本类型，如果想通过对象的形式去使用他们，Java提供的基本类型包装类，使得Java能够更好的体现面向对象的思想，同时也使得基本类型能够支持对象操作！\n\n![img](https:\u002F\u002Fs2.loli.net\u002F2023\u002F08\u002F14\u002FveDjhiS45FWaHnu.png)\n\n* byte  ->  Byte      \n* boolean  ->  Boolean   \n* short  ->  Short    \n* char  ->  Character  \n* int -> Integer    \n* long ->  Long     \n* float -> Float      \n* double -> Double   \n\n包装类实际上就行将我们的基本数据类型，封装成一个类（运用了封装的思想）\n\n```java\nprivate final int value;   \u002F\u002FInteger内部其实本质还是存了一个基本类型的数据，但是我们不能直接操作\n\npublic Integer(int value) {\n    this.value = value;\n}\n```\n\n现在我们操作的就是Integer对象而不是一个int基本类型了！\n\n```java\npublic static void main(String[] args) {\n     Integer i = 1;   \u002F\u002F包装类型可以直接接收对应类型的数据，并变为一个对象！\n     System.out.println(i + i);    \u002F\u002F包装类型可以直接被当做一个基本类型进行操作！\n}\n```\n\n#### 自动装箱和拆箱\n\n那么为什么包装类型能直接使用一个具体值来赋值呢？其实依靠的是自动装箱和拆箱机制\n\n```java\nInteger i = 1;    \u002F\u002F其实这里只是简写了而已\nInteger i = Integer.valueOf(1);  \u002F\u002F编译后真正的样子\n```\n\n调用valueOf来生成一个Integer对象！\n\n```java\npublic static Integer valueOf(int i) {\n    if (i >= IntegerCache.low && i \u003C= IntegerCache.high)   \u002F\u002F注意，Java为了优化，有一个缓存机制，如果是在-128~127之间的数，会直接使用已经缓存好的对象，而不是再去创建新的！（面试常考）\n       return IntegerCache.cache[i + (-IntegerCache.low)];\n  \treturn new Integer(i);   \u002F\u002F返回一个新创建好的对象\n}\n```\n\n而如果使用包装类来进行运算，或是赋值给一个基本类型变量，会进行自动拆箱：\n\n```java\npublic static void main(String[] args) {\n    Integer i = Integer.valueOf(1);\n    int a = i;    \u002F\u002F简写\n    int a = i.intValue();   \u002F\u002F编译后实际的代码\n  \n  \tlong c = i.longValue();   \u002F\u002F其他类型也有！\n}\n```\n\n既然现在是包装类型了，那么我们还能使用`==`来判断两个数是否相等吗？\n\n```java\npublic static void main(String[] args) {\n    Integer i1 = 28914;\n    Integer i2 = 28914;\n\n    System.out.println(i1 == i2);   \u002F\u002F实际上判断是两个对象是否为同一个对象（内存地址是否相同）\n    System.out.println(i1.equals(i2));   \u002F\u002F这个才是真正的值判断！\n}\n```\n\n注意IntegerCache带来的影响！\n\n思考：下面这种情况结果会是什么？\n\n```java\npublic static void main(String[] args) {\n    Integer i1 = 28914;\n    Integer i2 = 28914;\n\n    System.out.println(i1+1 == i2+1);\n}\n```\n\n在集合类的学习中，我们还会继续用到我们的包装类型！\n\n***\n\n## 面向对象编程实战\n\n虽然我们学习了编程，但是我们不能一股脑的所有问题都照着编程的思维去解决，编程只是解决问题的一种手段，灵活的运用我们所学的知识，才是解决问题的最好办法！比如，求1到100所有数的和：\n\n```java\npublic static void main(String[] args) {\n    int sum = 0;\n    for (int i = 1; i \u003C= 100; i++) {   \u002F\u002Ffor循环暴力求解，简单，但是效率似乎低了一些\n        sum += i;\n    }\n    System.out.println(sum);\n}\n\npublic static void main(String[] args) {\n    System.out.println((1 + 100) * 50);  \u002F\u002F高斯求和公式，利用数学，瞬间计算结果！\n}\n```\n\n说到最后，其实数学和逻辑思维才是解决问题的最终办法！\n\n### 对象设计（面向对象、多态运用）\n\n* 设计一个Person抽象类，包含吃饭运动学习三种行为，分为工人、学生、老师三种职业。\n* 设计设计一个接口`考试`，只有老师和学生会考试。\n* 设计一个方法，模拟让人类进入考场，要求只有会考试的人才能进入，并且考试。\n\n### 二分搜索（搜索算法）\n\n现在有一个有序数组（从小到大，数组长度 0 \u003C n \u003C 1000000）如何快速寻找我们想要的数在哪个位置，如果存在请返回下标，不存在返回`-1`即可。\n\n```java\nint[] arr = new int[]{1, 4, 5, 6, 7, 10, 12, 14, 20, 22, 26};   \u002F\u002F测试用例\n\nprivate static int test(int[] arr, int target){\n    \u002F\u002F请在这里实现搜索算法\n}\n```\n\n### 快速排序（排序算法、递归分治）\n\n（开始之前先介绍一下递归！）快速排序其实是一种排序执行效率很高的排序算法，它利用**分治法**来对待排序序列进行分治排序，它的思想主要是通过一趟排序将待排记录分隔成独立的两部分，其中的一部分比关键字小，后面一部分比关键字大，然后再对这前后的两部分分别采用这种方式进行排序，通过递归的运算最终达到整个序列有序。\n\n快速排序就像它的名字一样，快速！在极端情况下，会退化成冒泡排序！\n\n### 0\u002F1背包问题（回溯法、剪枝\u002F动态规划优化）\n\n给定 `n `件物品，每一个物品的重量为 `w[n]`，每个物品的价值为 `v[n]`。现挑选物品放入背包中，假定背包能承受的最大重量为 `capacity`，求装入物品的最大价值是多少?\n\n```java\nint[] w = {2, 3, 4, 5};\nint[] v = {3, 4, 5, 6};\nint capacity = 8;\n```",{"data":466,"status":460,"success":461},[467,472],{"id":8,"image":468,"link":469,"name":470,"type":471},"\u002Fimage\u002Fadv\u002Frainyun-2025-06.webp","https:\u002F\u002Fwww.rainyun.com\u002Fitbaima_","雨云优惠购","cloud",{"id":66,"image":473,"link":474,"name":475,"type":476},"\u002Fimage\u002Fadv\u002Fsimcard-2025-11.webp","https:\u002F\u002Fmall.itbaima.cn","号卡优惠","simcard"]