[{"data":1,"prerenderedAt":7210},["ShallowReactive",2],{"post:\u002Fposts\u002Fjava\u002Fjava-oop-notes":3,"posts:ordered":6933},{"id":4,"title":5,"body":6,"category":6917,"cover":6918,"date":6919,"description":6920,"extension":6921,"featured":6922,"meta":6923,"navigation":665,"path":6924,"seo":6925,"series":6926,"seriesOrder":68,"stem":6927,"tags":6928,"__hash__":6932},"posts\u002Fposts\u002Fjava\u002Fjava-oop-notes.md","Java 面向对象笔记：类、继承、多态与异常",{"type":7,"value":8,"toc":6854},"minimark",[9,16,21,26,34,115,120,147,180,184,191,220,224,228,234,280,284,289,357,361,368,404,408,411,506,509,512,516,520,536,540,589,764,768,808,870,874,879,945,948,956,960,1014,1018,1029,1251,1254,1426,1430,1441,1644,1648,1659,1824,1828,1847,1961,1963,1969,1973,1984,2099,2101,2107,2111,2151,2376,2378,2554,2556,2562,2564,2568,2572,2591,2595,2606,2666,2670,2699,2784,2788,2812,2910,2914,2942,2948,2952,2989,3115,3117,3121,3125,3187,3592,3596,3611,3658,3684,3688,3727,3904,3920,3924,3938,3940,3944,3948,3962,4057,4061,4075,4163,4167,4181,4188,4202,4308,4312,4323,4397,4401,4409,4413,4435,4469,4473,4555,4611,4619,4623,4631,4761,4769,4879,4887,5016,5020,5038,5143,5147,5155,5213,5228,5260,5269,5353,5357,5399,5524,5535,5537,5541,5545,5559,5563,5577,5688,5692,5719,5794,5798,5893,5897,5916,5920,5934,5965,5969,5988,5992,6016,6126,6130,6153,6224,6228,6248,6344,6348,6372,6415,6419,6441,6579,6584,6709,6713,6724,6848,6850],[10,11,12],"blockquote",{},[13,14,15],"p",{},"这是一份个人学习笔记：概念部分是我按自己的理解写的，示例代码也都是自己写的，输出结果是本地跑出来的。参考主要是 Oracle 的 Java 官方文档和语言规范，理解有偏差的地方欢迎指出。",[17,18,20],"h1",{"id":19},"_0-知识回顾","0 知识回顾",[22,23,25],"h2",{"id":24},"_00-数据类型data-type","0.0 数据类型（Data Type）",[13,27,28,29,33],{},"每个 variable（变量）都具有 data type（数据类型），该类型决定了变量可包含的值（values）以及可执行的操作（operations）。不同类型之间不能随意赋值或操作，例如不能将字符串赋值给 int，也不能对 String 使用 ",[30,31,32],"code",{},"++","。",[35,36,41],"pre",{"className":37,"code":38,"language":39,"meta":40,"style":40},"language-java shiki shiki-themes github-light github-dark","int number = 10; \nnumber++; \u002F\u002F 合法\nString course = \"java\"; \ncourse = course.toUpperCase(); \u002F\u002F 合法\n","java","",[30,42,43,66,81,95],{"__ignoreMap":40},[44,45,48,52,56,59,63],"span",{"class":46,"line":47},"line",1,[44,49,51],{"class":50},"szBVR","int",[44,53,55],{"class":54},"sVt8B"," number ",[44,57,58],{"class":50},"=",[44,60,62],{"class":61},"sj4cs"," 10",[44,64,65],{"class":54},"; \n",[44,67,69,72,74,77],{"class":46,"line":68},2,[44,70,71],{"class":54},"number",[44,73,32],{"class":50},[44,75,76],{"class":54},"; ",[44,78,80],{"class":79},"sJ8bj","\u002F\u002F 合法\n",[44,82,84,87,89,93],{"class":46,"line":83},3,[44,85,86],{"class":54},"String course ",[44,88,58],{"class":50},[44,90,92],{"class":91},"sZZnC"," \"java\"",[44,94,65],{"class":54},[44,96,98,101,103,106,110,113],{"class":46,"line":97},4,[44,99,100],{"class":54},"course ",[44,102,58],{"class":50},[44,104,105],{"class":54}," course.",[44,107,109],{"class":108},"sScJk","toUpperCase",[44,111,112],{"class":54},"(); ",[44,114,80],{"class":79},[116,117,119],"h3",{"id":118},"_000-基本数据类型primitive-type","0.0.0 基本数据类型（Primitive Type）",[13,121,122,123,126,127,126,130,126,132,126,135,126,138,126,141,126,144,33],{},"存储 real values（真实值）。共有8种：",[30,124,125],{},"byte",", ",[30,128,129],{},"short",[30,131,51],{},[30,133,134],{},"long",[30,136,137],{},"float",[30,139,140],{},"double",[30,142,143],{},"bool",[30,145,146],{},"char",[35,148,150],{"className":37,"code":149,"language":39,"meta":40,"style":40},"int number1 = 10;\ndouble number2 = 2.1;\n",[30,151,152,166],{"__ignoreMap":40},[44,153,154,156,159,161,163],{"class":46,"line":47},[44,155,51],{"class":50},[44,157,158],{"class":54}," number1 ",[44,160,58],{"class":50},[44,162,62],{"class":61},[44,164,165],{"class":54},";\n",[44,167,168,170,173,175,178],{"class":46,"line":68},[44,169,140],{"class":50},[44,171,172],{"class":54}," number2 ",[44,174,58],{"class":50},[44,176,177],{"class":61}," 2.1",[44,179,165],{"class":54},[116,181,183],{"id":182},"_001-引用数据类型reference-type","0.0.1 引用数据类型（Reference Type）",[13,185,186,187,190],{},"存储 references（引用），而非真实值。",[30,188,189],{},"String"," 和所有 objects（对象）都属于引用类型。",[35,192,194],{"className":37,"code":193,"language":39,"meta":40,"style":40},"String str1 = \"dog\";\nString str2 = \"cat\";\n",[30,195,196,208],{"__ignoreMap":40},[44,197,198,201,203,206],{"class":46,"line":47},[44,199,200],{"class":54},"String str1 ",[44,202,58],{"class":50},[44,204,205],{"class":91}," \"dog\"",[44,207,165],{"class":54},[44,209,210,213,215,218],{"class":46,"line":68},[44,211,212],{"class":54},"String str2 ",[44,214,58],{"class":50},[44,216,217],{"class":91}," \"cat\"",[44,219,165],{"class":54},[22,221,223],{"id":222},"_01-赋值assignment","0.1 赋值（Assignment）",[116,225,227],{"id":226},"_010-基本数据类型的赋值","0.1.0 基本数据类型的赋值",[13,229,230,231,233],{},"使用 operator ",[30,232,58],{}," 时，会直接复制变量的真实值。",[35,235,237],{"className":37,"code":236,"language":39,"meta":40,"style":40},"int num1 = 5;\nint num2 = 12;\nnum2 = num1; \u002F\u002F num2 变为 5，num1 保持 5\n",[30,238,239,253,267],{"__ignoreMap":40},[44,240,241,243,246,248,251],{"class":46,"line":47},[44,242,51],{"class":50},[44,244,245],{"class":54}," num1 ",[44,247,58],{"class":50},[44,249,250],{"class":61}," 5",[44,252,165],{"class":54},[44,254,255,257,260,262,265],{"class":46,"line":68},[44,256,51],{"class":50},[44,258,259],{"class":54}," num2 ",[44,261,58],{"class":50},[44,263,264],{"class":61}," 12",[44,266,165],{"class":54},[44,268,269,272,274,277],{"class":46,"line":83},[44,270,271],{"class":54},"num2 ",[44,273,58],{"class":50},[44,275,276],{"class":54}," num1; ",[44,278,279],{"class":79},"\u002F\u002F num2 变为 5，num1 保持 5\n",[116,281,283],{"id":282},"_011-引用数据类型的赋值","0.1.1 引用数据类型的赋值",[13,285,230,286,288],{},[30,287,58],{}," 时，复制的是 references（引用），而非对象的值。",[35,290,292],{"className":37,"code":291,"language":39,"meta":40,"style":40},"Book book1 = new Book(\"Java 编程思想\", \"Bruce Eckel\");\nBook book2 = new Book(\"代码大全\", \"Steve McConnell\");\nbook2 = book1; \u002F\u002F book2 和 book1 指向同一个 Book 对象\n",[30,293,294,321,344],{"__ignoreMap":40},[44,295,296,299,301,304,307,310,313,315,318],{"class":46,"line":47},[44,297,298],{"class":54},"Book book1 ",[44,300,58],{"class":50},[44,302,303],{"class":50}," new",[44,305,306],{"class":108}," Book",[44,308,309],{"class":54},"(",[44,311,312],{"class":91},"\"Java 编程思想\"",[44,314,126],{"class":54},[44,316,317],{"class":91},"\"Bruce Eckel\"",[44,319,320],{"class":54},");\n",[44,322,323,326,328,330,332,334,337,339,342],{"class":46,"line":68},[44,324,325],{"class":54},"Book book2 ",[44,327,58],{"class":50},[44,329,303],{"class":50},[44,331,306],{"class":108},[44,333,309],{"class":54},[44,335,336],{"class":91},"\"代码大全\"",[44,338,126],{"class":54},[44,340,341],{"class":91},"\"Steve McConnell\"",[44,343,320],{"class":54},[44,345,346,349,351,354],{"class":46,"line":83},[44,347,348],{"class":54},"book2 ",[44,350,58],{"class":50},[44,352,353],{"class":54}," book1; ",[44,355,356],{"class":79},"\u002F\u002F book2 和 book1 指向同一个 Book 对象\n",[22,358,360],{"id":359},"_02-对象实例化与访问","0.2 对象实例化与访问",[13,362,363,364,367],{},"使用关键字 ",[30,365,366],{},"new"," 来 instantiate（实例化） objects（对象）。通常需要一个 reference variable（引用变量）来指向该对象，并通过该变量来访问对象。",[35,369,371],{"className":37,"code":370,"language":39,"meta":40,"style":40},"Book myBook = new Book();\nSystem.out.println(myBook.getTitle());\n",[30,372,373,387],{"__ignoreMap":40},[44,374,375,378,380,382,384],{"class":46,"line":47},[44,376,377],{"class":54},"Book myBook ",[44,379,58],{"class":50},[44,381,303],{"class":50},[44,383,306],{"class":108},[44,385,386],{"class":54},"();\n",[44,388,389,392,395,398,401],{"class":46,"line":68},[44,390,391],{"class":54},"System.out.",[44,393,394],{"class":108},"println",[44,396,397],{"class":54},"(myBook.",[44,399,400],{"class":108},"getTitle",[44,402,403],{"class":54},"());\n",[22,405,407],{"id":406},"_03-别名alias与内存分析","0.3 别名（Alias）与内存分析",[13,409,410],{},"当多个 references（引用）指向同一个 object（对象）时，这些引用被称为该对象的 alias（别名）。通过任何一个 alias（别名）修改对象的 state（状态），都会影响其他所有别名。",[35,412,414],{"className":37,"code":413,"language":39,"meta":40,"style":40},"Book book1 = new Book(\"Java 编程思想\");\nBook book2 = new Book(\"代码大全\");\nbook2 = book1;\nbook2.setTitle(\"重构\");\nSystem.out.println(book1.getTitle()); \u002F\u002F 输出 \"重构\"\nSystem.out.println(book2.getTitle()); \u002F\u002F 输出 \"重构\"\n",[30,415,416,432,448,457,472,490],{"__ignoreMap":40},[44,417,418,420,422,424,426,428,430],{"class":46,"line":47},[44,419,298],{"class":54},[44,421,58],{"class":50},[44,423,303],{"class":50},[44,425,306],{"class":108},[44,427,309],{"class":54},[44,429,312],{"class":91},[44,431,320],{"class":54},[44,433,434,436,438,440,442,444,446],{"class":46,"line":68},[44,435,325],{"class":54},[44,437,58],{"class":50},[44,439,303],{"class":50},[44,441,306],{"class":108},[44,443,309],{"class":54},[44,445,336],{"class":91},[44,447,320],{"class":54},[44,449,450,452,454],{"class":46,"line":83},[44,451,348],{"class":54},[44,453,58],{"class":50},[44,455,456],{"class":54}," book1;\n",[44,458,459,462,465,467,470],{"class":46,"line":97},[44,460,461],{"class":54},"book2.",[44,463,464],{"class":108},"setTitle",[44,466,309],{"class":54},[44,468,469],{"class":91},"\"重构\"",[44,471,320],{"class":54},[44,473,475,477,479,482,484,487],{"class":46,"line":474},5,[44,476,391],{"class":54},[44,478,394],{"class":108},[44,480,481],{"class":54},"(book1.",[44,483,400],{"class":108},[44,485,486],{"class":54},"()); ",[44,488,489],{"class":79},"\u002F\u002F 输出 \"重构\"\n",[44,491,493,495,497,500,502,504],{"class":46,"line":492},6,[44,494,391],{"class":54},[44,496,394],{"class":108},[44,498,499],{"class":54},"(book2.",[44,501,400],{"class":108},[44,503,486],{"class":54},[44,505,489],{"class":79},[13,507,508],{},"失去所有引用的对象（如原名为「代码大全」的那个 Book 对象）将成为 garbage（垃圾），由 Garbage Collector（垃圾回收器）自动回收。",[510,511],"hr",{},[17,513,515],{"id":514},"_1-类与对象","1 类与对象",[22,517,519],{"id":518},"_10-初识面向对象introduction-to-oop","1.0 初识面向对象（Introduction to OOP）",[521,522,523,527,530,533],"ul",{},[524,525,526],"li",{},"Object-Oriented Programming (OOP，面向对象编程) 是建立在 Classes (类) 和 Objects (对象) 概念上的 Programming Paradigm (编程范式)，而非 Functions (函数)。",[524,528,529],{},"OOP 中 Classes 和 Objects 用于 Model Real-World Entities (建模现实世界实体)。",[524,531,532],{},"Object (对象) 由 Data (数据，定义 State 状态) 和 Methods (方法，定义 Behavior 行为) 组成。",[524,534,535],{},"OOP 最早用于 Simulation Programs (仿真程序)，如 Simula, 1967。",[22,537,539],{"id":538},"_11-类与对象classes-and-objects","1.1 类与对象（Classes and Objects）",[521,541,542,545,548,551,567,583,586],{},[524,543,544],{},"Class (类) 是建模 Real-World Entity (现实世界实体) 的 Blueprint (蓝图)。",[524,546,547],{},"Class 定义 Object 的 Attributes (属性\u002F数据) 和 Methods (方法\u002F行为) 以操作这些 Attributes。",[524,549,550],{},"Object (对象) 是 Class 的 Instance (实例)。",[524,552,553,554,126,557,560,561,126,564,33],{},"示例：Book 类有 Attributes ",[30,555,556],{},"title",[30,558,559],{},"author","；Methods ",[30,562,563],{},"info()",[30,565,566],{},"borrow()",[524,568,569,570,126,572,126,574,126,577,580,581,33],{},"Book 类定义 Attributes ",[30,571,556],{},[30,573,559],{},[30,575,576],{},"pages",[30,578,579],{},"price","；Method ",[30,582,563],{},[524,584,585],{},"《Java 编程思想》《代码大全》《重构》这些具体书目，就是这个类的 Object。",[524,587,588],{},"Objects 存储各自 Unique Data (唯一数据)，但 Share (共享) Class 的 Methods。",[35,590,592],{"className":37,"code":591,"language":39,"meta":40,"style":40},"public class Book {\n    String title = \"Java 编程思想\";\n    String author = \"Bruce Eckel\";\n    int pages = 850;\n    double price = 108.0;\n\n    public void info() {\n        System.out.println(\"书名：\" + title);\n        System.out.println(\"作者：\" + author);\n        System.out.println(\"页数：\" + pages);\n        System.out.println(\"定价：\" + price);\n    }\n}\n",[30,593,594,607,619,631,646,661,667,682,701,718,735,752,758],{"__ignoreMap":40},[44,595,596,599,602,604],{"class":46,"line":47},[44,597,598],{"class":50},"public",[44,600,601],{"class":50}," class",[44,603,306],{"class":108},[44,605,606],{"class":54}," {\n",[44,608,609,612,614,617],{"class":46,"line":68},[44,610,611],{"class":54},"    String title ",[44,613,58],{"class":50},[44,615,616],{"class":91}," \"Java 编程思想\"",[44,618,165],{"class":54},[44,620,621,624,626,629],{"class":46,"line":83},[44,622,623],{"class":54},"    String author ",[44,625,58],{"class":50},[44,627,628],{"class":91}," \"Bruce Eckel\"",[44,630,165],{"class":54},[44,632,633,636,639,641,644],{"class":46,"line":97},[44,634,635],{"class":50},"    int",[44,637,638],{"class":54}," pages ",[44,640,58],{"class":50},[44,642,643],{"class":61}," 850",[44,645,165],{"class":54},[44,647,648,651,654,656,659],{"class":46,"line":474},[44,649,650],{"class":50},"    double",[44,652,653],{"class":54}," price ",[44,655,58],{"class":50},[44,657,658],{"class":61}," 108.0",[44,660,165],{"class":54},[44,662,663],{"class":46,"line":492},[44,664,666],{"emptyLinePlaceholder":665},true,"\n",[44,668,670,673,676,679],{"class":46,"line":669},7,[44,671,672],{"class":50},"    public",[44,674,675],{"class":50}," void",[44,677,678],{"class":108}," info",[44,680,681],{"class":54},"() {\n",[44,683,685,688,690,692,695,698],{"class":46,"line":684},8,[44,686,687],{"class":54},"        System.out.",[44,689,394],{"class":108},[44,691,309],{"class":54},[44,693,694],{"class":91},"\"书名：\"",[44,696,697],{"class":50}," +",[44,699,700],{"class":54}," title);\n",[44,702,704,706,708,710,713,715],{"class":46,"line":703},9,[44,705,687],{"class":54},[44,707,394],{"class":108},[44,709,309],{"class":54},[44,711,712],{"class":91},"\"作者：\"",[44,714,697],{"class":50},[44,716,717],{"class":54}," author);\n",[44,719,721,723,725,727,730,732],{"class":46,"line":720},10,[44,722,687],{"class":54},[44,724,394],{"class":108},[44,726,309],{"class":54},[44,728,729],{"class":91},"\"页数：\"",[44,731,697],{"class":50},[44,733,734],{"class":54}," pages);\n",[44,736,738,740,742,744,747,749],{"class":46,"line":737},11,[44,739,687],{"class":54},[44,741,394],{"class":108},[44,743,309],{"class":54},[44,745,746],{"class":91},"\"定价：\"",[44,748,697],{"class":50},[44,750,751],{"class":54}," price);\n",[44,753,755],{"class":46,"line":754},12,[44,756,757],{"class":54},"    }\n",[44,759,761],{"class":46,"line":760},13,[44,762,763],{"class":54},"}\n",[22,765,767],{"id":766},"_12-java-程序结构java-program-structure","1.2 Java 程序结构（Java Program Structure）",[521,769,770,773,776,783,792,802],{},[524,771,772],{},"每个 Java Console Program (控制台程序) 都有 Main Method (主方法)，作为 Execution (执行) 的 Entry Point (入口点)。",[524,774,775],{},"Main Method 通常位于名为 Program 的 Class 中。",[524,777,778,779,782],{},"每个 Java Class 位于独立文件中，Classname 与 Filename (以 ",[30,780,781],{},".java"," 结尾) 必须相同。",[524,784,785,787,788,791],{},[30,786,781],{}," 文件编译为 ",[30,789,790],{},".class"," 文件。",[524,793,794,795,798,799,33],{},"编译：",[30,796,797],{},"javac *.java","；运行：",[30,800,801],{},"java Program",[524,803,804,807],{},[30,805,806],{},"args"," Array 包含程序的 Inputs (输入)。",[35,809,811],{"className":37,"code":810,"language":39,"meta":40,"style":40},"public class Program {\n    public static void main(String[] args) {\n        System.out.println(\"Hello World!\");\n    }\n}\n",[30,812,813,824,849,862,866],{"__ignoreMap":40},[44,814,815,817,819,822],{"class":46,"line":47},[44,816,598],{"class":50},[44,818,601],{"class":50},[44,820,821],{"class":108}," Program",[44,823,606],{"class":54},[44,825,826,828,831,833,836,838,840,843,846],{"class":46,"line":68},[44,827,672],{"class":50},[44,829,830],{"class":50}," static",[44,832,675],{"class":50},[44,834,835],{"class":108}," main",[44,837,309],{"class":54},[44,839,189],{"class":50},[44,841,842],{"class":54},"[] ",[44,844,806],{"class":845},"s4XuR",[44,847,848],{"class":54},") {\n",[44,850,851,853,855,857,860],{"class":46,"line":83},[44,852,687],{"class":54},[44,854,394],{"class":108},[44,856,309],{"class":54},[44,858,859],{"class":91},"\"Hello World!\"",[44,861,320],{"class":54},[44,863,864],{"class":46,"line":97},[44,865,757],{"class":54},[44,867,868],{"class":46,"line":474},[44,869,763],{"class":54},[22,871,873],{"id":872},"_13-使用-book-类","1.3 使用 Book 类",[521,875,876],{},[524,877,878],{},"从 Book Class Instantiate (实例化) 一个 Book Object，然后调用其 Methods。",[35,880,882],{"className":37,"code":881,"language":39,"meta":40,"style":40},"public class Program {\n    public static void main(String[] args) {\n        Book firstBook = new Book();\n        firstBook.info();\n    }\n}\n",[30,883,884,894,914,927,937,941],{"__ignoreMap":40},[44,885,886,888,890,892],{"class":46,"line":47},[44,887,598],{"class":50},[44,889,601],{"class":50},[44,891,821],{"class":108},[44,893,606],{"class":54},[44,895,896,898,900,902,904,906,908,910,912],{"class":46,"line":68},[44,897,672],{"class":50},[44,899,830],{"class":50},[44,901,675],{"class":50},[44,903,835],{"class":108},[44,905,309],{"class":54},[44,907,189],{"class":50},[44,909,842],{"class":54},[44,911,806],{"class":845},[44,913,848],{"class":54},[44,915,916,919,921,923,925],{"class":46,"line":83},[44,917,918],{"class":54},"        Book firstBook ",[44,920,58],{"class":50},[44,922,303],{"class":50},[44,924,306],{"class":108},[44,926,386],{"class":54},[44,928,929,932,935],{"class":46,"line":97},[44,930,931],{"class":54},"        firstBook.",[44,933,934],{"class":108},"info",[44,936,386],{"class":54},[44,938,939],{"class":46,"line":474},[44,940,757],{"class":54},[44,942,943],{"class":46,"line":492},[44,944,763],{"class":54},[13,946,947],{},"输出：",[35,949,954],{"className":950,"code":952,"language":953,"meta":40},[951],"language-text","书名：Java 编程思想\n作者：Bruce Eckel\n页数：850\n定价：108.0\n","text",[30,955,952],{"__ignoreMap":40},[22,957,959],{"id":958},"_14-设计练习先从需求里找出类","1.4 设计练习：先从需求里找出「类」",[521,961,962,965,968],{},[524,963,964],{},"拿到一个需求，先把里面的名词列出来，它们通常就是候选的 Class (类)，比如账单、会员、购物车。",[524,966,967],{},"再给每个类定下它的 Attributes (属性) 和 Methods (方法)，然后造两个具体的 Object (对象) 出来验证设计是否说得通。",[524,969,970,971],{},"Java Class Name 规则：\n",[521,972,973,976,982,996,999,1002],{},[524,974,975],{},"不能有 Spaces (空格)。",[524,977,978,979,33],{},"多词名称每个词首字母大写，如 ",[30,980,981],{},"MyClassName",[524,983,984,985,988,989,992,993,33],{},"使用 Descriptive Names (描述性名称)，如 ",[30,986,987],{},"Customer"," 而非 ",[30,990,991],{},"C"," 或 ",[30,994,995],{},"temp",[524,997,998],{},"不能与 Keywords\u002FReserved Words (关键字\u002F保留字) 匹配。",[524,1000,1001],{},"公开类必须与 Java File Name 相同。",[524,1003,1004,1005,126,1008,126,1011,33],{},"示例：",[30,1006,1007],{},"Order",[30,1009,1010],{},"OrderSummary",[30,1012,1013],{},"Order_Summary",[22,1015,1017],{"id":1016},"_15-构造器constructor","1.5 构造器（Constructor）",[521,1019,1020,1023,1026],{},[524,1021,1022],{},"Constructor (构造器\u002F构造方法) 是与 Class 同名的方法，在 Object-Instantiation (对象实例化) 时第一个自动执行。",[524,1024,1025],{},"Constructor 可接受 Inputs 来初始化 Object。",[524,1027,1028],{},"下面这个 Book 类用 Constructor 设置 Instance Variables (实例变量)。",[35,1030,1032],{"className":37,"code":1031,"language":39,"meta":40,"style":40},"public class Book {\n    private String title;\n    private String author;\n    private int pages;\n    private double price;\n\n    public Book(String title, String author, int pages, double price) {\n        this.title = title;\n        this.author = author;\n        this.pages = pages;\n        this.price = price;\n    }\n\n    public void info() {\n        System.out.println(\"书名：\" + title);\n        System.out.println(\"作者：\" + author);\n        System.out.println(\"页数：\" + pages);\n        System.out.println(\"定价：\" + price);\n    }\n}\n",[30,1033,1034,1044,1052,1059,1069,1079,1083,1115,1128,1140,1151,1162,1166,1170,1181,1196,1211,1226,1241,1246],{"__ignoreMap":40},[44,1035,1036,1038,1040,1042],{"class":46,"line":47},[44,1037,598],{"class":50},[44,1039,601],{"class":50},[44,1041,306],{"class":108},[44,1043,606],{"class":54},[44,1045,1046,1049],{"class":46,"line":68},[44,1047,1048],{"class":50},"    private",[44,1050,1051],{"class":54}," String title;\n",[44,1053,1054,1056],{"class":46,"line":83},[44,1055,1048],{"class":50},[44,1057,1058],{"class":54}," String author;\n",[44,1060,1061,1063,1066],{"class":46,"line":97},[44,1062,1048],{"class":50},[44,1064,1065],{"class":50}," int",[44,1067,1068],{"class":54}," pages;\n",[44,1070,1071,1073,1076],{"class":46,"line":474},[44,1072,1048],{"class":50},[44,1074,1075],{"class":50}," double",[44,1077,1078],{"class":54}," price;\n",[44,1080,1081],{"class":46,"line":492},[44,1082,666],{"emptyLinePlaceholder":665},[44,1084,1085,1087,1089,1092,1094,1097,1099,1101,1103,1106,1108,1110,1113],{"class":46,"line":669},[44,1086,672],{"class":50},[44,1088,306],{"class":108},[44,1090,1091],{"class":54},"(String ",[44,1093,556],{"class":845},[44,1095,1096],{"class":54},", String ",[44,1098,559],{"class":845},[44,1100,126],{"class":54},[44,1102,51],{"class":50},[44,1104,1105],{"class":845}," pages",[44,1107,126],{"class":54},[44,1109,140],{"class":50},[44,1111,1112],{"class":845}," price",[44,1114,848],{"class":54},[44,1116,1117,1120,1123,1125],{"class":46,"line":684},[44,1118,1119],{"class":61},"        this",[44,1121,1122],{"class":54},".title ",[44,1124,58],{"class":50},[44,1126,1127],{"class":54}," title;\n",[44,1129,1130,1132,1135,1137],{"class":46,"line":703},[44,1131,1119],{"class":61},[44,1133,1134],{"class":54},".author ",[44,1136,58],{"class":50},[44,1138,1139],{"class":54}," author;\n",[44,1141,1142,1144,1147,1149],{"class":46,"line":720},[44,1143,1119],{"class":61},[44,1145,1146],{"class":54},".pages ",[44,1148,58],{"class":50},[44,1150,1068],{"class":54},[44,1152,1153,1155,1158,1160],{"class":46,"line":737},[44,1154,1119],{"class":61},[44,1156,1157],{"class":54},".price ",[44,1159,58],{"class":50},[44,1161,1078],{"class":54},[44,1163,1164],{"class":46,"line":754},[44,1165,757],{"class":54},[44,1167,1168],{"class":46,"line":760},[44,1169,666],{"emptyLinePlaceholder":665},[44,1171,1173,1175,1177,1179],{"class":46,"line":1172},14,[44,1174,672],{"class":50},[44,1176,675],{"class":50},[44,1178,678],{"class":108},[44,1180,681],{"class":54},[44,1182,1184,1186,1188,1190,1192,1194],{"class":46,"line":1183},15,[44,1185,687],{"class":54},[44,1187,394],{"class":108},[44,1189,309],{"class":54},[44,1191,694],{"class":91},[44,1193,697],{"class":50},[44,1195,700],{"class":54},[44,1197,1199,1201,1203,1205,1207,1209],{"class":46,"line":1198},16,[44,1200,687],{"class":54},[44,1202,394],{"class":108},[44,1204,309],{"class":54},[44,1206,712],{"class":91},[44,1208,697],{"class":50},[44,1210,717],{"class":54},[44,1212,1214,1216,1218,1220,1222,1224],{"class":46,"line":1213},17,[44,1215,687],{"class":54},[44,1217,394],{"class":108},[44,1219,309],{"class":54},[44,1221,729],{"class":91},[44,1223,697],{"class":50},[44,1225,734],{"class":54},[44,1227,1229,1231,1233,1235,1237,1239],{"class":46,"line":1228},18,[44,1230,687],{"class":54},[44,1232,394],{"class":108},[44,1234,309],{"class":54},[44,1236,746],{"class":91},[44,1238,697],{"class":50},[44,1240,751],{"class":54},[44,1242,1244],{"class":46,"line":1243},19,[44,1245,757],{"class":54},[44,1247,1249],{"class":46,"line":1248},20,[44,1250,763],{"class":54},[13,1252,1253],{},"使用：",[35,1255,1257],{"className":37,"code":1256,"language":39,"meta":40,"style":40},"Book b1 = new Book(\"Java 编程思想\", \"Bruce Eckel\", 850, 108.0);\nBook b2 = new Book(\"代码大全\", \"Steve McConnell\", 900, 128.0);\nBook b3 = new Book(\"重构\", \"Martin Fowler\", 448, 89.0);\nBook b4 = new Book(\"深入理解 Java 虚拟机\", \"周志明\", 520, 129.0);\n\nb1.info();\nb2.info();\nb3.info();\nb4.info();\n",[30,1258,1259,1290,1321,1353,1386,1390,1399,1408,1417],{"__ignoreMap":40},[44,1260,1261,1264,1266,1268,1270,1272,1274,1276,1278,1280,1283,1285,1288],{"class":46,"line":47},[44,1262,1263],{"class":54},"Book b1 ",[44,1265,58],{"class":50},[44,1267,303],{"class":50},[44,1269,306],{"class":108},[44,1271,309],{"class":54},[44,1273,312],{"class":91},[44,1275,126],{"class":54},[44,1277,317],{"class":91},[44,1279,126],{"class":54},[44,1281,1282],{"class":61},"850",[44,1284,126],{"class":54},[44,1286,1287],{"class":61},"108.0",[44,1289,320],{"class":54},[44,1291,1292,1295,1297,1299,1301,1303,1305,1307,1309,1311,1314,1316,1319],{"class":46,"line":68},[44,1293,1294],{"class":54},"Book b2 ",[44,1296,58],{"class":50},[44,1298,303],{"class":50},[44,1300,306],{"class":108},[44,1302,309],{"class":54},[44,1304,336],{"class":91},[44,1306,126],{"class":54},[44,1308,341],{"class":91},[44,1310,126],{"class":54},[44,1312,1313],{"class":61},"900",[44,1315,126],{"class":54},[44,1317,1318],{"class":61},"128.0",[44,1320,320],{"class":54},[44,1322,1323,1326,1328,1330,1332,1334,1336,1338,1341,1343,1346,1348,1351],{"class":46,"line":83},[44,1324,1325],{"class":54},"Book b3 ",[44,1327,58],{"class":50},[44,1329,303],{"class":50},[44,1331,306],{"class":108},[44,1333,309],{"class":54},[44,1335,469],{"class":91},[44,1337,126],{"class":54},[44,1339,1340],{"class":91},"\"Martin Fowler\"",[44,1342,126],{"class":54},[44,1344,1345],{"class":61},"448",[44,1347,126],{"class":54},[44,1349,1350],{"class":61},"89.0",[44,1352,320],{"class":54},[44,1354,1355,1358,1360,1362,1364,1366,1369,1371,1374,1376,1379,1381,1384],{"class":46,"line":97},[44,1356,1357],{"class":54},"Book b4 ",[44,1359,58],{"class":50},[44,1361,303],{"class":50},[44,1363,306],{"class":108},[44,1365,309],{"class":54},[44,1367,1368],{"class":91},"\"深入理解 Java 虚拟机\"",[44,1370,126],{"class":54},[44,1372,1373],{"class":91},"\"周志明\"",[44,1375,126],{"class":54},[44,1377,1378],{"class":61},"520",[44,1380,126],{"class":54},[44,1382,1383],{"class":61},"129.0",[44,1385,320],{"class":54},[44,1387,1388],{"class":46,"line":474},[44,1389,666],{"emptyLinePlaceholder":665},[44,1391,1392,1395,1397],{"class":46,"line":492},[44,1393,1394],{"class":54},"b1.",[44,1396,934],{"class":108},[44,1398,386],{"class":54},[44,1400,1401,1404,1406],{"class":46,"line":669},[44,1402,1403],{"class":54},"b2.",[44,1405,934],{"class":108},[44,1407,386],{"class":54},[44,1409,1410,1413,1415],{"class":46,"line":684},[44,1411,1412],{"class":54},"b3.",[44,1414,934],{"class":108},[44,1416,386],{"class":54},[44,1418,1419,1422,1424],{"class":46,"line":703},[44,1420,1421],{"class":54},"b4.",[44,1423,934],{"class":108},[44,1425,386],{"class":54},[22,1427,1429],{"id":1428},"_16-组合composition","1.6 组合（Composition）",[521,1431,1432,1435,1438],{},[524,1433,1434],{},"Composition (组合) 指一个 Class 包含 Objects 作为 Instance Variables (实例变量)。",[524,1436,1437],{},"Class 可通过这些 Objects 的 Public Attributes 和 Methods 进行交互。",[524,1439,1440],{},"下面这个 Bookshelf 类就把 4 个 Book Object 当作自己的 Instance Variables。",[35,1442,1444],{"className":37,"code":1443,"language":39,"meta":40,"style":40},"public class Bookshelf {\n    private Book top;\n    private Book second;\n    private Book third;\n    private Book bottom;\n\n    public Bookshelf(Book top, Book second, Book third, Book bottom) {\n        this.top = top;\n        this.second = second;\n        this.third = third;\n        this.bottom = bottom;\n    }\n\n    public void listAll() {\n        System.out.println(\"这一格书架上的书：\");\n        top.info();\n        second.info();\n        third.info();\n        bottom.info();\n    }\n}\n",[30,1445,1446,1457,1464,1471,1478,1485,1489,1519,1531,1543,1555,1567,1571,1575,1586,1599,1608,1617,1626,1635,1639],{"__ignoreMap":40},[44,1447,1448,1450,1452,1455],{"class":46,"line":47},[44,1449,598],{"class":50},[44,1451,601],{"class":50},[44,1453,1454],{"class":108}," Bookshelf",[44,1456,606],{"class":54},[44,1458,1459,1461],{"class":46,"line":68},[44,1460,1048],{"class":50},[44,1462,1463],{"class":54}," Book top;\n",[44,1465,1466,1468],{"class":46,"line":83},[44,1467,1048],{"class":50},[44,1469,1470],{"class":54}," Book second;\n",[44,1472,1473,1475],{"class":46,"line":97},[44,1474,1048],{"class":50},[44,1476,1477],{"class":54}," Book third;\n",[44,1479,1480,1482],{"class":46,"line":474},[44,1481,1048],{"class":50},[44,1483,1484],{"class":54}," Book bottom;\n",[44,1486,1487],{"class":46,"line":492},[44,1488,666],{"emptyLinePlaceholder":665},[44,1490,1491,1493,1495,1498,1501,1504,1507,1509,1512,1514,1517],{"class":46,"line":669},[44,1492,672],{"class":50},[44,1494,1454],{"class":108},[44,1496,1497],{"class":54},"(Book ",[44,1499,1500],{"class":845},"top",[44,1502,1503],{"class":54},", Book ",[44,1505,1506],{"class":845},"second",[44,1508,1503],{"class":54},[44,1510,1511],{"class":845},"third",[44,1513,1503],{"class":54},[44,1515,1516],{"class":845},"bottom",[44,1518,848],{"class":54},[44,1520,1521,1523,1526,1528],{"class":46,"line":684},[44,1522,1119],{"class":61},[44,1524,1525],{"class":54},".top ",[44,1527,58],{"class":50},[44,1529,1530],{"class":54}," top;\n",[44,1532,1533,1535,1538,1540],{"class":46,"line":703},[44,1534,1119],{"class":61},[44,1536,1537],{"class":54},".second ",[44,1539,58],{"class":50},[44,1541,1542],{"class":54}," second;\n",[44,1544,1545,1547,1550,1552],{"class":46,"line":720},[44,1546,1119],{"class":61},[44,1548,1549],{"class":54},".third ",[44,1551,58],{"class":50},[44,1553,1554],{"class":54}," third;\n",[44,1556,1557,1559,1562,1564],{"class":46,"line":737},[44,1558,1119],{"class":61},[44,1560,1561],{"class":54},".bottom ",[44,1563,58],{"class":50},[44,1565,1566],{"class":54}," bottom;\n",[44,1568,1569],{"class":46,"line":754},[44,1570,757],{"class":54},[44,1572,1573],{"class":46,"line":760},[44,1574,666],{"emptyLinePlaceholder":665},[44,1576,1577,1579,1581,1584],{"class":46,"line":1172},[44,1578,672],{"class":50},[44,1580,675],{"class":50},[44,1582,1583],{"class":108}," listAll",[44,1585,681],{"class":54},[44,1587,1588,1590,1592,1594,1597],{"class":46,"line":1183},[44,1589,687],{"class":54},[44,1591,394],{"class":108},[44,1593,309],{"class":54},[44,1595,1596],{"class":91},"\"这一格书架上的书：\"",[44,1598,320],{"class":54},[44,1600,1601,1604,1606],{"class":46,"line":1198},[44,1602,1603],{"class":54},"        top.",[44,1605,934],{"class":108},[44,1607,386],{"class":54},[44,1609,1610,1613,1615],{"class":46,"line":1213},[44,1611,1612],{"class":54},"        second.",[44,1614,934],{"class":108},[44,1616,386],{"class":54},[44,1618,1619,1622,1624],{"class":46,"line":1228},[44,1620,1621],{"class":54},"        third.",[44,1623,934],{"class":108},[44,1625,386],{"class":54},[44,1627,1628,1631,1633],{"class":46,"line":1243},[44,1629,1630],{"class":54},"        bottom.",[44,1632,934],{"class":108},[44,1634,386],{"class":54},[44,1636,1637],{"class":46,"line":1248},[44,1638,757],{"class":54},[44,1640,1642],{"class":46,"line":1641},21,[44,1643,763],{"class":54},[22,1645,1647],{"id":1646},"_17-作用域scope","1.7 作用域（Scope）",[521,1649,1650,1653,1656],{},[524,1651,1652],{},"Scope (作用域) 是 Variable (变量) 的 Visibility (可见性)，由声明位置决定。",[524,1654,1655],{},"Local Variable (局部变量) 在 Method 中声明，仅对该 Method 可见。",[524,1657,1658],{},"Instance Variable (实例变量) 在 Class 中声明，对该 Class 的所有 Methods 可见。",[35,1660,1662],{"className":37,"code":1661,"language":39,"meta":40,"style":40},"public class Counter {\n    private String label = \"总计数器\";\n\n    public void increaseByTen() {\n        int step = 10; \u002F\u002F local variable：只在这个方法里存在\n        System.out.println(\"step = \" + step);\n        System.out.println(\"label = \" + label);\n    }\n\n    public void increaseByTwenty() {\n        int step = 20; \u002F\u002F 另一个方法里的局部变量，与上面互不相干\n        System.out.println(\"step = \" + step);\n        System.out.println(\"label = \" + label);\n    }\n}\n",[30,1663,1664,1675,1689,1693,1704,1721,1737,1753,1757,1761,1772,1788,1802,1816,1820],{"__ignoreMap":40},[44,1665,1666,1668,1670,1673],{"class":46,"line":47},[44,1667,598],{"class":50},[44,1669,601],{"class":50},[44,1671,1672],{"class":108}," Counter",[44,1674,606],{"class":54},[44,1676,1677,1679,1682,1684,1687],{"class":46,"line":68},[44,1678,1048],{"class":50},[44,1680,1681],{"class":54}," String label ",[44,1683,58],{"class":50},[44,1685,1686],{"class":91}," \"总计数器\"",[44,1688,165],{"class":54},[44,1690,1691],{"class":46,"line":83},[44,1692,666],{"emptyLinePlaceholder":665},[44,1694,1695,1697,1699,1702],{"class":46,"line":97},[44,1696,672],{"class":50},[44,1698,675],{"class":50},[44,1700,1701],{"class":108}," increaseByTen",[44,1703,681],{"class":54},[44,1705,1706,1709,1712,1714,1716,1718],{"class":46,"line":474},[44,1707,1708],{"class":50},"        int",[44,1710,1711],{"class":54}," step ",[44,1713,58],{"class":50},[44,1715,62],{"class":61},[44,1717,76],{"class":54},[44,1719,1720],{"class":79},"\u002F\u002F local variable：只在这个方法里存在\n",[44,1722,1723,1725,1727,1729,1732,1734],{"class":46,"line":492},[44,1724,687],{"class":54},[44,1726,394],{"class":108},[44,1728,309],{"class":54},[44,1730,1731],{"class":91},"\"step = \"",[44,1733,697],{"class":50},[44,1735,1736],{"class":54}," step);\n",[44,1738,1739,1741,1743,1745,1748,1750],{"class":46,"line":669},[44,1740,687],{"class":54},[44,1742,394],{"class":108},[44,1744,309],{"class":54},[44,1746,1747],{"class":91},"\"label = \"",[44,1749,697],{"class":50},[44,1751,1752],{"class":54}," label);\n",[44,1754,1755],{"class":46,"line":684},[44,1756,757],{"class":54},[44,1758,1759],{"class":46,"line":703},[44,1760,666],{"emptyLinePlaceholder":665},[44,1762,1763,1765,1767,1770],{"class":46,"line":720},[44,1764,672],{"class":50},[44,1766,675],{"class":50},[44,1768,1769],{"class":108}," increaseByTwenty",[44,1771,681],{"class":54},[44,1773,1774,1776,1778,1780,1783,1785],{"class":46,"line":737},[44,1775,1708],{"class":50},[44,1777,1711],{"class":54},[44,1779,58],{"class":50},[44,1781,1782],{"class":61}," 20",[44,1784,76],{"class":54},[44,1786,1787],{"class":79},"\u002F\u002F 另一个方法里的局部变量，与上面互不相干\n",[44,1789,1790,1792,1794,1796,1798,1800],{"class":46,"line":754},[44,1791,687],{"class":54},[44,1793,394],{"class":108},[44,1795,309],{"class":54},[44,1797,1731],{"class":91},[44,1799,697],{"class":50},[44,1801,1736],{"class":54},[44,1803,1804,1806,1808,1810,1812,1814],{"class":46,"line":760},[44,1805,687],{"class":54},[44,1807,394],{"class":108},[44,1809,309],{"class":54},[44,1811,1747],{"class":91},[44,1813,697],{"class":50},[44,1815,1752],{"class":54},[44,1817,1818],{"class":46,"line":1172},[44,1819,757],{"class":54},[44,1821,1822],{"class":46,"line":1183},[44,1823,763],{"class":54},[22,1825,1827],{"id":1826},"_18-作用域里的就近原则proximity","1.8 作用域里的就近原则（Proximity）",[521,1829,1830,1833,1844],{},[524,1831,1832],{},"在 Block of Code (代码块) 内，Variable Names 必须唯一。",[524,1834,1835,1836,1839,1840,1843],{},"Block 位于 ",[30,1837,1838],{},"{"," 和 ",[30,1841,1842],{},"}"," 之间，总是看到 Nearest (最近的) Variable。",[524,1845,1846],{},"Local Variable 会 Overshadow (遮蔽) 同名的 Instance Variable。",[35,1848,1850],{"className":37,"code":1849,"language":39,"meta":40,"style":40},"public class Shadow {\n    private String label = \"实例属性\";\n\n    public void shadowed() {\n        String label = \"局部变量\"; \u002F\u002F local variable：遮蔽了同名的实例属性\n        System.out.println(\"label = \" + label);\n    }\n\n    public void notShadowed() {\n        System.out.println(\"label = \" + label);\n    }\n}\n",[30,1851,1852,1863,1876,1880,1891,1906,1920,1924,1928,1939,1953,1957],{"__ignoreMap":40},[44,1853,1854,1856,1858,1861],{"class":46,"line":47},[44,1855,598],{"class":50},[44,1857,601],{"class":50},[44,1859,1860],{"class":108}," Shadow",[44,1862,606],{"class":54},[44,1864,1865,1867,1869,1871,1874],{"class":46,"line":68},[44,1866,1048],{"class":50},[44,1868,1681],{"class":54},[44,1870,58],{"class":50},[44,1872,1873],{"class":91}," \"实例属性\"",[44,1875,165],{"class":54},[44,1877,1878],{"class":46,"line":83},[44,1879,666],{"emptyLinePlaceholder":665},[44,1881,1882,1884,1886,1889],{"class":46,"line":97},[44,1883,672],{"class":50},[44,1885,675],{"class":50},[44,1887,1888],{"class":108}," shadowed",[44,1890,681],{"class":54},[44,1892,1893,1896,1898,1901,1903],{"class":46,"line":474},[44,1894,1895],{"class":54},"        String label ",[44,1897,58],{"class":50},[44,1899,1900],{"class":91}," \"局部变量\"",[44,1902,76],{"class":54},[44,1904,1905],{"class":79},"\u002F\u002F local variable：遮蔽了同名的实例属性\n",[44,1907,1908,1910,1912,1914,1916,1918],{"class":46,"line":492},[44,1909,687],{"class":54},[44,1911,394],{"class":108},[44,1913,309],{"class":54},[44,1915,1747],{"class":91},[44,1917,697],{"class":50},[44,1919,1752],{"class":54},[44,1921,1922],{"class":46,"line":669},[44,1923,757],{"class":54},[44,1925,1926],{"class":46,"line":684},[44,1927,666],{"emptyLinePlaceholder":665},[44,1929,1930,1932,1934,1937],{"class":46,"line":703},[44,1931,672],{"class":50},[44,1933,675],{"class":50},[44,1935,1936],{"class":108}," notShadowed",[44,1938,681],{"class":54},[44,1940,1941,1943,1945,1947,1949,1951],{"class":46,"line":720},[44,1942,687],{"class":54},[44,1944,394],{"class":108},[44,1946,309],{"class":54},[44,1948,1747],{"class":91},[44,1950,697],{"class":50},[44,1952,1752],{"class":54},[44,1954,1955],{"class":46,"line":737},[44,1956,757],{"class":54},[44,1958,1959],{"class":46,"line":754},[44,1960,763],{"class":54},[13,1962,947],{},[35,1964,1967],{"className":1965,"code":1966,"language":953,"meta":40},[951],"label = 局部变量\nlabel = 实例属性\n",[30,1968,1966],{"__ignoreMap":40},[22,1970,1972],{"id":1971},"_19-this-关键字","1.9 this 关键字",[521,1974,1975,1981],{},[524,1976,1977,1980],{},[30,1978,1979],{},"this"," Keyword (this 关键字) 引用 Current Object (当前对象)，用于访问该 Object 中的 Instance Variables。",[524,1982,1983],{},"可用于访问被 Local Variable 遮蔽的 Instance Variable。",[35,1985,1987],{"className":37,"code":1986,"language":39,"meta":40,"style":40},"public class ThisDemo {\n    private String label = \"实例属性\";\n\n    public void withThis() {\n        String label = \"局部变量\";\n        System.out.println(\"label = \" + this.label); \u002F\u002F this.label 明确指向实例属性\n    }\n\n    public void withoutThis() {\n        System.out.println(\"label = \" + label);\n    }\n}\n",[30,1988,1989,2000,2012,2016,2027,2037,2058,2062,2066,2077,2091,2095],{"__ignoreMap":40},[44,1990,1991,1993,1995,1998],{"class":46,"line":47},[44,1992,598],{"class":50},[44,1994,601],{"class":50},[44,1996,1997],{"class":108}," ThisDemo",[44,1999,606],{"class":54},[44,2001,2002,2004,2006,2008,2010],{"class":46,"line":68},[44,2003,1048],{"class":50},[44,2005,1681],{"class":54},[44,2007,58],{"class":50},[44,2009,1873],{"class":91},[44,2011,165],{"class":54},[44,2013,2014],{"class":46,"line":83},[44,2015,666],{"emptyLinePlaceholder":665},[44,2017,2018,2020,2022,2025],{"class":46,"line":97},[44,2019,672],{"class":50},[44,2021,675],{"class":50},[44,2023,2024],{"class":108}," withThis",[44,2026,681],{"class":54},[44,2028,2029,2031,2033,2035],{"class":46,"line":474},[44,2030,1895],{"class":54},[44,2032,58],{"class":50},[44,2034,1900],{"class":91},[44,2036,165],{"class":54},[44,2038,2039,2041,2043,2045,2047,2049,2052,2055],{"class":46,"line":492},[44,2040,687],{"class":54},[44,2042,394],{"class":108},[44,2044,309],{"class":54},[44,2046,1747],{"class":91},[44,2048,697],{"class":50},[44,2050,2051],{"class":61}," this",[44,2053,2054],{"class":54},".label); ",[44,2056,2057],{"class":79},"\u002F\u002F this.label 明确指向实例属性\n",[44,2059,2060],{"class":46,"line":669},[44,2061,757],{"class":54},[44,2063,2064],{"class":46,"line":684},[44,2065,666],{"emptyLinePlaceholder":665},[44,2067,2068,2070,2072,2075],{"class":46,"line":703},[44,2069,672],{"class":50},[44,2071,675],{"class":50},[44,2073,2074],{"class":108}," withoutThis",[44,2076,681],{"class":54},[44,2078,2079,2081,2083,2085,2087,2089],{"class":46,"line":720},[44,2080,687],{"class":54},[44,2082,394],{"class":108},[44,2084,309],{"class":54},[44,2086,1747],{"class":91},[44,2088,697],{"class":50},[44,2090,1752],{"class":54},[44,2092,2093],{"class":46,"line":737},[44,2094,757],{"class":54},[44,2096,2097],{"class":46,"line":754},[44,2098,763],{"class":54},[13,2100,947],{},[35,2102,2105],{"className":2103,"code":2104,"language":953,"meta":40},[951],"label = 实例属性\nlabel = 实例属性\n",[30,2106,2104],{"__ignoreMap":40},[22,2108,2110],{"id":2109},"_110-动手示例给一盏台灯建模","1.10 动手示例：给一盏台灯建模",[521,2112,2113],{},[524,2114,2115,2116],{},"需求：一盏台灯，有颜色，有开和关两种状态。\n",[521,2117,2118,2129,2144],{},[524,2119,2120,2121,2124,2125,2128],{},"Attributes：",[30,2122,2123],{},"color"," (String)，",[30,2126,2127],{},"isOn"," (boolean)。",[524,2130,2131,2132,126,2135,126,2138,126,2141,33],{},"Methods：",[30,2133,2134],{},"turnOn()",[30,2136,2137],{},"turnOff()",[30,2139,2140],{},"getColor()",[30,2142,2143],{},"isOn()",[524,2145,2146,2147,2150],{},"Constructor 接受一个颜色字符串（如 ",[30,2148,2149],{},"\"white\"","）。",[35,2152,2154],{"className":37,"code":2153,"language":39,"meta":40,"style":40},"public class DeskLamp {\n    private boolean isOn;\n    public String color;\n\n    public DeskLamp(String color) {\n        isOn = false;\n        this.color = color;\n    }\n\n    public String getColor() {\n        return color;\n    }\n\n    public boolean isOn() {\n        return isOn;\n    }\n\n    public void turnOn() {\n        if (!isOn())\n            isOn = true;\n    }\n\n    public void turnOff() {\n        if (isOn())\n            isOn = false;\n    }\n}\n",[30,2155,2156,2167,2177,2184,2188,2200,2212,2224,2228,2232,2244,2251,2255,2259,2270,2276,2280,2284,2295,2311,2323,2327,2332,2344,2355,2366,2371],{"__ignoreMap":40},[44,2157,2158,2160,2162,2165],{"class":46,"line":47},[44,2159,598],{"class":50},[44,2161,601],{"class":50},[44,2163,2164],{"class":108}," DeskLamp",[44,2166,606],{"class":54},[44,2168,2169,2171,2174],{"class":46,"line":68},[44,2170,1048],{"class":50},[44,2172,2173],{"class":50}," boolean",[44,2175,2176],{"class":54}," isOn;\n",[44,2178,2179,2181],{"class":46,"line":83},[44,2180,672],{"class":50},[44,2182,2183],{"class":54}," String color;\n",[44,2185,2186],{"class":46,"line":97},[44,2187,666],{"emptyLinePlaceholder":665},[44,2189,2190,2192,2194,2196,2198],{"class":46,"line":474},[44,2191,672],{"class":50},[44,2193,2164],{"class":108},[44,2195,1091],{"class":54},[44,2197,2123],{"class":845},[44,2199,848],{"class":54},[44,2201,2202,2205,2207,2210],{"class":46,"line":492},[44,2203,2204],{"class":54},"        isOn ",[44,2206,58],{"class":50},[44,2208,2209],{"class":61}," false",[44,2211,165],{"class":54},[44,2213,2214,2216,2219,2221],{"class":46,"line":669},[44,2215,1119],{"class":61},[44,2217,2218],{"class":54},".color ",[44,2220,58],{"class":50},[44,2222,2223],{"class":54}," color;\n",[44,2225,2226],{"class":46,"line":684},[44,2227,757],{"class":54},[44,2229,2230],{"class":46,"line":703},[44,2231,666],{"emptyLinePlaceholder":665},[44,2233,2234,2236,2239,2242],{"class":46,"line":720},[44,2235,672],{"class":50},[44,2237,2238],{"class":54}," String ",[44,2240,2241],{"class":108},"getColor",[44,2243,681],{"class":54},[44,2245,2246,2249],{"class":46,"line":737},[44,2247,2248],{"class":50},"        return",[44,2250,2223],{"class":54},[44,2252,2253],{"class":46,"line":754},[44,2254,757],{"class":54},[44,2256,2257],{"class":46,"line":760},[44,2258,666],{"emptyLinePlaceholder":665},[44,2260,2261,2263,2265,2268],{"class":46,"line":1172},[44,2262,672],{"class":50},[44,2264,2173],{"class":50},[44,2266,2267],{"class":108}," isOn",[44,2269,681],{"class":54},[44,2271,2272,2274],{"class":46,"line":1183},[44,2273,2248],{"class":50},[44,2275,2176],{"class":54},[44,2277,2278],{"class":46,"line":1198},[44,2279,757],{"class":54},[44,2281,2282],{"class":46,"line":1213},[44,2283,666],{"emptyLinePlaceholder":665},[44,2285,2286,2288,2290,2293],{"class":46,"line":1228},[44,2287,672],{"class":50},[44,2289,675],{"class":50},[44,2291,2292],{"class":108}," turnOn",[44,2294,681],{"class":54},[44,2296,2297,2300,2303,2306,2308],{"class":46,"line":1243},[44,2298,2299],{"class":50},"        if",[44,2301,2302],{"class":54}," (",[44,2304,2305],{"class":50},"!",[44,2307,2127],{"class":108},[44,2309,2310],{"class":54},"())\n",[44,2312,2313,2316,2318,2321],{"class":46,"line":1248},[44,2314,2315],{"class":54},"            isOn ",[44,2317,58],{"class":50},[44,2319,2320],{"class":61}," true",[44,2322,165],{"class":54},[44,2324,2325],{"class":46,"line":1641},[44,2326,757],{"class":54},[44,2328,2330],{"class":46,"line":2329},22,[44,2331,666],{"emptyLinePlaceholder":665},[44,2333,2335,2337,2339,2342],{"class":46,"line":2334},23,[44,2336,672],{"class":50},[44,2338,675],{"class":50},[44,2340,2341],{"class":108}," turnOff",[44,2343,681],{"class":54},[44,2345,2347,2349,2351,2353],{"class":46,"line":2346},24,[44,2348,2299],{"class":50},[44,2350,2302],{"class":54},[44,2352,2127],{"class":108},[44,2354,2310],{"class":54},[44,2356,2358,2360,2362,2364],{"class":46,"line":2357},25,[44,2359,2315],{"class":54},[44,2361,58],{"class":50},[44,2363,2209],{"class":61},[44,2365,165],{"class":54},[44,2367,2369],{"class":46,"line":2368},26,[44,2370,757],{"class":54},[44,2372,2374],{"class":46,"line":2373},27,[44,2375,763],{"class":54},[13,2377,1253],{},[35,2379,2381],{"className":37,"code":2380,"language":39,"meta":40,"style":40},"public class Program_DeskLamp {\n    public static void main(String[] args) {\n        DeskLamp readingLamp = new DeskLamp(\"white\");\n\n        System.out.println(\"台灯颜色：\" + readingLamp.getColor());\n\n        readingLamp.turnOn();\n        System.out.println(\"台灯状态：\" + (readingLamp.isOn() ? \"开\" : \"关\"));\n\n        readingLamp.turnOff();\n        System.out.println(\"台灯状态：\" + (readingLamp.isOn() ? \"开\" : \"关\"));\n    }\n}\n",[30,2382,2383,2394,2414,2431,2435,2455,2459,2469,2505,2509,2518,2546,2550],{"__ignoreMap":40},[44,2384,2385,2387,2389,2392],{"class":46,"line":47},[44,2386,598],{"class":50},[44,2388,601],{"class":50},[44,2390,2391],{"class":108}," Program_DeskLamp",[44,2393,606],{"class":54},[44,2395,2396,2398,2400,2402,2404,2406,2408,2410,2412],{"class":46,"line":68},[44,2397,672],{"class":50},[44,2399,830],{"class":50},[44,2401,675],{"class":50},[44,2403,835],{"class":108},[44,2405,309],{"class":54},[44,2407,189],{"class":50},[44,2409,842],{"class":54},[44,2411,806],{"class":845},[44,2413,848],{"class":54},[44,2415,2416,2419,2421,2423,2425,2427,2429],{"class":46,"line":83},[44,2417,2418],{"class":54},"        DeskLamp readingLamp ",[44,2420,58],{"class":50},[44,2422,303],{"class":50},[44,2424,2164],{"class":108},[44,2426,309],{"class":54},[44,2428,2149],{"class":91},[44,2430,320],{"class":54},[44,2432,2433],{"class":46,"line":97},[44,2434,666],{"emptyLinePlaceholder":665},[44,2436,2437,2439,2441,2443,2446,2448,2451,2453],{"class":46,"line":474},[44,2438,687],{"class":54},[44,2440,394],{"class":108},[44,2442,309],{"class":54},[44,2444,2445],{"class":91},"\"台灯颜色：\"",[44,2447,697],{"class":50},[44,2449,2450],{"class":54}," readingLamp.",[44,2452,2241],{"class":108},[44,2454,403],{"class":54},[44,2456,2457],{"class":46,"line":492},[44,2458,666],{"emptyLinePlaceholder":665},[44,2460,2461,2464,2467],{"class":46,"line":669},[44,2462,2463],{"class":54},"        readingLamp.",[44,2465,2466],{"class":108},"turnOn",[44,2468,386],{"class":54},[44,2470,2471,2473,2475,2477,2480,2482,2485,2487,2490,2493,2496,2499,2502],{"class":46,"line":684},[44,2472,687],{"class":54},[44,2474,394],{"class":108},[44,2476,309],{"class":54},[44,2478,2479],{"class":91},"\"台灯状态：\"",[44,2481,697],{"class":50},[44,2483,2484],{"class":54}," (readingLamp.",[44,2486,2127],{"class":108},[44,2488,2489],{"class":54},"() ",[44,2491,2492],{"class":50},"?",[44,2494,2495],{"class":91}," \"开\"",[44,2497,2498],{"class":50}," :",[44,2500,2501],{"class":91}," \"关\"",[44,2503,2504],{"class":54},"));\n",[44,2506,2507],{"class":46,"line":703},[44,2508,666],{"emptyLinePlaceholder":665},[44,2510,2511,2513,2516],{"class":46,"line":720},[44,2512,2463],{"class":54},[44,2514,2515],{"class":108},"turnOff",[44,2517,386],{"class":54},[44,2519,2520,2522,2524,2526,2528,2530,2532,2534,2536,2538,2540,2542,2544],{"class":46,"line":737},[44,2521,687],{"class":54},[44,2523,394],{"class":108},[44,2525,309],{"class":54},[44,2527,2479],{"class":91},[44,2529,697],{"class":50},[44,2531,2484],{"class":54},[44,2533,2127],{"class":108},[44,2535,2489],{"class":54},[44,2537,2492],{"class":50},[44,2539,2495],{"class":91},[44,2541,2498],{"class":50},[44,2543,2501],{"class":91},[44,2545,2504],{"class":54},[44,2547,2548],{"class":46,"line":754},[44,2549,757],{"class":54},[44,2551,2552],{"class":46,"line":760},[44,2553,763],{"class":54},[13,2555,947],{},[35,2557,2560],{"className":2558,"code":2559,"language":953,"meta":40},[951],"台灯颜色：white\n台灯状态：开\n台灯状态：关\n",[30,2561,2559],{"__ignoreMap":40},[510,2563],{},[17,2565,2567],{"id":2566},"_2-访问修饰符与包","2 访问修饰符与包",[22,2569,2571],{"id":2570},"_20-访问修饰符access-modifiers","2.0 访问修饰符（Access Modifiers）",[521,2573,2574,2577,2580],{},[524,2575,2576],{},"控制外部对 Class（类）的 Attributes（属性）和 Methods（方法）的访问。",[524,2578,2579],{},"在 Class 内部无效果。",[524,2581,2582,2583,126,2585,126,2588,33],{},"三种：",[30,2584,598],{},[30,2586,2587],{},"private",[30,2589,2590],{},"protected",[116,2592,2594],{"id":2593},"_200-公有访问修饰符public","2.0.0 公有访问修饰符（public）",[521,2596,2597,2600,2603],{},[524,2598,2599],{},"访问级别为 everywhere（任何地方）。",[524,2601,2602],{},"可修饰 classes, methods, fields。",[524,2604,2605],{},"在类内、类外、包内、包外均可访问。",[35,2607,2609],{"className":37,"code":2608,"language":39,"meta":40,"style":40},"public class MyClass {\n    public int number; \u002F\u002F 外部可读写\n    public void display() { \u002F\u002F 外部可调用\n        System.out.println(number);\n    }\n}\n",[30,2610,2611,2622,2634,2649,2658,2662],{"__ignoreMap":40},[44,2612,2613,2615,2617,2620],{"class":46,"line":47},[44,2614,598],{"class":50},[44,2616,601],{"class":50},[44,2618,2619],{"class":108}," MyClass",[44,2621,606],{"class":54},[44,2623,2624,2626,2628,2631],{"class":46,"line":68},[44,2625,672],{"class":50},[44,2627,1065],{"class":50},[44,2629,2630],{"class":54}," number; ",[44,2632,2633],{"class":79},"\u002F\u002F 外部可读写\n",[44,2635,2636,2638,2640,2643,2646],{"class":46,"line":83},[44,2637,672],{"class":50},[44,2639,675],{"class":50},[44,2641,2642],{"class":108}," display",[44,2644,2645],{"class":54},"() { ",[44,2647,2648],{"class":79},"\u002F\u002F 外部可调用\n",[44,2650,2651,2653,2655],{"class":46,"line":97},[44,2652,687],{"class":54},[44,2654,394],{"class":108},[44,2656,2657],{"class":54},"(number);\n",[44,2659,2660],{"class":46,"line":474},[44,2661,757],{"class":54},[44,2663,2664],{"class":46,"line":492},[44,2665,763],{"class":54},[116,2667,2669],{"id":2668},"_201-私有访问修饰符private","2.0.1 私有访问修饰符（private）",[521,2671,2672,2675,2680,2685,2688],{},[524,2673,2674],{},"访问级别仅 within the class（类内）。",[524,2676,2677,2679],{},[30,2678,2587],{}," attribute：只能被类内代码读写。",[524,2681,2682,2684],{},[30,2683,2587],{}," method：只能被类内代码调用。",[524,2686,2687],{},"仅供类自身使用，外部（包括 Main 程序）不可访问。",[524,2689,2690,2691,2694,2695,2698],{},"代码里的 ",[30,2692,2693],{},"reset()"," 声明为 private，外部只能通过 ",[30,2696,2697],{},"doReset()"," 间接调用它。",[35,2700,2702],{"className":37,"code":2701,"language":39,"meta":40,"style":40},"public class MyClass {\n    private int number; \u002F\u002F 仅类内可读写\n    private void reset() { \u002F\u002F 仅类内可调用\n        number = 0;\n    }\n    public void doReset() {\n        reset(); \u002F\u002F 类内可调用\n    }\n}\n",[30,2703,2704,2714,2725,2739,2751,2755,2766,2776,2780],{"__ignoreMap":40},[44,2705,2706,2708,2710,2712],{"class":46,"line":47},[44,2707,598],{"class":50},[44,2709,601],{"class":50},[44,2711,2619],{"class":108},[44,2713,606],{"class":54},[44,2715,2716,2718,2720,2722],{"class":46,"line":68},[44,2717,1048],{"class":50},[44,2719,1065],{"class":50},[44,2721,2630],{"class":54},[44,2723,2724],{"class":79},"\u002F\u002F 仅类内可读写\n",[44,2726,2727,2729,2731,2734,2736],{"class":46,"line":83},[44,2728,1048],{"class":50},[44,2730,675],{"class":50},[44,2732,2733],{"class":108}," reset",[44,2735,2645],{"class":54},[44,2737,2738],{"class":79},"\u002F\u002F 仅类内可调用\n",[44,2740,2741,2744,2746,2749],{"class":46,"line":97},[44,2742,2743],{"class":54},"        number ",[44,2745,58],{"class":50},[44,2747,2748],{"class":61}," 0",[44,2750,165],{"class":54},[44,2752,2753],{"class":46,"line":474},[44,2754,757],{"class":54},[44,2756,2757,2759,2761,2764],{"class":46,"line":492},[44,2758,672],{"class":50},[44,2760,675],{"class":50},[44,2762,2763],{"class":108}," doReset",[44,2765,681],{"class":54},[44,2767,2768,2771,2773],{"class":46,"line":669},[44,2769,2770],{"class":108},"        reset",[44,2772,112],{"class":54},[44,2774,2775],{"class":79},"\u002F\u002F 类内可调用\n",[44,2777,2778],{"class":46,"line":684},[44,2779,757],{"class":54},[44,2781,2782],{"class":46,"line":703},[44,2783,763],{"class":54},[116,2785,2787],{"id":2786},"_202-受保护访问修饰符protected","2.0.2 受保护访问修饰符（protected）",[521,2789,2790,2793,2801,2806],{},[524,2791,2792],{},"仅在 Java Packages（包）和 Inheritance（继承）上下文中有效。",[524,2794,2795,2796,1839,2798,2800],{},"子类可继承父类的 ",[30,2797,598],{},[30,2799,2590],{}," 属性和方法。",[524,2802,2803,2805],{},[30,2804,2587],{}," 属性和方法对子类也不可访问。",[524,2807,2808,2809,2811],{},"示例：子类访问父类的 ",[30,2810,2590],{}," 方法。",[35,2813,2815],{"className":37,"code":2814,"language":39,"meta":40,"style":40},"public class Parent {\n    protected int value;\n    protected void show() {\n        System.out.println(value);\n    }\n}\npublic class Child extends Parent {\n    public void display() {\n        show(); \u002F\u002F 子类可访问 protected 方法\n    }\n}\n",[30,2816,2817,2828,2838,2849,2858,2862,2866,2882,2892,2902,2906],{"__ignoreMap":40},[44,2818,2819,2821,2823,2826],{"class":46,"line":47},[44,2820,598],{"class":50},[44,2822,601],{"class":50},[44,2824,2825],{"class":108}," Parent",[44,2827,606],{"class":54},[44,2829,2830,2833,2835],{"class":46,"line":68},[44,2831,2832],{"class":50},"    protected",[44,2834,1065],{"class":50},[44,2836,2837],{"class":54}," value;\n",[44,2839,2840,2842,2844,2847],{"class":46,"line":83},[44,2841,2832],{"class":50},[44,2843,675],{"class":50},[44,2845,2846],{"class":108}," show",[44,2848,681],{"class":54},[44,2850,2851,2853,2855],{"class":46,"line":97},[44,2852,687],{"class":54},[44,2854,394],{"class":108},[44,2856,2857],{"class":54},"(value);\n",[44,2859,2860],{"class":46,"line":474},[44,2861,757],{"class":54},[44,2863,2864],{"class":46,"line":492},[44,2865,763],{"class":54},[44,2867,2868,2870,2872,2875,2878,2880],{"class":46,"line":669},[44,2869,598],{"class":50},[44,2871,601],{"class":50},[44,2873,2874],{"class":108}," Child",[44,2876,2877],{"class":50}," extends",[44,2879,2825],{"class":108},[44,2881,606],{"class":54},[44,2883,2884,2886,2888,2890],{"class":46,"line":684},[44,2885,672],{"class":50},[44,2887,675],{"class":50},[44,2889,2642],{"class":108},[44,2891,681],{"class":54},[44,2893,2894,2897,2899],{"class":46,"line":703},[44,2895,2896],{"class":108},"        show",[44,2898,112],{"class":54},[44,2900,2901],{"class":79},"\u002F\u002F 子类可访问 protected 方法\n",[44,2903,2904],{"class":46,"line":720},[44,2905,757],{"class":54},[44,2907,2908],{"class":46,"line":737},[44,2909,763],{"class":54},[22,2911,2913],{"id":2912},"_21-包packages","2.1 包（Packages）",[521,2915,2916,2919,2922,2925],{},[524,2917,2918],{},"Java package 是 namespace（命名空间），组织一组相关的 classes 和 interfaces。",[524,2920,2921],{},"防止命名冲突，允许控制访问。",[524,2923,2924],{},"实现为 directory structures（目录结构），每个包有唯一名称。",[524,2926,2927,2928,2931,2932,2935,2936,2938,2939,2941],{},"示例：把表格格式化代码放进 ",[30,2929,2930],{},"format"," 包，主程序放在 ",[30,2933,2934],{},"app"," 包，",[30,2937,2934],{}," 里的类用 import 引入 ",[30,2940,2930],{}," 包。",[35,2943,2946],{"className":2944,"code":2945,"language":953,"meta":40},[951],".\n├── format\n│   └── TableFormatter.java\n└── app\n    └── Program.java\n",[30,2947,2945],{"__ignoreMap":40},[22,2949,2951],{"id":2950},"_22-继承inheritance简介","2.2 继承（Inheritance）简介",[521,2953,2954,2961,2968,2975,2981],{},[524,2955,2956,2957,1839,2959,2800],{},"OOP 中，child class（子类）可 extend（扩展）parent class（父类），继承 ",[30,2958,598],{},[30,2960,2590],{},[524,2962,2963,2964,2967],{},"Java 关键字 ",[30,2965,2966],{},"super"," 指代子类的父类。",[524,2969,2970,2971,2974],{},"子类调用 ",[30,2972,2973],{},"super()"," 调用父类的 constructor（构造器）。",[524,2976,2977,2978,2980],{},"子类可访问父类的 ",[30,2979,2590],{}," 属性。",[524,2982,2983,2984,2986,2987,2980],{},"示例：子类调用 ",[30,2985,2973],{}," 并访问父类 ",[30,2988,2590],{},[35,2990,2992],{"className":37,"code":2991,"language":39,"meta":40,"style":40},"public class Parent {\n    protected String name;\n    public Parent(String name) {\n        this.name = name;\n    }\n}\npublic class Child extends Parent {\n    public Child(String name) {\n        super(name); \u002F\u002F 调用父类构造器\n    }\n    public void printName() {\n        System.out.println(name); \u002F\u002F 访问 protected 属性\n    }\n}\n",[30,2993,2994,3004,3011,3024,3036,3040,3044,3058,3070,3081,3085,3096,3107,3111],{"__ignoreMap":40},[44,2995,2996,2998,3000,3002],{"class":46,"line":47},[44,2997,598],{"class":50},[44,2999,601],{"class":50},[44,3001,2825],{"class":108},[44,3003,606],{"class":54},[44,3005,3006,3008],{"class":46,"line":68},[44,3007,2832],{"class":50},[44,3009,3010],{"class":54}," String name;\n",[44,3012,3013,3015,3017,3019,3022],{"class":46,"line":83},[44,3014,672],{"class":50},[44,3016,2825],{"class":108},[44,3018,1091],{"class":54},[44,3020,3021],{"class":845},"name",[44,3023,848],{"class":54},[44,3025,3026,3028,3031,3033],{"class":46,"line":97},[44,3027,1119],{"class":61},[44,3029,3030],{"class":54},".name ",[44,3032,58],{"class":50},[44,3034,3035],{"class":54}," name;\n",[44,3037,3038],{"class":46,"line":474},[44,3039,757],{"class":54},[44,3041,3042],{"class":46,"line":492},[44,3043,763],{"class":54},[44,3045,3046,3048,3050,3052,3054,3056],{"class":46,"line":669},[44,3047,598],{"class":50},[44,3049,601],{"class":50},[44,3051,2874],{"class":108},[44,3053,2877],{"class":50},[44,3055,2825],{"class":108},[44,3057,606],{"class":54},[44,3059,3060,3062,3064,3066,3068],{"class":46,"line":684},[44,3061,672],{"class":50},[44,3063,2874],{"class":108},[44,3065,1091],{"class":54},[44,3067,3021],{"class":845},[44,3069,848],{"class":54},[44,3071,3072,3075,3078],{"class":46,"line":703},[44,3073,3074],{"class":61},"        super",[44,3076,3077],{"class":54},"(name); ",[44,3079,3080],{"class":79},"\u002F\u002F 调用父类构造器\n",[44,3082,3083],{"class":46,"line":720},[44,3084,757],{"class":54},[44,3086,3087,3089,3091,3094],{"class":46,"line":737},[44,3088,672],{"class":50},[44,3090,675],{"class":50},[44,3092,3093],{"class":108}," printName",[44,3095,681],{"class":54},[44,3097,3098,3100,3102,3104],{"class":46,"line":754},[44,3099,687],{"class":54},[44,3101,394],{"class":108},[44,3103,3077],{"class":54},[44,3105,3106],{"class":79},"\u002F\u002F 访问 protected 属性\n",[44,3108,3109],{"class":46,"line":760},[44,3110,757],{"class":54},[44,3112,3113],{"class":46,"line":1172},[44,3114,763],{"class":54},[510,3116],{},[17,3118,3120],{"id":3119},"_3-继承inheritance","3 继承（Inheritance）",[22,3122,3124],{"id":3123},"_30-重复代码问题","3.0 重复代码问题",[521,3126,3127,3181,3184],{},[524,3128,3129,3130],{},"需求：算两种人的月收入。\n",[521,3131,3132,3157],{},[524,3133,3134,3137,3138,126,3140,126,3143,126,3146,3149,3150,3153,3154,33],{},[30,3135,3136],{},"FullTimer","：属性 ",[30,3139,3021],{},[30,3141,3142],{},"staffId",[30,3144,3145],{},"baseSalary",[30,3147,3148],{},"bonus","；方法 ",[30,3151,3152],{},"monthlyPay()"," 返回 ",[30,3155,3156],{},"baseSalary + bonus",[524,3158,3159,3137,3162,126,3164,126,3166,126,3168,126,3170,126,3173,3149,3176,3153,3178,33],{},[30,3160,3161],{},"Contractor",[30,3163,3021],{},[30,3165,3142],{},[30,3167,3145],{},[30,3169,3148],{},[30,3171,3172],{},"hours",[30,3174,3175],{},"hourlyRate",[30,3177,3152],{},[30,3179,3180],{},"baseSalary + bonus + hours * hourlyRate",[524,3182,3183],{},"两个类的字段和公式大面积重复。Duplicate code（重复代码）导致维护复杂，是 Bad（不好的）。",[524,3185,3186],{},"需要一种方式避免重复：Inheritance（继承）。",[35,3188,3190],{"className":37,"code":3189,"language":39,"meta":40,"style":40},"public class FullTimer {\n    private String name;\n    private String staffId;\n    private double baseSalary;\n    private double bonus;\n\n    public FullTimer(String name, String staffId,\n                     double baseSalary, double bonus) {\n        this.name = name;\n        this.staffId = staffId;\n        this.baseSalary = baseSalary;\n        this.bonus = bonus;\n    }\n\n    public double monthlyPay() {\n        return baseSalary + bonus;\n    }\n}\n\npublic class Contractor {\n    private String name;\n    private String staffId;\n    private double baseSalary;\n    private double bonus;\n    private int hours;\n    private double hourlyRate;\n\n    public Contractor(String name, String staffId,\n                      double baseSalary, double bonus,\n                      int hours, double hourlyRate) {\n        this.name = name;\n        this.staffId = staffId;\n        this.baseSalary = baseSalary;\n        this.bonus = bonus;\n        this.hours = hours;\n        this.hourlyRate = hourlyRate;\n    }\n\n    public double monthlyPay() {\n        return baseSalary + bonus + hours * hourlyRate;\n    }\n}\n",[30,3191,3192,3203,3209,3216,3225,3234,3238,3255,3272,3282,3294,3305,3316,3320,3324,3335,3347,3351,3355,3359,3370,3376,3382,3390,3398,3407,3416,3420,3437,3453,3471,3482,3493,3504,3515,3527,3539,3544,3549,3560,3582,3587],{"__ignoreMap":40},[44,3193,3194,3196,3198,3201],{"class":46,"line":47},[44,3195,598],{"class":50},[44,3197,601],{"class":50},[44,3199,3200],{"class":108}," FullTimer",[44,3202,606],{"class":54},[44,3204,3205,3207],{"class":46,"line":68},[44,3206,1048],{"class":50},[44,3208,3010],{"class":54},[44,3210,3211,3213],{"class":46,"line":83},[44,3212,1048],{"class":50},[44,3214,3215],{"class":54}," String staffId;\n",[44,3217,3218,3220,3222],{"class":46,"line":97},[44,3219,1048],{"class":50},[44,3221,1075],{"class":50},[44,3223,3224],{"class":54}," baseSalary;\n",[44,3226,3227,3229,3231],{"class":46,"line":474},[44,3228,1048],{"class":50},[44,3230,1075],{"class":50},[44,3232,3233],{"class":54}," bonus;\n",[44,3235,3236],{"class":46,"line":492},[44,3237,666],{"emptyLinePlaceholder":665},[44,3239,3240,3242,3244,3246,3248,3250,3252],{"class":46,"line":669},[44,3241,672],{"class":50},[44,3243,3200],{"class":108},[44,3245,1091],{"class":54},[44,3247,3021],{"class":845},[44,3249,1096],{"class":54},[44,3251,3142],{"class":845},[44,3253,3254],{"class":54},",\n",[44,3256,3257,3260,3263,3265,3267,3270],{"class":46,"line":684},[44,3258,3259],{"class":50},"                     double",[44,3261,3262],{"class":845}," baseSalary",[44,3264,126],{"class":54},[44,3266,140],{"class":50},[44,3268,3269],{"class":845}," bonus",[44,3271,848],{"class":54},[44,3273,3274,3276,3278,3280],{"class":46,"line":703},[44,3275,1119],{"class":61},[44,3277,3030],{"class":54},[44,3279,58],{"class":50},[44,3281,3035],{"class":54},[44,3283,3284,3286,3289,3291],{"class":46,"line":720},[44,3285,1119],{"class":61},[44,3287,3288],{"class":54},".staffId ",[44,3290,58],{"class":50},[44,3292,3293],{"class":54}," staffId;\n",[44,3295,3296,3298,3301,3303],{"class":46,"line":737},[44,3297,1119],{"class":61},[44,3299,3300],{"class":54},".baseSalary ",[44,3302,58],{"class":50},[44,3304,3224],{"class":54},[44,3306,3307,3309,3312,3314],{"class":46,"line":754},[44,3308,1119],{"class":61},[44,3310,3311],{"class":54},".bonus ",[44,3313,58],{"class":50},[44,3315,3233],{"class":54},[44,3317,3318],{"class":46,"line":760},[44,3319,757],{"class":54},[44,3321,3322],{"class":46,"line":1172},[44,3323,666],{"emptyLinePlaceholder":665},[44,3325,3326,3328,3330,3333],{"class":46,"line":1183},[44,3327,672],{"class":50},[44,3329,1075],{"class":50},[44,3331,3332],{"class":108}," monthlyPay",[44,3334,681],{"class":54},[44,3336,3337,3339,3342,3345],{"class":46,"line":1198},[44,3338,2248],{"class":50},[44,3340,3341],{"class":54}," baseSalary ",[44,3343,3344],{"class":50},"+",[44,3346,3233],{"class":54},[44,3348,3349],{"class":46,"line":1213},[44,3350,757],{"class":54},[44,3352,3353],{"class":46,"line":1228},[44,3354,763],{"class":54},[44,3356,3357],{"class":46,"line":1243},[44,3358,666],{"emptyLinePlaceholder":665},[44,3360,3361,3363,3365,3368],{"class":46,"line":1248},[44,3362,598],{"class":50},[44,3364,601],{"class":50},[44,3366,3367],{"class":108}," Contractor",[44,3369,606],{"class":54},[44,3371,3372,3374],{"class":46,"line":1641},[44,3373,1048],{"class":50},[44,3375,3010],{"class":54},[44,3377,3378,3380],{"class":46,"line":2329},[44,3379,1048],{"class":50},[44,3381,3215],{"class":54},[44,3383,3384,3386,3388],{"class":46,"line":2334},[44,3385,1048],{"class":50},[44,3387,1075],{"class":50},[44,3389,3224],{"class":54},[44,3391,3392,3394,3396],{"class":46,"line":2346},[44,3393,1048],{"class":50},[44,3395,1075],{"class":50},[44,3397,3233],{"class":54},[44,3399,3400,3402,3404],{"class":46,"line":2357},[44,3401,1048],{"class":50},[44,3403,1065],{"class":50},[44,3405,3406],{"class":54}," hours;\n",[44,3408,3409,3411,3413],{"class":46,"line":2368},[44,3410,1048],{"class":50},[44,3412,1075],{"class":50},[44,3414,3415],{"class":54}," hourlyRate;\n",[44,3417,3418],{"class":46,"line":2373},[44,3419,666],{"emptyLinePlaceholder":665},[44,3421,3423,3425,3427,3429,3431,3433,3435],{"class":46,"line":3422},28,[44,3424,672],{"class":50},[44,3426,3367],{"class":108},[44,3428,1091],{"class":54},[44,3430,3021],{"class":845},[44,3432,1096],{"class":54},[44,3434,3142],{"class":845},[44,3436,3254],{"class":54},[44,3438,3440,3443,3445,3447,3449,3451],{"class":46,"line":3439},29,[44,3441,3442],{"class":50},"                      double",[44,3444,3262],{"class":845},[44,3446,126],{"class":54},[44,3448,140],{"class":50},[44,3450,3269],{"class":845},[44,3452,3254],{"class":54},[44,3454,3456,3459,3462,3464,3466,3469],{"class":46,"line":3455},30,[44,3457,3458],{"class":50},"                      int",[44,3460,3461],{"class":845}," hours",[44,3463,126],{"class":54},[44,3465,140],{"class":50},[44,3467,3468],{"class":845}," hourlyRate",[44,3470,848],{"class":54},[44,3472,3474,3476,3478,3480],{"class":46,"line":3473},31,[44,3475,1119],{"class":61},[44,3477,3030],{"class":54},[44,3479,58],{"class":50},[44,3481,3035],{"class":54},[44,3483,3485,3487,3489,3491],{"class":46,"line":3484},32,[44,3486,1119],{"class":61},[44,3488,3288],{"class":54},[44,3490,58],{"class":50},[44,3492,3293],{"class":54},[44,3494,3496,3498,3500,3502],{"class":46,"line":3495},33,[44,3497,1119],{"class":61},[44,3499,3300],{"class":54},[44,3501,58],{"class":50},[44,3503,3224],{"class":54},[44,3505,3507,3509,3511,3513],{"class":46,"line":3506},34,[44,3508,1119],{"class":61},[44,3510,3311],{"class":54},[44,3512,58],{"class":50},[44,3514,3233],{"class":54},[44,3516,3518,3520,3523,3525],{"class":46,"line":3517},35,[44,3519,1119],{"class":61},[44,3521,3522],{"class":54},".hours ",[44,3524,58],{"class":50},[44,3526,3406],{"class":54},[44,3528,3530,3532,3535,3537],{"class":46,"line":3529},36,[44,3531,1119],{"class":61},[44,3533,3534],{"class":54},".hourlyRate ",[44,3536,58],{"class":50},[44,3538,3415],{"class":54},[44,3540,3542],{"class":46,"line":3541},37,[44,3543,757],{"class":54},[44,3545,3547],{"class":46,"line":3546},38,[44,3548,666],{"emptyLinePlaceholder":665},[44,3550,3552,3554,3556,3558],{"class":46,"line":3551},39,[44,3553,672],{"class":50},[44,3555,1075],{"class":50},[44,3557,3332],{"class":108},[44,3559,681],{"class":54},[44,3561,3563,3565,3567,3569,3572,3574,3577,3580],{"class":46,"line":3562},40,[44,3564,2248],{"class":50},[44,3566,3341],{"class":54},[44,3568,3344],{"class":50},[44,3570,3571],{"class":54}," bonus ",[44,3573,3344],{"class":50},[44,3575,3576],{"class":54}," hours ",[44,3578,3579],{"class":50},"*",[44,3581,3415],{"class":54},[44,3583,3585],{"class":46,"line":3584},41,[44,3586,757],{"class":54},[44,3588,3590],{"class":46,"line":3589},42,[44,3591,763],{"class":54},[22,3593,3595],{"id":3594},"_31-inheritance继承概念","3.1 Inheritance（继承）概念",[521,3597,3598,3601,3604],{},[524,3599,3600],{},"Inheritance（继承）：定义 general class（一般类，即 parent class \u002F base class \u002F superclass，父类\u002F基类\u002F超类），并 extend（扩展）为更 specific classes（具体类，即 child class \u002F derived class \u002F subclass，子类\u002F派生类）。",[524,3602,3603],{},"子类继承父类的 states（状态）和 behaviours（行为）。",[524,3605,3606,3607,3610],{},"用关键字 ",[30,3608,3609],{},"extends"," 实现子类。",[35,3612,3614],{"className":37,"code":3613,"language":39,"meta":40,"style":40},"class Parent {\n    \u002F\u002F Class body\n}\n\nclass Child extends Parent {\n    \u002F\u002F Class body\n}\n",[30,3615,3616,3625,3630,3634,3638,3650,3654],{"__ignoreMap":40},[44,3617,3618,3621,3623],{"class":46,"line":47},[44,3619,3620],{"class":50},"class",[44,3622,2825],{"class":108},[44,3624,606],{"class":54},[44,3626,3627],{"class":46,"line":68},[44,3628,3629],{"class":79},"    \u002F\u002F Class body\n",[44,3631,3632],{"class":46,"line":83},[44,3633,763],{"class":54},[44,3635,3636],{"class":46,"line":97},[44,3637,666],{"emptyLinePlaceholder":665},[44,3639,3640,3642,3644,3646,3648],{"class":46,"line":474},[44,3641,3620],{"class":50},[44,3643,2874],{"class":108},[44,3645,2877],{"class":50},[44,3647,2825],{"class":108},[44,3649,606],{"class":54},[44,3651,3652],{"class":46,"line":492},[44,3653,3629],{"class":79},[44,3655,3656],{"class":46,"line":669},[44,3657,763],{"class":54},[521,3659,3660],{},[524,3661,1004,3662,3665,3666,3669,3670,3673,3674,126,3677,126,3680,3683],{},[30,3663,3664],{},"Vehicle"," 为父类，有 ",[30,3667,3668],{},"maker"," 属性和 ",[30,3671,3672],{},"getMaker()"," 方法；",[30,3675,3676],{},"Bicycle",[30,3678,3679],{},"Truck",[30,3681,3682],{},"Ferry"," 为子类，各自增加自己的属性和方法。",[22,3685,3687],{"id":3686},"_32-重新设计","3.2 重新设计",[521,3689,3690,3705],{},[524,3691,3692,3693,3696,3697,126,3699,126,3701,126,3703,33],{},"把公共部分上提到 superclass（超类）",[30,3694,3695],{},"Staff"," 中：",[30,3698,3021],{},[30,3700,3142],{},[30,3702,3145],{},[30,3704,3148],{},[524,3706,3707,3708],{},"差异放在 subclasses（子类）中：\n",[521,3709,3710,3715],{},[524,3711,3712,3714],{},[30,3713,3136],{}," 复用父类的字段来算月收入。",[524,3716,3717,3719,3720,126,3722,3724,3725,33],{},[30,3718,3161],{}," 自己加 ",[30,3721,3172],{},[30,3723,3175],{},"，并重写 ",[30,3726,3152],{},[35,3728,3730],{"className":37,"code":3729,"language":39,"meta":40,"style":40},"public class Staff {\n    private String name;\n    private String staffId;\n    private double baseSalary;\n    private double bonus;\n    \u002F\u002F 构造器省略\n}\n\npublic class FullTimer extends Staff {\n    \u002F\u002F 构造器省略\n    public double monthlyPay() {\n        return baseSalary + bonus;\n    }\n}\n\npublic class Contractor extends Staff {\n    private int hours;\n    private double hourlyRate;\n    \u002F\u002F 构造器省略\n    public double monthlyPay() {\n        return baseSalary + bonus + hours * hourlyRate;\n    }\n}\n",[30,3731,3732,3743,3749,3755,3763,3771,3776,3780,3784,3798,3802,3812,3822,3826,3830,3834,3848,3856,3864,3868,3878,3896,3900],{"__ignoreMap":40},[44,3733,3734,3736,3738,3741],{"class":46,"line":47},[44,3735,598],{"class":50},[44,3737,601],{"class":50},[44,3739,3740],{"class":108}," Staff",[44,3742,606],{"class":54},[44,3744,3745,3747],{"class":46,"line":68},[44,3746,1048],{"class":50},[44,3748,3010],{"class":54},[44,3750,3751,3753],{"class":46,"line":83},[44,3752,1048],{"class":50},[44,3754,3215],{"class":54},[44,3756,3757,3759,3761],{"class":46,"line":97},[44,3758,1048],{"class":50},[44,3760,1075],{"class":50},[44,3762,3224],{"class":54},[44,3764,3765,3767,3769],{"class":46,"line":474},[44,3766,1048],{"class":50},[44,3768,1075],{"class":50},[44,3770,3233],{"class":54},[44,3772,3773],{"class":46,"line":492},[44,3774,3775],{"class":79},"    \u002F\u002F 构造器省略\n",[44,3777,3778],{"class":46,"line":669},[44,3779,763],{"class":54},[44,3781,3782],{"class":46,"line":684},[44,3783,666],{"emptyLinePlaceholder":665},[44,3785,3786,3788,3790,3792,3794,3796],{"class":46,"line":703},[44,3787,598],{"class":50},[44,3789,601],{"class":50},[44,3791,3200],{"class":108},[44,3793,2877],{"class":50},[44,3795,3740],{"class":108},[44,3797,606],{"class":54},[44,3799,3800],{"class":46,"line":720},[44,3801,3775],{"class":79},[44,3803,3804,3806,3808,3810],{"class":46,"line":737},[44,3805,672],{"class":50},[44,3807,1075],{"class":50},[44,3809,3332],{"class":108},[44,3811,681],{"class":54},[44,3813,3814,3816,3818,3820],{"class":46,"line":754},[44,3815,2248],{"class":50},[44,3817,3341],{"class":54},[44,3819,3344],{"class":50},[44,3821,3233],{"class":54},[44,3823,3824],{"class":46,"line":760},[44,3825,757],{"class":54},[44,3827,3828],{"class":46,"line":1172},[44,3829,763],{"class":54},[44,3831,3832],{"class":46,"line":1183},[44,3833,666],{"emptyLinePlaceholder":665},[44,3835,3836,3838,3840,3842,3844,3846],{"class":46,"line":1198},[44,3837,598],{"class":50},[44,3839,601],{"class":50},[44,3841,3367],{"class":108},[44,3843,2877],{"class":50},[44,3845,3740],{"class":108},[44,3847,606],{"class":54},[44,3849,3850,3852,3854],{"class":46,"line":1213},[44,3851,1048],{"class":50},[44,3853,1065],{"class":50},[44,3855,3406],{"class":54},[44,3857,3858,3860,3862],{"class":46,"line":1228},[44,3859,1048],{"class":50},[44,3861,1075],{"class":50},[44,3863,3415],{"class":54},[44,3865,3866],{"class":46,"line":1243},[44,3867,3775],{"class":79},[44,3869,3870,3872,3874,3876],{"class":46,"line":1248},[44,3871,672],{"class":50},[44,3873,1075],{"class":50},[44,3875,3332],{"class":108},[44,3877,681],{"class":54},[44,3879,3880,3882,3884,3886,3888,3890,3892,3894],{"class":46,"line":1641},[44,3881,2248],{"class":50},[44,3883,3341],{"class":54},[44,3885,3344],{"class":50},[44,3887,3571],{"class":54},[44,3889,3344],{"class":50},[44,3891,3576],{"class":54},[44,3893,3579],{"class":50},[44,3895,3415],{"class":54},[44,3897,3898],{"class":46,"line":2329},[44,3899,757],{"class":54},[44,3901,3902],{"class":46,"line":2334},[44,3903,763],{"class":54},[521,3905,3906],{},[524,3907,3908,3909,1839,3911,3913,3914,3916,3917,3919],{},"问题：",[30,3910,3145],{},[30,3912,3148],{}," 是 ",[30,3915,2587],{},"，子类访问不到。想让子类读到父类的属性，可以改成 ",[30,3918,2590],{},"，也可以在父类提供 getter\u002Fsetter。",[22,3921,3923],{"id":3922},"_33-inheritance继承的好处","3.3 Inheritance（继承）的好处",[521,3925,3926,3929,3932,3935],{},[524,3927,3928],{},"Software re-use（软件复用）：子类无需重复祖先已定义的公共描述。",[524,3930,3931],{},"Ease of maintenance（易维护）：修改父类一处，所有子类自动继承新定义。",[524,3933,3934],{},"但以上两个好处也可通过 Object Composition（对象组合，has-a 关系）实现，且在许多情况下组合优于继承。",[524,3936,3937],{},"Inheritance 最重要的好处是 Polymorphism（多态）。",[510,3939],{},[17,3941,3943],{"id":3942},"_4-重载集合与多态","4 重载、集合与多态",[22,3945,3947],{"id":3946},"_40-重载overloading","4.0 重载（Overloading）",[521,3949,3950,3953,3956,3959],{},[524,3951,3952],{},"Overloading（重载）允许在同一个类中定义多个 members（成员，包括 constructors 或 methods），它们共享相同名称但 parameters（参数）不同。",[524,3954,3955],{},"区分依据：参数的数量和类型。方法的 return type（返回类型）不能作为重载的区分依据。",[524,3957,3958],{},"Constructor Overloading（构造器重载）：一个类可以有多个构造器，参数不同。",[524,3960,3961],{},"Method Overloading（方法重载）：同名方法，参数不同（数量或类型），调用时根据提供的参数选择合适版本。",[35,3963,3965],{"className":37,"code":3964,"language":39,"meta":40,"style":40},"public class Constr_Overload {\n    public Constr_Overload() { }\n    public Constr_Overload(int value) { }\n}\n\npublic class Method_Overload {\n    public void display(int number) { }\n    public void display(String text) { }\n}\n",[30,3966,3967,3978,3987,4003,4007,4011,4022,4039,4053],{"__ignoreMap":40},[44,3968,3969,3971,3973,3976],{"class":46,"line":47},[44,3970,598],{"class":50},[44,3972,601],{"class":50},[44,3974,3975],{"class":108}," Constr_Overload",[44,3977,606],{"class":54},[44,3979,3980,3982,3984],{"class":46,"line":68},[44,3981,672],{"class":50},[44,3983,3975],{"class":108},[44,3985,3986],{"class":54},"() { }\n",[44,3988,3989,3991,3993,3995,3997,4000],{"class":46,"line":83},[44,3990,672],{"class":50},[44,3992,3975],{"class":108},[44,3994,309],{"class":54},[44,3996,51],{"class":50},[44,3998,3999],{"class":845}," value",[44,4001,4002],{"class":54},") { }\n",[44,4004,4005],{"class":46,"line":97},[44,4006,763],{"class":54},[44,4008,4009],{"class":46,"line":474},[44,4010,666],{"emptyLinePlaceholder":665},[44,4012,4013,4015,4017,4020],{"class":46,"line":492},[44,4014,598],{"class":50},[44,4016,601],{"class":50},[44,4018,4019],{"class":108}," Method_Overload",[44,4021,606],{"class":54},[44,4023,4024,4026,4028,4030,4032,4034,4037],{"class":46,"line":669},[44,4025,672],{"class":50},[44,4027,675],{"class":50},[44,4029,2642],{"class":108},[44,4031,309],{"class":54},[44,4033,51],{"class":50},[44,4035,4036],{"class":845}," number",[44,4038,4002],{"class":54},[44,4040,4041,4043,4045,4047,4049,4051],{"class":46,"line":684},[44,4042,672],{"class":50},[44,4044,675],{"class":50},[44,4046,2642],{"class":108},[44,4048,1091],{"class":54},[44,4050,953],{"class":845},[44,4052,4002],{"class":54},[44,4054,4055],{"class":46,"line":703},[44,4056,763],{"class":54},[22,4058,4060],{"id":4059},"_41-传参值传递与引用传递","4.1 传参：值传递与引用传递",[521,4062,4063,4066,4069,4072],{},[524,4064,4065],{},"Java 中，当变量作为参数传递给方法时，采用 Pass By Value（值传递）。方法接收的是变量值的副本，而非变量本身的引用。",[524,4067,4068],{},"对于 primitive types（基本类型），方法内对副本的修改不影响外部原变量。",[524,4070,4071],{},"对于 objects（对象），传递的是 object reference（对象引用）的副本。方法接收的引用副本与外部引用指向同一对象。因此，方法内修改对象的 state（状态），外部可见。但若方法内重新赋值引用副本指向新对象，外部引用不受影响。",[524,4073,4074],{},"对象传递称为 Pass By Reference（引用传递），强调方法内修改对象状态会影响原对象。",[35,4076,4078],{"className":37,"code":4077,"language":39,"meta":40,"style":40},"\u002F\u002F Pass By Value 示例\npublic void modify(int x) {\n    x = 100; \u002F\u002F 不影响外部\n}\n\n\u002F\u002F 对象引用传递示例\npublic void modify(Car car) {\n    car.setColor(\"blue\"); \u002F\u002F 影响外部对象\n}\n",[30,4079,4080,4085,4101,4116,4120,4124,4129,4140,4159],{"__ignoreMap":40},[44,4081,4082],{"class":46,"line":47},[44,4083,4084],{"class":79},"\u002F\u002F Pass By Value 示例\n",[44,4086,4087,4089,4091,4094,4096,4098],{"class":46,"line":68},[44,4088,598],{"class":50},[44,4090,675],{"class":50},[44,4092,4093],{"class":108}," modify",[44,4095,309],{"class":54},[44,4097,51],{"class":50},[44,4099,4100],{"class":54}," x) {\n",[44,4102,4103,4106,4108,4111,4113],{"class":46,"line":83},[44,4104,4105],{"class":54},"    x ",[44,4107,58],{"class":50},[44,4109,4110],{"class":61}," 100",[44,4112,76],{"class":54},[44,4114,4115],{"class":79},"\u002F\u002F 不影响外部\n",[44,4117,4118],{"class":46,"line":97},[44,4119,763],{"class":54},[44,4121,4122],{"class":46,"line":474},[44,4123,666],{"emptyLinePlaceholder":665},[44,4125,4126],{"class":46,"line":492},[44,4127,4128],{"class":79},"\u002F\u002F 对象引用传递示例\n",[44,4130,4131,4133,4135,4137],{"class":46,"line":669},[44,4132,598],{"class":50},[44,4134,675],{"class":50},[44,4136,4093],{"class":108},[44,4138,4139],{"class":54},"(Car car) {\n",[44,4141,4142,4145,4148,4150,4153,4156],{"class":46,"line":684},[44,4143,4144],{"class":54},"    car.",[44,4146,4147],{"class":108},"setColor",[44,4149,309],{"class":54},[44,4151,4152],{"class":91},"\"blue\"",[44,4154,4155],{"class":54},"); ",[44,4157,4158],{"class":79},"\u002F\u002F 影响外部对象\n",[44,4160,4161],{"class":46,"line":703},[44,4162,763],{"class":54},[22,4164,4166],{"id":4165},"_42-集合collections","4.2 集合（Collections）",[521,4168,4169,4172,4175,4178],{},[524,4170,4171],{},"Java Collections 提供分组和组织数据的方式，允许在单一实体下存储和操作多个对象。",[524,4173,4174],{},"提供迭代、搜索、添加、删除等操作。",[524,4176,4177],{},"只能存储 objects（对象），不能存储 primitive data types（基本数据类型，如 int, char, double）。",[524,4179,4180],{},"类型检查在编译时进行，减少运行时类型错误。",[116,4182,4184,4185],{"id":4183},"_420-arraylist","4.2.0 ArrayList",[4186,4187],"t",{},[521,4189,4190,4193,4196],{},[524,4191,4192],{},"动态数组，大小可增长或缩小。",[524,4194,4195],{},"元素按顺序存储，可通过整数索引（从0开始）访问。",[524,4197,4198,4201],{},[30,4199,4200],{},"T"," 指定列表可包含的对象类型，在实例化时确定。",[35,4203,4205],{"className":37,"code":4204,"language":39,"meta":40,"style":40},"List\u003CInteger> list = new ArrayList\u003CInteger>();\nlist.add(10);\nint value = list.get(0);\nlist.remove(0);\nfor (Integer item : list) {\n    System.out.println(item);\n}\n",[30,4206,4207,4230,4245,4267,4280,4294,4304],{"__ignoreMap":40},[44,4208,4209,4212,4215,4218,4220,4222,4225,4227],{"class":46,"line":47},[44,4210,4211],{"class":54},"List\u003C",[44,4213,4214],{"class":50},"Integer",[44,4216,4217],{"class":54},"> list ",[44,4219,58],{"class":50},[44,4221,303],{"class":50},[44,4223,4224],{"class":54}," ArrayList\u003C",[44,4226,4214],{"class":50},[44,4228,4229],{"class":54},">();\n",[44,4231,4232,4235,4238,4240,4243],{"class":46,"line":68},[44,4233,4234],{"class":54},"list.",[44,4236,4237],{"class":108},"add",[44,4239,309],{"class":54},[44,4241,4242],{"class":61},"10",[44,4244,320],{"class":54},[44,4246,4247,4249,4252,4254,4257,4260,4262,4265],{"class":46,"line":83},[44,4248,51],{"class":50},[44,4250,4251],{"class":54}," value ",[44,4253,58],{"class":50},[44,4255,4256],{"class":54}," list.",[44,4258,4259],{"class":108},"get",[44,4261,309],{"class":54},[44,4263,4264],{"class":61},"0",[44,4266,320],{"class":54},[44,4268,4269,4271,4274,4276,4278],{"class":46,"line":97},[44,4270,4234],{"class":54},[44,4272,4273],{"class":108},"remove",[44,4275,309],{"class":54},[44,4277,4264],{"class":61},[44,4279,320],{"class":54},[44,4281,4282,4285,4288,4291],{"class":46,"line":474},[44,4283,4284],{"class":50},"for",[44,4286,4287],{"class":54}," (Integer item ",[44,4289,4290],{"class":50},":",[44,4292,4293],{"class":54}," list) {\n",[44,4295,4296,4299,4301],{"class":46,"line":492},[44,4297,4298],{"class":54},"    System.out.",[44,4300,394],{"class":108},[44,4302,4303],{"class":54},"(item);\n",[44,4305,4306],{"class":46,"line":669},[44,4307,763],{"class":54},[116,4309,4311],{"id":4310},"_421-hashmapk-v","4.2.1 HashMap\u003CK, V>",[521,4313,4314,4317,4320],{},[524,4315,4316],{},"用于存储 key-value pairs（键值对）。",[524,4318,4319],{},"key（键）和 value（值）都是对象。",[524,4321,4322],{},"通过 key 存储和检索 value。",[35,4324,4326],{"className":37,"code":4325,"language":39,"meta":40,"style":40},"HashMap\u003CString, Integer> map = new HashMap\u003CString, Integer>();\nmap.put(\"Monday\", 1);\nint day = map.get(\"Monday\");\n",[30,4327,4328,4357,4377],{"__ignoreMap":40},[44,4329,4330,4333,4335,4337,4339,4342,4344,4346,4349,4351,4353,4355],{"class":46,"line":47},[44,4331,4332],{"class":54},"HashMap\u003C",[44,4334,189],{"class":50},[44,4336,126],{"class":54},[44,4338,4214],{"class":50},[44,4340,4341],{"class":54},"> map ",[44,4343,58],{"class":50},[44,4345,303],{"class":50},[44,4347,4348],{"class":54}," HashMap\u003C",[44,4350,189],{"class":50},[44,4352,126],{"class":54},[44,4354,4214],{"class":50},[44,4356,4229],{"class":54},[44,4358,4359,4362,4365,4367,4370,4372,4375],{"class":46,"line":68},[44,4360,4361],{"class":54},"map.",[44,4363,4364],{"class":108},"put",[44,4366,309],{"class":54},[44,4368,4369],{"class":91},"\"Monday\"",[44,4371,126],{"class":54},[44,4373,4374],{"class":61},"1",[44,4376,320],{"class":54},[44,4378,4379,4381,4384,4386,4389,4391,4393,4395],{"class":46,"line":83},[44,4380,51],{"class":50},[44,4382,4383],{"class":54}," day ",[44,4385,58],{"class":50},[44,4387,4388],{"class":54}," map.",[44,4390,4259],{"class":108},[44,4392,309],{"class":54},[44,4394,4369],{"class":91},[44,4396,320],{"class":54},[22,4398,4400],{"id":4399},"_43-多态polymorphism","4.3 多态（Polymorphism）",[521,4402,4403,4406],{},[524,4404,4405],{},"Polymorphism（多态）是 OOP 的关键特性，允许通过父类型引用操作子类型对象，执行时根据实际对象类型调用相应方法。",[524,4407,4408],{},"核心：manipulate objects with similar interface subset（操作具有相似接口子集的对象）。",[116,4410,4412],{"id":4411},"_430-对象引用与继承","4.3.0 对象引用与继承",[521,4414,4415,4418,4425,4432],{},[524,4416,4417],{},"引用类型变量可以引用同类型对象，也可以引用其 sub-types（子类型）对象。",[524,4419,4420,4421,4424],{},"例如，",[30,4422,4423],{},"Animal myCat = new Cat();"," 合法，因为 Cat 是 Animal 的子类。",[524,4426,4427,4428,4431],{},"反之，子类型变量不能引用父类型对象，如 ",[30,4429,4430],{},"Cat myAnimal = new Animal();"," 非法。",[524,4433,4434],{},"引用类型与对象类型可以不同。",[35,4436,4438],{"className":37,"code":4437,"language":39,"meta":40,"style":40},"Cat myCat1 = new Cat();\nAnimal myCat2 = new Cat(); \u002F\u002F 合法\n",[30,4439,4440,4454],{"__ignoreMap":40},[44,4441,4442,4445,4447,4449,4452],{"class":46,"line":47},[44,4443,4444],{"class":54},"Cat myCat1 ",[44,4446,58],{"class":50},[44,4448,303],{"class":50},[44,4450,4451],{"class":108}," Cat",[44,4453,386],{"class":54},[44,4455,4456,4459,4461,4463,4465,4467],{"class":46,"line":68},[44,4457,4458],{"class":54},"Animal myCat2 ",[44,4460,58],{"class":50},[44,4462,303],{"class":50},[44,4464,4451],{"class":108},[44,4466,112],{"class":54},[44,4468,80],{"class":79},[116,4470,4472],{"id":4471},"_431-引用类型与对象类型的作用","4.3.1 引用类型与对象类型的作用",[521,4474,4475,4482,4488],{},[524,4476,4477,4481],{},[4478,4479,4480],"strong",{},"Reference Type（引用类型）"," 决定哪些 methods 和 data members 可以被调用或使用。",[524,4483,4484,4487],{},[4478,4485,4486],{},"Object Type（对象类型）"," 决定当调用被 overridden（重写）的方法时，执行哪个版本。",[524,4489,1004,4490,4493,4494,126,4497,126,4500,4503,4504,4507,4508,126,4510,4512,4513,4516,4517],{},[30,4491,4492],{},"Animal"," 有 ",[30,4495,4496],{},"makeNoise()",[30,4498,4499],{},"eat()",[30,4501,4502],{},"sleep()","；",[30,4505,4506],{},"Cat"," 重写 ",[30,4509,4496],{},[30,4511,4499],{},"，并新增 ",[30,4514,4515],{},"catchMouse()","。\n",[521,4518,4519,4533,4548],{},[524,4520,4521,4524,4525,126,4527,126,4529,126,4531,33],{},[30,4522,4523],{},"Cat myCat1 = new Cat();"," 可调用 ",[30,4526,4496],{},[30,4528,4499],{},[30,4530,4502],{},[30,4532,4515],{},[524,4534,4535,4538,4539,126,4541,126,4543,4545,4546,33],{},[30,4536,4537],{},"Animal myCat2 = new Cat();"," 只能调用 ",[30,4540,4496],{},[30,4542,4499],{},[30,4544,4502],{},"，不能调用 ",[30,4547,4515],{},[524,4549,4550,4551,4554],{},"当 ",[30,4552,4553],{},"myCat2.makeNoise()"," 执行时，实际执行 Cat 中重写的版本。",[35,4556,4558],{"className":37,"code":4557,"language":39,"meta":40,"style":40},"Animal myAni = new Animal();\nmyAni.makeNoise(); \u002F\u002F 调用 Animal 版本\nmyAni = new Cat();\nmyAni.makeNoise(); \u002F\u002F 调用 Cat 版本\n",[30,4559,4560,4574,4587,4600],{"__ignoreMap":40},[44,4561,4562,4565,4567,4569,4572],{"class":46,"line":47},[44,4563,4564],{"class":54},"Animal myAni ",[44,4566,58],{"class":50},[44,4568,303],{"class":50},[44,4570,4571],{"class":108}," Animal",[44,4573,386],{"class":54},[44,4575,4576,4579,4582,4584],{"class":46,"line":68},[44,4577,4578],{"class":54},"myAni.",[44,4580,4581],{"class":108},"makeNoise",[44,4583,112],{"class":54},[44,4585,4586],{"class":79},"\u002F\u002F 调用 Animal 版本\n",[44,4588,4589,4592,4594,4596,4598],{"class":46,"line":83},[44,4590,4591],{"class":54},"myAni ",[44,4593,58],{"class":50},[44,4595,303],{"class":50},[44,4597,4451],{"class":108},[44,4599,386],{"class":54},[44,4601,4602,4604,4606,4608],{"class":46,"line":97},[44,4603,4578],{"class":54},[44,4605,4581],{"class":108},[44,4607,112],{"class":54},[44,4609,4610],{"class":79},"\u002F\u002F 调用 Cat 版本\n",[521,4612,4613,4616],{},[524,4614,4615],{},"由于引用可以在不同时间引用不同对象类型，称为 polymorphic reference（多态引用）。",[524,4617,4618],{},"编译器使用 dynamic binding（动态绑定）在运行时确定执行哪个版本。",[116,4620,4622],{"id":4621},"_432-多态的三种应用形式","4.3.2 多态的三种应用形式",[521,4624,4625],{},[524,4626,4627,4630],{},[4478,4628,4629],{},"Polymorphic Arrays\u002FCollections（多态数组\u002F集合）","：可以混合存放父类型及其子类型的对象。",[35,4632,4634],{"className":37,"code":4633,"language":39,"meta":40,"style":40},"Animal[] myAnimals = new Animal[4];\nmyAnimals[0] = new Cat();\nmyAnimals[1] = new Cow();\nmyAnimals[2] = new Pig();\nmyAnimals[3] = new Cow();\n\nfor (Animal myAnimal : myAnimals) {\n    myAnimal.sound(); \u002F\u002F 根据对象类型输出 Meow, Moo, Oink, Moo\n}\n",[30,4635,4636,4658,4676,4693,4711,4728,4732,4744,4757],{"__ignoreMap":40},[44,4637,4638,4640,4643,4645,4647,4649,4652,4655],{"class":46,"line":47},[44,4639,4492],{"class":50},[44,4641,4642],{"class":54},"[] myAnimals ",[44,4644,58],{"class":50},[44,4646,303],{"class":50},[44,4648,4571],{"class":50},[44,4650,4651],{"class":54},"[",[44,4653,4654],{"class":61},"4",[44,4656,4657],{"class":54},"];\n",[44,4659,4660,4663,4665,4668,4670,4672,4674],{"class":46,"line":68},[44,4661,4662],{"class":54},"myAnimals[",[44,4664,4264],{"class":61},[44,4666,4667],{"class":54},"] ",[44,4669,58],{"class":50},[44,4671,303],{"class":50},[44,4673,4451],{"class":108},[44,4675,386],{"class":54},[44,4677,4678,4680,4682,4684,4686,4688,4691],{"class":46,"line":83},[44,4679,4662],{"class":54},[44,4681,4374],{"class":61},[44,4683,4667],{"class":54},[44,4685,58],{"class":50},[44,4687,303],{"class":50},[44,4689,4690],{"class":108}," Cow",[44,4692,386],{"class":54},[44,4694,4695,4697,4700,4702,4704,4706,4709],{"class":46,"line":97},[44,4696,4662],{"class":54},[44,4698,4699],{"class":61},"2",[44,4701,4667],{"class":54},[44,4703,58],{"class":50},[44,4705,303],{"class":50},[44,4707,4708],{"class":108}," Pig",[44,4710,386],{"class":54},[44,4712,4713,4715,4718,4720,4722,4724,4726],{"class":46,"line":474},[44,4714,4662],{"class":54},[44,4716,4717],{"class":61},"3",[44,4719,4667],{"class":54},[44,4721,58],{"class":50},[44,4723,303],{"class":50},[44,4725,4690],{"class":108},[44,4727,386],{"class":54},[44,4729,4730],{"class":46,"line":492},[44,4731,666],{"emptyLinePlaceholder":665},[44,4733,4734,4736,4739,4741],{"class":46,"line":669},[44,4735,4284],{"class":50},[44,4737,4738],{"class":54}," (Animal myAnimal ",[44,4740,4290],{"class":50},[44,4742,4743],{"class":54}," myAnimals) {\n",[44,4745,4746,4749,4752,4754],{"class":46,"line":684},[44,4747,4748],{"class":54},"    myAnimal.",[44,4750,4751],{"class":108},"sound",[44,4753,112],{"class":54},[44,4755,4756],{"class":79},"\u002F\u002F 根据对象类型输出 Meow, Moo, Oink, Moo\n",[44,4758,4759],{"class":46,"line":703},[44,4760,763],{"class":54},[521,4762,4763],{},[524,4764,4765,4768],{},[4478,4766,4767],{},"Polymorphic Arguments（多态参数）","：方法参数为父类型，可接受任意子类型对象。",[35,4770,4772],{"className":37,"code":4771,"language":39,"meta":40,"style":40},"public static void makeManySound(Animal myAnimal, int times) {\n    for (int i = 0; i \u003C times; i++) {\n        myAnimal.sound();\n    }\n}\nmakeManySound(new Cat(), 3); \u002F\u002F Meow Meow Meow\nmakeManySound(new Cow(), 2); \u002F\u002F Moo Moo\n",[30,4773,4774,4793,4822,4831,4835,4839,4860],{"__ignoreMap":40},[44,4775,4776,4778,4780,4782,4785,4788,4790],{"class":46,"line":47},[44,4777,598],{"class":50},[44,4779,830],{"class":50},[44,4781,675],{"class":50},[44,4783,4784],{"class":108}," makeManySound",[44,4786,4787],{"class":54},"(Animal myAnimal, ",[44,4789,51],{"class":50},[44,4791,4792],{"class":54}," times) {\n",[44,4794,4795,4798,4800,4802,4805,4807,4809,4812,4815,4818,4820],{"class":46,"line":68},[44,4796,4797],{"class":50},"    for",[44,4799,2302],{"class":54},[44,4801,51],{"class":50},[44,4803,4804],{"class":54}," i ",[44,4806,58],{"class":50},[44,4808,2748],{"class":61},[44,4810,4811],{"class":54},"; i ",[44,4813,4814],{"class":50},"\u003C",[44,4816,4817],{"class":54}," times; i",[44,4819,32],{"class":50},[44,4821,848],{"class":54},[44,4823,4824,4827,4829],{"class":46,"line":83},[44,4825,4826],{"class":54},"        myAnimal.",[44,4828,4751],{"class":108},[44,4830,386],{"class":54},[44,4832,4833],{"class":46,"line":97},[44,4834,757],{"class":54},[44,4836,4837],{"class":46,"line":474},[44,4838,763],{"class":54},[44,4840,4841,4844,4846,4848,4850,4853,4855,4857],{"class":46,"line":492},[44,4842,4843],{"class":108},"makeManySound",[44,4845,309],{"class":54},[44,4847,366],{"class":50},[44,4849,4451],{"class":108},[44,4851,4852],{"class":54},"(), ",[44,4854,4717],{"class":61},[44,4856,4155],{"class":54},[44,4858,4859],{"class":79},"\u002F\u002F Meow Meow Meow\n",[44,4861,4862,4864,4866,4868,4870,4872,4874,4876],{"class":46,"line":669},[44,4863,4843],{"class":108},[44,4865,309],{"class":54},[44,4867,366],{"class":50},[44,4869,4690],{"class":108},[44,4871,4852],{"class":54},[44,4873,4699],{"class":61},[44,4875,4155],{"class":54},[44,4877,4878],{"class":79},"\u002F\u002F Moo Moo\n",[521,4880,4881],{},[524,4882,4883,4886],{},[4478,4884,4885],{},"Polymorphic Return Type（多态返回类型）","：方法返回父类型，可返回任意子类型对象。",[35,4888,4890],{"className":37,"code":4889,"language":39,"meta":40,"style":40},"public static Animal createAnimal(String type) {\n    switch (type) {\n        case \"cat\": return new Cat();\n        case \"pig\": return new Pig();\n        case \"cow\": return new Cow();\n        default: return null;\n    }\n}\nAnimal myAnimal1 = createAnimal(\"cat\");\nmyAnimal1.sound(); \u002F\u002F Meow\n",[30,4891,4892,4907,4915,4933,4950,4967,4979,4983,4987,5004],{"__ignoreMap":40},[44,4893,4894,4896,4898,4901,4904],{"class":46,"line":47},[44,4895,598],{"class":50},[44,4897,830],{"class":50},[44,4899,4900],{"class":54}," Animal ",[44,4902,4903],{"class":108},"createAnimal",[44,4905,4906],{"class":54},"(String type) {\n",[44,4908,4909,4912],{"class":46,"line":68},[44,4910,4911],{"class":50},"    switch",[44,4913,4914],{"class":54}," (type) {\n",[44,4916,4917,4920,4922,4924,4927,4929,4931],{"class":46,"line":83},[44,4918,4919],{"class":50},"        case",[44,4921,217],{"class":91},[44,4923,4290],{"class":50},[44,4925,4926],{"class":50}," return",[44,4928,303],{"class":50},[44,4930,4451],{"class":108},[44,4932,386],{"class":54},[44,4934,4935,4937,4940,4942,4944,4946,4948],{"class":46,"line":97},[44,4936,4919],{"class":50},[44,4938,4939],{"class":91}," \"pig\"",[44,4941,4290],{"class":50},[44,4943,4926],{"class":50},[44,4945,303],{"class":50},[44,4947,4708],{"class":108},[44,4949,386],{"class":54},[44,4951,4952,4954,4957,4959,4961,4963,4965],{"class":46,"line":474},[44,4953,4919],{"class":50},[44,4955,4956],{"class":91}," \"cow\"",[44,4958,4290],{"class":50},[44,4960,4926],{"class":50},[44,4962,303],{"class":50},[44,4964,4690],{"class":108},[44,4966,386],{"class":54},[44,4968,4969,4972,4974,4977],{"class":46,"line":492},[44,4970,4971],{"class":50},"        default:",[44,4973,4926],{"class":50},[44,4975,4976],{"class":61}," null",[44,4978,165],{"class":54},[44,4980,4981],{"class":46,"line":669},[44,4982,757],{"class":54},[44,4984,4985],{"class":46,"line":684},[44,4986,763],{"class":54},[44,4988,4989,4992,4994,4997,4999,5002],{"class":46,"line":703},[44,4990,4991],{"class":54},"Animal myAnimal1 ",[44,4993,58],{"class":50},[44,4995,4996],{"class":108}," createAnimal",[44,4998,309],{"class":54},[44,5000,5001],{"class":91},"\"cat\"",[44,5003,320],{"class":54},[44,5005,5006,5009,5011,5013],{"class":46,"line":720},[44,5007,5008],{"class":54},"myAnimal1.",[44,5010,4751],{"class":108},[44,5012,112],{"class":54},[44,5014,5015],{"class":79},"\u002F\u002F Meow\n",[116,5017,5019],{"id":5018},"_433-多态的好处","4.3.3 多态的好处",[521,5021,5022,5025,5028],{},[524,5023,5024],{},"编写代码时无需随着新子类型的引入而修改。",[524,5026,5027],{},"框架可以在不知道具体子类的情况下实现。",[524,5029,5030,5031,1839,5034,5037],{},"示例：Shape 层次中，Drawing 类使用 ",[30,5032,5033],{},"List\u003CShape>",[30,5035,5036],{},"draw()"," 方法，新增 Triangle 子类时，Drawing 类无需修改。",[35,5039,5041],{"className":37,"code":5040,"language":39,"meta":40,"style":40},"class Drawing {\n    List\u003CShape> allshapes = new ArrayList\u003CShape>();\n    public void add(Shape s) { allshapes.add(s); }\n    public void draw() {\n        for (Shape s : allshapes) {\n            s.draw();\n        }\n    }\n}\n",[30,5042,5043,5052,5073,5096,5107,5120,5130,5135,5139],{"__ignoreMap":40},[44,5044,5045,5047,5050],{"class":46,"line":47},[44,5046,3620],{"class":50},[44,5048,5049],{"class":108}," Drawing",[44,5051,606],{"class":54},[44,5053,5054,5057,5060,5063,5065,5067,5069,5071],{"class":46,"line":68},[44,5055,5056],{"class":54},"    List\u003C",[44,5058,5059],{"class":50},"Shape",[44,5061,5062],{"class":54},"> allshapes ",[44,5064,58],{"class":50},[44,5066,303],{"class":50},[44,5068,4224],{"class":54},[44,5070,5059],{"class":50},[44,5072,4229],{"class":54},[44,5074,5075,5077,5079,5082,5085,5088,5091,5093],{"class":46,"line":83},[44,5076,672],{"class":50},[44,5078,675],{"class":50},[44,5080,5081],{"class":108}," add",[44,5083,5084],{"class":54},"(Shape ",[44,5086,5087],{"class":845},"s",[44,5089,5090],{"class":54},") { allshapes.",[44,5092,4237],{"class":108},[44,5094,5095],{"class":54},"(s); }\n",[44,5097,5098,5100,5102,5105],{"class":46,"line":97},[44,5099,672],{"class":50},[44,5101,675],{"class":50},[44,5103,5104],{"class":108}," draw",[44,5106,681],{"class":54},[44,5108,5109,5112,5115,5117],{"class":46,"line":474},[44,5110,5111],{"class":50},"        for",[44,5113,5114],{"class":54}," (Shape s ",[44,5116,4290],{"class":50},[44,5118,5119],{"class":54}," allshapes) {\n",[44,5121,5122,5125,5128],{"class":46,"line":492},[44,5123,5124],{"class":54},"            s.",[44,5126,5127],{"class":108},"draw",[44,5129,386],{"class":54},[44,5131,5132],{"class":46,"line":669},[44,5133,5134],{"class":54},"        }\n",[44,5136,5137],{"class":46,"line":684},[44,5138,757],{"class":54},[44,5140,5141],{"class":46,"line":703},[44,5142,763],{"class":54},[22,5144,5146],{"id":5145},"_44-类型转换casting","4.4 类型转换（Casting）",[521,5148,5149,5152],{},[524,5150,5151],{},"引用类型变量可以赋值给同类型或子类型对象（upcasting，向上转型，自动）。",[524,5153,5154],{},"子类型变量不能直接引用父类型对象，需要 explicit casting（显式类型转换，downcasting，向下转型）。",[35,5156,5158],{"className":37,"code":5157,"language":39,"meta":40,"style":40},"EBook myEBook = new EBook(\"深入理解 Java 虚拟机\", \"epub\");\nBook myBook = myEBook; \u002F\u002F 向上转型，自动\n\u002F\u002F ...\nEBook backToEBook = (EBook) myBook; \u002F\u002F 向下转型，强制\n",[30,5159,5160,5183,5195,5200],{"__ignoreMap":40},[44,5161,5162,5165,5167,5169,5172,5174,5176,5178,5181],{"class":46,"line":47},[44,5163,5164],{"class":54},"EBook myEBook ",[44,5166,58],{"class":50},[44,5168,303],{"class":50},[44,5170,5171],{"class":108}," EBook",[44,5173,309],{"class":54},[44,5175,1368],{"class":91},[44,5177,126],{"class":54},[44,5179,5180],{"class":91},"\"epub\"",[44,5182,320],{"class":54},[44,5184,5185,5187,5189,5192],{"class":46,"line":68},[44,5186,377],{"class":54},[44,5188,58],{"class":50},[44,5190,5191],{"class":54}," myEBook; ",[44,5193,5194],{"class":79},"\u002F\u002F 向上转型，自动\n",[44,5196,5197],{"class":46,"line":83},[44,5198,5199],{"class":79},"\u002F\u002F ...\n",[44,5201,5202,5205,5207,5210],{"class":46,"line":97},[44,5203,5204],{"class":54},"EBook backToEBook ",[44,5206,58],{"class":50},[44,5208,5209],{"class":54}," (EBook) myBook; ",[44,5211,5212],{"class":79},"\u002F\u002F 向下转型，强制\n",[521,5214,5215,5221],{},[524,5216,5217,5218,33],{},"如果对象实际类型不是要转换的类型，会抛出 ",[30,5219,5220],{},"ClassCastException",[524,5222,5223,5224,5227],{},"使用 ",[30,5225,5226],{},"instanceof"," 在转换前检查对象类型。",[35,5229,5231],{"className":37,"code":5230,"language":39,"meta":40,"style":40},"if (myBook instanceof EBook) {\n    EBook backToEBook = (EBook) myBook;\n}\n",[30,5232,5233,5246,5256],{"__ignoreMap":40},[44,5234,5235,5238,5241,5243],{"class":46,"line":47},[44,5236,5237],{"class":50},"if",[44,5239,5240],{"class":54}," (myBook ",[44,5242,5226],{"class":50},[44,5244,5245],{"class":54}," EBook) {\n",[44,5247,5248,5251,5253],{"class":46,"line":68},[44,5249,5250],{"class":54},"    EBook backToEBook ",[44,5252,58],{"class":50},[44,5254,5255],{"class":54}," (EBook) myBook;\n",[44,5257,5258],{"class":46,"line":83},[44,5259,763],{"class":54},[521,5261,5262],{},[524,5263,5264,5265,5268],{},"示例：实现 ",[30,5266,5267],{},"equals()"," 方法，比较两个 Circle 的 radius。",[35,5270,5272],{"className":37,"code":5271,"language":39,"meta":40,"style":40},"@Override\npublic boolean equals(Object anotherObj) {\n    if (!(anotherObj instanceof Circle)) {\n        return false;\n    }\n    Circle anotherCircle = (Circle) anotherObj;\n    return anotherCircle.radius == this.radius;\n}\n",[30,5273,5274,5282,5294,5311,5319,5323,5333,5349],{"__ignoreMap":40},[44,5275,5276,5279],{"class":46,"line":47},[44,5277,5278],{"class":54},"@",[44,5280,5281],{"class":50},"Override\n",[44,5283,5284,5286,5288,5291],{"class":46,"line":68},[44,5285,598],{"class":50},[44,5287,2173],{"class":50},[44,5289,5290],{"class":108}," equals",[44,5292,5293],{"class":54},"(Object anotherObj) {\n",[44,5295,5296,5299,5301,5303,5306,5308],{"class":46,"line":83},[44,5297,5298],{"class":50},"    if",[44,5300,2302],{"class":54},[44,5302,2305],{"class":50},[44,5304,5305],{"class":54},"(anotherObj ",[44,5307,5226],{"class":50},[44,5309,5310],{"class":54}," Circle)) {\n",[44,5312,5313,5315,5317],{"class":46,"line":97},[44,5314,2248],{"class":50},[44,5316,2209],{"class":61},[44,5318,165],{"class":54},[44,5320,5321],{"class":46,"line":474},[44,5322,757],{"class":54},[44,5324,5325,5328,5330],{"class":46,"line":492},[44,5326,5327],{"class":54},"    Circle anotherCircle ",[44,5329,58],{"class":50},[44,5331,5332],{"class":54}," (Circle) anotherObj;\n",[44,5334,5335,5338,5341,5344,5346],{"class":46,"line":669},[44,5336,5337],{"class":50},"    return",[44,5339,5340],{"class":54}," anotherCircle.radius ",[44,5342,5343],{"class":50},"==",[44,5345,2051],{"class":61},[44,5347,5348],{"class":54},".radius;\n",[44,5350,5351],{"class":46,"line":684},[44,5352,763],{"class":54},[22,5354,5356],{"id":5355},"_45-多态解决方案","4.5 多态解决方案",[521,5358,5359,5362],{},[524,5360,5361],{},"反例：给每种人各写一个类、各存一个数组来算总额，代码重复，加一种人就要改一遍。",[524,5363,5364,5365],{},"用 Inheritance 和 Polymorphism 重新设计：\n",[521,5366,5367,5376,5386],{},[524,5368,5369,5370,4493,5372,1839,5374,2811],{},"父类 ",[30,5371,3695],{},[30,5373,3021],{},[30,5375,3152],{},[524,5377,5378,5379,126,5381,5383,5384,33],{},"子类 ",[30,5380,3136],{},[30,5382,3161],{}," 各自重写 ",[30,5385,3152],{},[524,5387,5388,5391,5392,5395,5396,5398],{},[30,5389,5390],{},"Payroll"," 只持有 ",[30,5393,5394],{},"Staff[]","，循环里统一调用 ",[30,5397,3152],{},"，具体执行哪个版本交给动态绑定。",[35,5400,5402],{"className":37,"code":5401,"language":39,"meta":40,"style":40},"public class Payroll {\n    private Staff[] staff;\n    public Payroll(Staff[] staff) { this.staff = staff; }\n    public double totalPay() {\n        double total = 0;\n        for (Staff s : staff) {\n            total += s.monthlyPay();\n        }\n        return total;\n    }\n}\n",[30,5403,5404,5415,5424,5452,5463,5477,5489,5505,5509,5516,5520],{"__ignoreMap":40},[44,5405,5406,5408,5410,5413],{"class":46,"line":47},[44,5407,598],{"class":50},[44,5409,601],{"class":50},[44,5411,5412],{"class":108}," Payroll",[44,5414,606],{"class":54},[44,5416,5417,5419,5421],{"class":46,"line":68},[44,5418,1048],{"class":50},[44,5420,3740],{"class":50},[44,5422,5423],{"class":54},"[] staff;\n",[44,5425,5426,5428,5430,5432,5434,5436,5439,5442,5444,5447,5449],{"class":46,"line":83},[44,5427,672],{"class":50},[44,5429,5412],{"class":108},[44,5431,309],{"class":54},[44,5433,3695],{"class":50},[44,5435,842],{"class":54},[44,5437,5438],{"class":845},"staff",[44,5440,5441],{"class":54},") { ",[44,5443,1979],{"class":61},[44,5445,5446],{"class":54},".staff ",[44,5448,58],{"class":50},[44,5450,5451],{"class":54}," staff; }\n",[44,5453,5454,5456,5458,5461],{"class":46,"line":97},[44,5455,672],{"class":50},[44,5457,1075],{"class":50},[44,5459,5460],{"class":108}," totalPay",[44,5462,681],{"class":54},[44,5464,5465,5468,5471,5473,5475],{"class":46,"line":474},[44,5466,5467],{"class":50},"        double",[44,5469,5470],{"class":54}," total ",[44,5472,58],{"class":50},[44,5474,2748],{"class":61},[44,5476,165],{"class":54},[44,5478,5479,5481,5484,5486],{"class":46,"line":492},[44,5480,5111],{"class":50},[44,5482,5483],{"class":54}," (Staff s ",[44,5485,4290],{"class":50},[44,5487,5488],{"class":54}," staff) {\n",[44,5490,5491,5494,5497,5500,5503],{"class":46,"line":669},[44,5492,5493],{"class":54},"            total ",[44,5495,5496],{"class":50},"+=",[44,5498,5499],{"class":54}," s.",[44,5501,5502],{"class":108},"monthlyPay",[44,5504,386],{"class":54},[44,5506,5507],{"class":46,"line":684},[44,5508,5134],{"class":54},[44,5510,5511,5513],{"class":46,"line":703},[44,5512,2248],{"class":50},[44,5514,5515],{"class":54}," total;\n",[44,5517,5518],{"class":46,"line":720},[44,5519,757],{"class":54},[44,5521,5522],{"class":46,"line":737},[44,5523,763],{"class":54},[521,5525,5526],{},[524,5527,5528,5529,5531,5532,5534],{},"再加一种人的时候，只要新写一个子类并重写 ",[30,5530,3152],{},"，",[30,5533,5390],{}," 完全不用动。",[510,5536],{},[17,5538,5540],{"id":5539},"_5-抽象类接口与异常处理","5 抽象类、接口与异常处理",[22,5542,5544],{"id":5543},"_50-松耦合的软件设计","5.0 松耦合的软件设计",[521,5546,5547,5550,5553,5556],{},[524,5548,5549],{},"目标是设计 loosely-coupled（松耦合）的软件，组件边界清晰。",[524,5551,5552],{},"Tightly-coupled（紧耦合）情况下，组件 A 的变化要求组件 B 也变化才能协同工作。",[524,5554,5555],{},"组件仍需紧密协作以保证系统高效有用。",[524,5557,5558],{},"Abstract Class（抽象类）和 Interface（接口）是两种语言构造，使组件紧密协作的同时保持松耦合，便于维护和升级。",[22,5560,5562],{"id":5561},"_51-抽象类abstract-class","5.1 抽象类（Abstract Class）",[521,5564,5565,5568,5571,5574],{},[524,5566,5567],{},"类似普通类，但有一个或多个 abstract methods（抽象方法，无实现）。",[524,5569,5570],{},"不能 instantiated（实例化），设计为被继承或子类化。",[524,5572,5573],{},"继承抽象类的类必须实现该抽象类中定义的所有抽象方法。",[524,5575,5576],{},"示例：Shape 抽象类提供核心功能，将面积计算留给子类 Circle 和 Rectangle。",[35,5578,5580],{"className":37,"code":5579,"language":39,"meta":40,"style":40},"abstract class Shape {\n    abstract double area();\n}\nclass Circle extends Shape {\n    double radius;\n    Circle(double radius) { this.radius = radius; }\n    @Override\n    double area() { return Math.PI * radius * radius; }\n}\n",[30,5581,5582,5594,5606,5610,5623,5630,5654,5661,5684],{"__ignoreMap":40},[44,5583,5584,5587,5589,5592],{"class":46,"line":47},[44,5585,5586],{"class":50},"abstract",[44,5588,601],{"class":50},[44,5590,5591],{"class":108}," Shape",[44,5593,606],{"class":54},[44,5595,5596,5599,5601,5604],{"class":46,"line":68},[44,5597,5598],{"class":50},"    abstract",[44,5600,1075],{"class":50},[44,5602,5603],{"class":108}," area",[44,5605,386],{"class":54},[44,5607,5608],{"class":46,"line":83},[44,5609,763],{"class":54},[44,5611,5612,5614,5617,5619,5621],{"class":46,"line":97},[44,5613,3620],{"class":50},[44,5615,5616],{"class":108}," Circle",[44,5618,2877],{"class":50},[44,5620,5591],{"class":108},[44,5622,606],{"class":54},[44,5624,5625,5627],{"class":46,"line":474},[44,5626,650],{"class":50},[44,5628,5629],{"class":54}," radius;\n",[44,5631,5632,5635,5637,5639,5642,5644,5646,5649,5651],{"class":46,"line":492},[44,5633,5634],{"class":108},"    Circle",[44,5636,309],{"class":54},[44,5638,140],{"class":50},[44,5640,5641],{"class":845}," radius",[44,5643,5441],{"class":54},[44,5645,1979],{"class":61},[44,5647,5648],{"class":54},".radius ",[44,5650,58],{"class":50},[44,5652,5653],{"class":54}," radius; }\n",[44,5655,5656,5659],{"class":46,"line":669},[44,5657,5658],{"class":54},"    @",[44,5660,5281],{"class":50},[44,5662,5663,5665,5667,5669,5672,5675,5677,5680,5682],{"class":46,"line":684},[44,5664,650],{"class":50},[44,5666,5603],{"class":108},[44,5668,2645],{"class":54},[44,5670,5671],{"class":50},"return",[44,5673,5674],{"class":54}," Math.PI ",[44,5676,3579],{"class":50},[44,5678,5679],{"class":54}," radius ",[44,5681,3579],{"class":50},[44,5683,5653],{"class":54},[44,5685,5686],{"class":46,"line":703},[44,5687,763],{"class":54},[22,5689,5691],{"id":5690},"_52-接口interface","5.2 接口（Interface）",[521,5693,5694,5697,5700,5703,5706,5709],{},[524,5695,5696],{},"作为软件组件之间的 contract（契约），定义一个或多个 interface methods（接口方法），必须被实现。",[524,5698,5699],{},"接口方法定义系统中交互组件预期的行为。",[524,5701,5702],{},"接口方法无实现，因此接口不能实例化。",[524,5704,5705],{},"实现接口的类必须提供该接口定义的所有接口方法的实现。",[524,5707,5708],{},"一个类可以实现一个或多个接口。",[524,5710,1004,5711,5714,5715,5718],{},[30,5712,5713],{},"Logger"," 并不关心传进来的是什么类，只要它实现了 ",[30,5716,5717],{},"ILoggable","（能给出自己的日志文本）就能被记录下来。",[35,5720,5722],{"className":37,"code":5721,"language":39,"meta":40,"style":40},"interface ILoggable {\n    String getLogMessage();\n}\nclass Logger {\n    void log(ILoggable obj) {\n        System.out.println(obj.getLogMessage());\n    }\n}\n",[30,5723,5724,5734,5744,5748,5757,5773,5786,5790],{"__ignoreMap":40},[44,5725,5726,5729,5732],{"class":46,"line":47},[44,5727,5728],{"class":50},"interface",[44,5730,5731],{"class":108}," ILoggable",[44,5733,606],{"class":54},[44,5735,5736,5739,5742],{"class":46,"line":68},[44,5737,5738],{"class":54},"    String ",[44,5740,5741],{"class":108},"getLogMessage",[44,5743,386],{"class":54},[44,5745,5746],{"class":46,"line":83},[44,5747,763],{"class":54},[44,5749,5750,5752,5755],{"class":46,"line":97},[44,5751,3620],{"class":50},[44,5753,5754],{"class":108}," Logger",[44,5756,606],{"class":54},[44,5758,5759,5762,5765,5768,5771],{"class":46,"line":474},[44,5760,5761],{"class":50},"    void",[44,5763,5764],{"class":108}," log",[44,5766,5767],{"class":54},"(ILoggable ",[44,5769,5770],{"class":845},"obj",[44,5772,848],{"class":54},[44,5774,5775,5777,5779,5782,5784],{"class":46,"line":492},[44,5776,687],{"class":54},[44,5778,394],{"class":108},[44,5780,5781],{"class":54},"(obj.",[44,5783,5741],{"class":108},[44,5785,403],{"class":54},[44,5787,5788],{"class":46,"line":669},[44,5789,757],{"class":54},[44,5791,5792],{"class":46,"line":684},[44,5793,763],{"class":54},[22,5795,5797],{"id":5796},"_53-抽象类与接口的对比","5.3 抽象类与接口的对比",[5799,5800,5801,5817],"table",{},[5802,5803,5804],"thead",{},[5805,5806,5807,5811,5814],"tr",{},[5808,5809,5810],"th",{},"Feature",[5808,5812,5813],{},"Abstract Class",[5808,5815,5816],{},"Interface",[5818,5819,5820,5832,5843,5854,5871,5882],"tbody",{},[5805,5821,5822,5826,5829],{},[5823,5824,5825],"td",{},"Constructors",[5823,5827,5828],{},"可以有构造器",[5823,5830,5831],{},"不能有构造器",[5805,5833,5834,5837,5840],{},[5823,5835,5836],{},"Implementation",[5823,5838,5839],{},"可以有抽象方法和具体方法",[5823,5841,5842],{},"方法隐式为抽象（无方法体）",[5805,5844,5845,5848,5851],{},[5823,5846,5847],{},"Variables",[5823,5849,5850],{},"可以有实例变量、static 和 final 字段",[5823,5852,5853],{},"变量隐式为 public, static, final（常量）",[5805,5855,5856,5859,5865],{},[5823,5857,5858],{},"Inheritance keyword",[5823,5860,5861,5862,5864],{},"类使用 ",[30,5863,3609],{}," 继承抽象类",[5823,5866,5861,5867,5870],{},[30,5868,5869],{},"implements"," 实现接口",[5805,5872,5873,5876,5879],{},[5823,5874,5875],{},"Multiple Inheritance",[5823,5877,5878],{},"一个类只能继承一个抽象类",[5823,5880,5881],{},"一个类可以实现多个接口",[5805,5883,5884,5887,5890],{},[5823,5885,5886],{},"Access Modifiers",[5823,5888,5889],{},"可以使用 public, protected, private",[5823,5891,5892],{},"所有成员隐式为 public",[22,5894,5896],{"id":5895},"_54-异常处理exception-handling","5.4 异常处理（Exception Handling）",[521,5898,5899,5902,5913],{},[524,5900,5901],{},"运行时错误场景：除零、输入非整数、文件写入、从互联网下载图片等。",[524,5903,5904,5905],{},"Runtime vs Compile-time Errors：\n",[521,5906,5907,5910],{},[524,5908,5909],{},"Compile-time errors（编译时错误）：编译期间发生，必须修正才能运行。",[524,5911,5912],{},"Runtime errors（运行时错误）：程序运行期间发生，难以确定预测。",[524,5914,5915],{},"应由 programmers（程序员）处理异常。",[22,5917,5919],{"id":5918},"_55-什么是异常","5.5 什么是异常",[521,5921,5922,5925,5928,5931],{},[524,5923,5924],{},"Java 异常处理是 object-oriented（面向对象的）。",[524,5926,5927],{},"运行时错误发生时，JRE 生成（throws，抛出）一个 Exception 对象。",[524,5929,5930],{},"Exception 对象嵌入异常信息：异常类型、原因、程序当前状态。",[524,5932,5933],{},"JRE 停止执行后续未处理的代码。",[35,5935,5937],{"className":37,"code":5936,"language":39,"meta":40,"style":40},"int quotient = 10 \u002F divisor;\nSystem.out.println(quotient);\n",[30,5938,5939,5956],{"__ignoreMap":40},[44,5940,5941,5943,5946,5948,5950,5953],{"class":46,"line":47},[44,5942,51],{"class":50},[44,5944,5945],{"class":54}," quotient ",[44,5947,58],{"class":50},[44,5949,62],{"class":61},[44,5951,5952],{"class":50}," \u002F",[44,5954,5955],{"class":54}," divisor;\n",[44,5957,5958,5960,5962],{"class":46,"line":68},[44,5959,391],{"class":54},[44,5961,394],{"class":108},[44,5963,5964],{"class":54},"(quotient);\n",[22,5966,5968],{"id":5967},"_56-怎么处理异常","5.6 怎么处理异常",[521,5970,5971,5985],{},[524,5972,5973,5974],{},"处理方式：\n",[521,5975,5976,5979,5982],{},[524,5977,5978],{},"Option A：Ignore it（忽略），由默认异常处理器处理。",[524,5980,5981],{},"Option B1：Handle it where it occurs（在发生处处理）。",[524,5983,5984],{},"Option B2：Handle it in another place（在其他地方处理）。",[524,5986,5987],{},"处理异常的方式是重要的设计考虑。",[116,5989,5991],{"id":5990},"_560-try-catch","5.6.0 try-catch",[521,5993,5994,5997,6000,6007,6010,6013],{},[524,5995,5996],{},"try 块包含可能抛出异常的语句。",[524,5998,5999],{},"异常在 try 块中抛出后，可在 catch 块中捕获和处理。",[524,6001,6002,6003,6006],{},"异常对象 ",[30,6004,6005],{},"e"," 及所有信息由 JRE 提供。",[524,6008,6009],{},"可以有多个 catch 块处理不同异常类型，抛出异常时调用第一个兼容的 catch 块。",[524,6011,6012],{},"若 try 块成功执行无异常，后续 catch 块不执行，流程继续到最后一个 catch 块之后。",[524,6014,6015],{},"若异常被抛出，程序流进入相应 catch 块。执行完 catch 块后，不会返回 try 块，而是继续到最后一个 catch 块之后的语句，程序继续运行不终止。",[35,6017,6019],{"className":37,"code":6018,"language":39,"meta":40,"style":40},"try {\n    int divisor = scanner.nextInt();\n    int quotient = 10 \u002F divisor;\n    System.out.println(quotient);\n} catch (InputMismatchException e) {\n    System.err.println(\"输入的不是整数\");\n} catch (ArithmeticException e) {\n    System.err.println(\"除数不能为 0\");\n}\n",[30,6020,6021,6028,6045,6059,6067,6082,6096,6109,6122],{"__ignoreMap":40},[44,6022,6023,6026],{"class":46,"line":47},[44,6024,6025],{"class":50},"try",[44,6027,606],{"class":54},[44,6029,6030,6032,6035,6037,6040,6043],{"class":46,"line":68},[44,6031,635],{"class":50},[44,6033,6034],{"class":54}," divisor ",[44,6036,58],{"class":50},[44,6038,6039],{"class":54}," scanner.",[44,6041,6042],{"class":108},"nextInt",[44,6044,386],{"class":54},[44,6046,6047,6049,6051,6053,6055,6057],{"class":46,"line":83},[44,6048,635],{"class":50},[44,6050,5945],{"class":54},[44,6052,58],{"class":50},[44,6054,62],{"class":61},[44,6056,5952],{"class":50},[44,6058,5955],{"class":54},[44,6060,6061,6063,6065],{"class":46,"line":97},[44,6062,4298],{"class":54},[44,6064,394],{"class":108},[44,6066,5964],{"class":54},[44,6068,6069,6072,6075,6078,6080],{"class":46,"line":474},[44,6070,6071],{"class":54},"} ",[44,6073,6074],{"class":50},"catch",[44,6076,6077],{"class":54}," (InputMismatchException ",[44,6079,6005],{"class":845},[44,6081,848],{"class":54},[44,6083,6084,6087,6089,6091,6094],{"class":46,"line":492},[44,6085,6086],{"class":54},"    System.err.",[44,6088,394],{"class":108},[44,6090,309],{"class":54},[44,6092,6093],{"class":91},"\"输入的不是整数\"",[44,6095,320],{"class":54},[44,6097,6098,6100,6102,6105,6107],{"class":46,"line":669},[44,6099,6071],{"class":54},[44,6101,6074],{"class":50},[44,6103,6104],{"class":54}," (ArithmeticException ",[44,6106,6005],{"class":845},[44,6108,848],{"class":54},[44,6110,6111,6113,6115,6117,6120],{"class":46,"line":684},[44,6112,6086],{"class":54},[44,6114,394],{"class":108},[44,6116,309],{"class":54},[44,6118,6119],{"class":91},"\"除数不能为 0\"",[44,6121,320],{"class":54},[44,6123,6124],{"class":46,"line":703},[44,6125,763],{"class":54},[116,6127,6129],{"id":6128},"_561-finally","5.6.1 finally",[521,6131,6132,6135,6138],{},[524,6133,6134],{},"finally 块总是执行，无论是否发生异常。",[524,6136,6137],{},"通常用于清理已分配资源，如文件、互联网连接。",[524,6139,6140,6141],{},"执行时机：\n",[6142,6143,6144,6147,6150],"ol",{},[524,6145,6146],{},"无异常生成：try 块语句完成后执行 finally 块语句。",[524,6148,6149],{},"异常生成：相应 catch 块语句完成后执行 finally 块语句。",[524,6151,6152],{},"异常未捕获：finally 块仍会执行。",[35,6154,6156],{"className":37,"code":6155,"language":39,"meta":40,"style":40},"try {\n    \u002F\u002F Main logic code\n} catch (Exception_Type1 e1) {\n    \u002F\u002F Exception handling code\n} catch (Exception_Type2 e2) {\n    \u002F\u002F Exception handling code\n} finally {\n    \u002F\u002F Clean up code\n}\n",[30,6157,6158,6164,6169,6183,6188,6202,6206,6215,6220],{"__ignoreMap":40},[44,6159,6160,6162],{"class":46,"line":47},[44,6161,6025],{"class":50},[44,6163,606],{"class":54},[44,6165,6166],{"class":46,"line":68},[44,6167,6168],{"class":79},"    \u002F\u002F Main logic code\n",[44,6170,6171,6173,6175,6178,6181],{"class":46,"line":83},[44,6172,6071],{"class":54},[44,6174,6074],{"class":50},[44,6176,6177],{"class":54}," (Exception_Type1 ",[44,6179,6180],{"class":845},"e1",[44,6182,848],{"class":54},[44,6184,6185],{"class":46,"line":97},[44,6186,6187],{"class":79},"    \u002F\u002F Exception handling code\n",[44,6189,6190,6192,6194,6197,6200],{"class":46,"line":474},[44,6191,6071],{"class":54},[44,6193,6074],{"class":50},[44,6195,6196],{"class":54}," (Exception_Type2 ",[44,6198,6199],{"class":845},"e2",[44,6201,848],{"class":54},[44,6203,6204],{"class":46,"line":492},[44,6205,6187],{"class":79},[44,6207,6208,6210,6213],{"class":46,"line":669},[44,6209,6071],{"class":54},[44,6211,6212],{"class":50},"finally",[44,6214,606],{"class":54},[44,6216,6217],{"class":46,"line":684},[44,6218,6219],{"class":79},"    \u002F\u002F Clean up code\n",[44,6221,6222],{"class":46,"line":703},[44,6223,763],{"class":54},[22,6225,6227],{"id":6226},"_57-异常类的继承层次","5.7 异常类的继承层次",[521,6229,6230,6233,6236,6239,6242,6245],{},[524,6231,6232],{},"异常对象由类定义，根类为 Exception。",[524,6234,6235],{},"层次结构：Exception -> IOException, ClassNotFoundException, RuntimeException -> ArithmeticException, InputMismatchException, IndexOutOfBoundsException -> ArrayIndexOutOfBoundsException, StringIndexOutOfBoundsException。",[524,6237,6238],{},"RuntimeException 及其子类为 unchecked exceptions（非受检异常）。",[524,6240,6241],{},"其他为 checked exceptions（受检异常）。",[524,6243,6244],{},"捕获父类异常可捕获其所有派生类异常。",[524,6246,6247],{},"最好为每个预期异常指定 catch 块，并添加通用 Exception 类捕获其他异常。",[35,6249,6251],{"className":37,"code":6250,"language":39,"meta":40,"style":40},"try {\n    \u002F\u002F ...\n} catch (InputMismatchException e) {\n    \u002F\u002F ...\n} catch (ArithmeticException e) {\n    \u002F\u002F ...\n} catch (Exception e) {\n    System.err.println(\"出现了没有预料到的异常\");\n} finally {\n    scanner.close();\n}\n",[30,6252,6253,6259,6264,6276,6280,6292,6296,6309,6322,6330,6340],{"__ignoreMap":40},[44,6254,6255,6257],{"class":46,"line":47},[44,6256,6025],{"class":50},[44,6258,606],{"class":54},[44,6260,6261],{"class":46,"line":68},[44,6262,6263],{"class":79},"    \u002F\u002F ...\n",[44,6265,6266,6268,6270,6272,6274],{"class":46,"line":83},[44,6267,6071],{"class":54},[44,6269,6074],{"class":50},[44,6271,6077],{"class":54},[44,6273,6005],{"class":845},[44,6275,848],{"class":54},[44,6277,6278],{"class":46,"line":97},[44,6279,6263],{"class":79},[44,6281,6282,6284,6286,6288,6290],{"class":46,"line":474},[44,6283,6071],{"class":54},[44,6285,6074],{"class":50},[44,6287,6104],{"class":54},[44,6289,6005],{"class":845},[44,6291,848],{"class":54},[44,6293,6294],{"class":46,"line":492},[44,6295,6263],{"class":79},[44,6297,6298,6300,6302,6305,6307],{"class":46,"line":669},[44,6299,6071],{"class":54},[44,6301,6074],{"class":50},[44,6303,6304],{"class":54}," (Exception ",[44,6306,6005],{"class":845},[44,6308,848],{"class":54},[44,6310,6311,6313,6315,6317,6320],{"class":46,"line":684},[44,6312,6086],{"class":54},[44,6314,394],{"class":108},[44,6316,309],{"class":54},[44,6318,6319],{"class":91},"\"出现了没有预料到的异常\"",[44,6321,320],{"class":54},[44,6323,6324,6326,6328],{"class":46,"line":703},[44,6325,6071],{"class":54},[44,6327,6212],{"class":50},[44,6329,606],{"class":54},[44,6331,6332,6335,6338],{"class":46,"line":720},[44,6333,6334],{"class":54},"    scanner.",[44,6336,6337],{"class":108},"close",[44,6339,386],{"class":54},[44,6341,6342],{"class":46,"line":737},[44,6343,763],{"class":54},[116,6345,6347],{"id":6346},"_570-exception-类","5.7.0 Exception 类",[521,6349,6350,6361],{},[524,6351,6352,6353,6356,6357,6360],{},"构造器：",[30,6354,6355],{},"Exception()"," 无额外信息；",[30,6358,6359],{},"Exception(String message)"," 指定详细消息。",[524,6362,6363,6364,6367,6368,6371],{},"方法：",[30,6365,6366],{},"getMessage()"," 获取详细消息字符串；",[30,6369,6370],{},"printStackTrace()"," 打印 throwable 及其 backtrace 到标准错误流。",[35,6373,6375],{"className":37,"code":6374,"language":39,"meta":40,"style":40},"catch (Exception e) {\n    System.err.println(e.getMessage());\n    e.printStackTrace();\n}\n",[30,6376,6377,6387,6401,6411],{"__ignoreMap":40},[44,6378,6379,6381,6383,6385],{"class":46,"line":47},[44,6380,6074],{"class":50},[44,6382,6304],{"class":54},[44,6384,6005],{"class":845},[44,6386,848],{"class":54},[44,6388,6389,6391,6393,6396,6399],{"class":46,"line":68},[44,6390,6086],{"class":54},[44,6392,394],{"class":108},[44,6394,6395],{"class":54},"(e.",[44,6397,6398],{"class":108},"getMessage",[44,6400,403],{"class":54},[44,6402,6403,6406,6409],{"class":46,"line":83},[44,6404,6405],{"class":54},"    e.",[44,6407,6408],{"class":108},"printStackTrace",[44,6410,386],{"class":54},[44,6412,6413],{"class":46,"line":97},[44,6414,763],{"class":54},[22,6416,6418],{"id":6417},"_58-自定义异常","5.8 自定义异常",[521,6420,6421,6424,6430,6436],{},[524,6422,6423],{},"可通过继承 Exception 或其子类创建自己的异常类。",[524,6425,6426,6427,6429],{},"通常实现一两个构造器，调用 ",[30,6428,2973],{}," 初始化异常信息。",[524,6431,6432,6433,33],{},"Checked exception（受检异常）：继承 Exception，方法若不处理必须声明 ",[30,6434,6435],{},"throws",[524,6437,6438,6439,33],{},"Unchecked exception（非受检异常）：继承 RuntimeException，方法若不处理无需声明 ",[30,6440,6435],{},[35,6442,6444],{"className":37,"code":6443,"language":39,"meta":40,"style":40},"class BookingException extends Exception {\n    public BookingException() { super(); }\n    public BookingException(String message) { super(message); }\n}\n\npublic static String pickSeat(String[] seats, int index) throws BookingException {\n    if (index \u003C 0 || index >= seats.length) {\n        throw new BookingException(\"座位号超出范围：\" + index);\n    }\n    return seats[index];\n}\n",[30,6445,6446,6460,6473,6491,6495,6499,6522,6545,6564,6568,6575],{"__ignoreMap":40},[44,6447,6448,6450,6453,6455,6458],{"class":46,"line":47},[44,6449,3620],{"class":50},[44,6451,6452],{"class":108}," BookingException",[44,6454,2877],{"class":50},[44,6456,6457],{"class":108}," Exception",[44,6459,606],{"class":54},[44,6461,6462,6464,6466,6468,6470],{"class":46,"line":68},[44,6463,672],{"class":50},[44,6465,6452],{"class":108},[44,6467,2645],{"class":54},[44,6469,2966],{"class":61},[44,6471,6472],{"class":54},"(); }\n",[44,6474,6475,6477,6479,6481,6484,6486,6488],{"class":46,"line":83},[44,6476,672],{"class":50},[44,6478,6452],{"class":108},[44,6480,1091],{"class":54},[44,6482,6483],{"class":845},"message",[44,6485,5441],{"class":54},[44,6487,2966],{"class":61},[44,6489,6490],{"class":54},"(message); }\n",[44,6492,6493],{"class":46,"line":97},[44,6494,763],{"class":54},[44,6496,6497],{"class":46,"line":474},[44,6498,666],{"emptyLinePlaceholder":665},[44,6500,6501,6503,6505,6507,6510,6512,6514,6517,6519],{"class":46,"line":492},[44,6502,598],{"class":50},[44,6504,830],{"class":50},[44,6506,2238],{"class":54},[44,6508,6509],{"class":108},"pickSeat",[44,6511,309],{"class":54},[44,6513,189],{"class":50},[44,6515,6516],{"class":54},"[] seats, ",[44,6518,51],{"class":50},[44,6520,6521],{"class":54}," index) throws BookingException {\n",[44,6523,6524,6526,6529,6531,6533,6536,6539,6542],{"class":46,"line":669},[44,6525,5298],{"class":50},[44,6527,6528],{"class":54}," (index ",[44,6530,4814],{"class":50},[44,6532,2748],{"class":61},[44,6534,6535],{"class":50}," ||",[44,6537,6538],{"class":54}," index ",[44,6540,6541],{"class":50},">=",[44,6543,6544],{"class":54}," seats.length) {\n",[44,6546,6547,6550,6552,6554,6556,6559,6561],{"class":46,"line":684},[44,6548,6549],{"class":50},"        throw",[44,6551,303],{"class":50},[44,6553,6452],{"class":108},[44,6555,309],{"class":54},[44,6557,6558],{"class":91},"\"座位号超出范围：\"",[44,6560,697],{"class":50},[44,6562,6563],{"class":54}," index);\n",[44,6565,6566],{"class":46,"line":703},[44,6567,757],{"class":54},[44,6569,6570,6572],{"class":46,"line":720},[44,6571,5337],{"class":50},[44,6573,6574],{"class":54}," seats[index];\n",[44,6576,6577],{"class":46,"line":737},[44,6578,763],{"class":54},[521,6580,6581],{},[524,6582,6583],{},"非受检自定义异常：",[35,6585,6587],{"className":37,"code":6586,"language":39,"meta":40,"style":40},"public class BookingException extends RuntimeException {\n    public BookingException() { super(); }\n    public BookingException(String message) { super(message); }\n}\n\npublic static String pickSeat(String[] seats, int index) {\n    if (index \u003C 0 || index >= seats.length) {\n        throw new BookingException(\"座位号超出范围：\" + index);\n    }\n    return seats[index];\n}\n",[30,6588,6589,6604,6616,6632,6636,6640,6661,6679,6695,6699,6705],{"__ignoreMap":40},[44,6590,6591,6593,6595,6597,6599,6602],{"class":46,"line":47},[44,6592,598],{"class":50},[44,6594,601],{"class":50},[44,6596,6452],{"class":108},[44,6598,2877],{"class":50},[44,6600,6601],{"class":108}," RuntimeException",[44,6603,606],{"class":54},[44,6605,6606,6608,6610,6612,6614],{"class":46,"line":68},[44,6607,672],{"class":50},[44,6609,6452],{"class":108},[44,6611,2645],{"class":54},[44,6613,2966],{"class":61},[44,6615,6472],{"class":54},[44,6617,6618,6620,6622,6624,6626,6628,6630],{"class":46,"line":83},[44,6619,672],{"class":50},[44,6621,6452],{"class":108},[44,6623,1091],{"class":54},[44,6625,6483],{"class":845},[44,6627,5441],{"class":54},[44,6629,2966],{"class":61},[44,6631,6490],{"class":54},[44,6633,6634],{"class":46,"line":97},[44,6635,763],{"class":54},[44,6637,6638],{"class":46,"line":474},[44,6639,666],{"emptyLinePlaceholder":665},[44,6641,6642,6644,6646,6648,6650,6652,6654,6656,6658],{"class":46,"line":492},[44,6643,598],{"class":50},[44,6645,830],{"class":50},[44,6647,2238],{"class":54},[44,6649,6509],{"class":108},[44,6651,309],{"class":54},[44,6653,189],{"class":50},[44,6655,6516],{"class":54},[44,6657,51],{"class":50},[44,6659,6660],{"class":54}," index) {\n",[44,6662,6663,6665,6667,6669,6671,6673,6675,6677],{"class":46,"line":669},[44,6664,5298],{"class":50},[44,6666,6528],{"class":54},[44,6668,4814],{"class":50},[44,6670,2748],{"class":61},[44,6672,6535],{"class":50},[44,6674,6538],{"class":54},[44,6676,6541],{"class":50},[44,6678,6544],{"class":54},[44,6680,6681,6683,6685,6687,6689,6691,6693],{"class":46,"line":684},[44,6682,6549],{"class":50},[44,6684,303],{"class":50},[44,6686,6452],{"class":108},[44,6688,309],{"class":54},[44,6690,6558],{"class":91},[44,6692,697],{"class":50},[44,6694,6563],{"class":54},[44,6696,6697],{"class":46,"line":703},[44,6698,757],{"class":54},[44,6700,6701,6703],{"class":46,"line":720},[44,6702,5337],{"class":50},[44,6704,6574],{"class":54},[44,6706,6707],{"class":46,"line":737},[44,6708,763],{"class":54},[22,6710,6712],{"id":6711},"_59-异常的传播propagation","5.9 异常的传播（Propagation）",[521,6714,6715,6718,6721],{},[524,6716,6717],{},"若方法不捕获抛出的异常，异常传播到调用方法。",[524,6719,6720],{},"传播持续直到异常被捕获，或到达最外层由默认异常处理器处理。",[524,6722,6723],{},"好处：分离错误识别\u002F报告与对错误的反应，可能在不同类中。错误在一处识别，异常处理器在另一处，通过抛出的异常对象链接。增加程序健壮性而不使代码逻辑复杂。",[35,6725,6727],{"className":37,"code":6726,"language":39,"meta":40,"style":40},"static void loadConfig() {\n    throw new RuntimeException(\"配置文件读取失败\");\n}\nstatic void startApp() {\n    loadConfig();\n}\npublic static void main(String[] args) {\n    try {\n        startApp();\n    } catch (RuntimeException e) {\n        System.out.println(e.getMessage());\n    }\n}\n",[30,6728,6729,6741,6757,6761,6772,6779,6783,6800,6807,6814,6828,6840,6844],{"__ignoreMap":40},[44,6730,6731,6734,6736,6739],{"class":46,"line":47},[44,6732,6733],{"class":50},"static",[44,6735,675],{"class":50},[44,6737,6738],{"class":108}," loadConfig",[44,6740,681],{"class":54},[44,6742,6743,6746,6748,6750,6752,6755],{"class":46,"line":68},[44,6744,6745],{"class":50},"    throw",[44,6747,303],{"class":50},[44,6749,6601],{"class":108},[44,6751,309],{"class":54},[44,6753,6754],{"class":91},"\"配置文件读取失败\"",[44,6756,320],{"class":54},[44,6758,6759],{"class":46,"line":83},[44,6760,763],{"class":54},[44,6762,6763,6765,6767,6770],{"class":46,"line":97},[44,6764,6733],{"class":50},[44,6766,675],{"class":50},[44,6768,6769],{"class":108}," startApp",[44,6771,681],{"class":54},[44,6773,6774,6777],{"class":46,"line":474},[44,6775,6776],{"class":108},"    loadConfig",[44,6778,386],{"class":54},[44,6780,6781],{"class":46,"line":492},[44,6782,763],{"class":54},[44,6784,6785,6787,6789,6791,6793,6795,6797],{"class":46,"line":669},[44,6786,598],{"class":50},[44,6788,830],{"class":50},[44,6790,675],{"class":50},[44,6792,835],{"class":108},[44,6794,309],{"class":54},[44,6796,189],{"class":50},[44,6798,6799],{"class":54},"[] args) {\n",[44,6801,6802,6805],{"class":46,"line":684},[44,6803,6804],{"class":50},"    try",[44,6806,606],{"class":54},[44,6808,6809,6812],{"class":46,"line":703},[44,6810,6811],{"class":108},"        startApp",[44,6813,386],{"class":54},[44,6815,6816,6819,6821,6824,6826],{"class":46,"line":720},[44,6817,6818],{"class":54},"    } ",[44,6820,6074],{"class":50},[44,6822,6823],{"class":54}," (RuntimeException ",[44,6825,6005],{"class":845},[44,6827,848],{"class":54},[44,6829,6830,6832,6834,6836,6838],{"class":46,"line":737},[44,6831,687],{"class":54},[44,6833,394],{"class":108},[44,6835,6395],{"class":54},[44,6837,6398],{"class":108},[44,6839,403],{"class":54},[44,6841,6842],{"class":46,"line":754},[44,6843,757],{"class":54},[44,6845,6846],{"class":46,"line":760},[44,6847,763],{"class":54},[510,6849],{},[6851,6852,6853],"style",{},"html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s4XuR, html code.shiki .s4XuR{--shiki-default:#E36209;--shiki-dark:#FFAB70}",{"title":40,"searchDepth":83,"depth":83,"links":6855},[6856,6860,6864,6865,6866,6867,6868,6869,6870,6871,6872,6873,6874,6875,6876,6877,6882,6883,6884,6885,6886,6887,6888,6889,6890,6894,6900,6901,6902,6903,6904,6905,6906,6907,6908,6912,6915,6916],{"id":24,"depth":68,"text":25,"children":6857},[6858,6859],{"id":118,"depth":83,"text":119},{"id":182,"depth":83,"text":183},{"id":222,"depth":68,"text":223,"children":6861},[6862,6863],{"id":226,"depth":83,"text":227},{"id":282,"depth":83,"text":283},{"id":359,"depth":68,"text":360},{"id":406,"depth":68,"text":407},{"id":518,"depth":68,"text":519},{"id":538,"depth":68,"text":539},{"id":766,"depth":68,"text":767},{"id":872,"depth":68,"text":873},{"id":958,"depth":68,"text":959},{"id":1016,"depth":68,"text":1017},{"id":1428,"depth":68,"text":1429},{"id":1646,"depth":68,"text":1647},{"id":1826,"depth":68,"text":1827},{"id":1971,"depth":68,"text":1972},{"id":2109,"depth":68,"text":2110},{"id":2570,"depth":68,"text":2571,"children":6878},[6879,6880,6881],{"id":2593,"depth":83,"text":2594},{"id":2668,"depth":83,"text":2669},{"id":2786,"depth":83,"text":2787},{"id":2912,"depth":68,"text":2913},{"id":2950,"depth":68,"text":2951},{"id":3123,"depth":68,"text":3124},{"id":3594,"depth":68,"text":3595},{"id":3686,"depth":68,"text":3687},{"id":3922,"depth":68,"text":3923},{"id":3946,"depth":68,"text":3947},{"id":4059,"depth":68,"text":4060},{"id":4165,"depth":68,"text":4166,"children":6891},[6892,6893],{"id":4183,"depth":83,"text":4184},{"id":4310,"depth":83,"text":4311},{"id":4399,"depth":68,"text":4400,"children":6895},[6896,6897,6898,6899],{"id":4411,"depth":83,"text":4412},{"id":4471,"depth":83,"text":4472},{"id":4621,"depth":83,"text":4622},{"id":5018,"depth":83,"text":5019},{"id":5145,"depth":68,"text":5146},{"id":5355,"depth":68,"text":5356},{"id":5543,"depth":68,"text":5544},{"id":5561,"depth":68,"text":5562},{"id":5690,"depth":68,"text":5691},{"id":5796,"depth":68,"text":5797},{"id":5895,"depth":68,"text":5896},{"id":5918,"depth":68,"text":5919},{"id":5967,"depth":68,"text":5968,"children":6909},[6910,6911],{"id":5990,"depth":83,"text":5991},{"id":6128,"depth":83,"text":6129},{"id":6226,"depth":68,"text":6227,"children":6913},[6914],{"id":6346,"depth":83,"text":6347},{"id":6417,"depth":68,"text":6418},{"id":6711,"depth":68,"text":6712},"学习",null,"2026-10-06","学习 Java 面向对象编程时的个人笔记：类与对象、封装与访问修饰符、继承与多态、集合、抽象类与接口、异常处理。示例代码均为自写，运行结果来自本地实测。","md",false,{},"\u002Fposts\u002Fjava\u002Fjava-oop-notes",{"title":5,"description":6920},"Java 学习笔记","posts\u002Fjava\u002Fjava-oop-notes",[6929,6930,6931],"Java","面向对象","学习笔记","IGVxpM9Jjb9GBDwsGu_0GuC4iD5TnV6-L2UYHp7Rk_g",[6934,6940,6945,6950,6955,6960,6965,6970,6975,6980,6985,6990,6995,7000,7005,7010,7015,7020,7025,7030,7035,7040,7045,7050,7055,7060,7065,7070,7075,7081,7085,7089,7093,7097,7101,7105,7109,7113,7117,7121,7125,7130,7134,7140,7144,7148,7152,7156,7160,7164,7168,7173,7177,7181,7182,7187,7193,7197,7202,7206],{"path":6935,"title":6936,"description":6937,"date":6938,"series":6939,"seriesOrder":3422},"\u002Fposts\u002Fswdesign\u002Fsw-design-notes-28","软件分析与设计笔记 28：draw.io 作图手册：五张图的符号位置、落笔顺序与自检","不模拟软件界面，只讲清三件事：每个 UML 符号在 draw.io 里搜什么词、一张图该按什么顺序落笔、画完拿什么标准自查。覆盖用例图、活动图、顺序图、类图、界面草图五种图纸，末尾附「最容易画反的十二笔」总检表。","2026-11-19","软件分析与设计笔记",{"path":6941,"title":6942,"description":6943,"date":6944,"series":6939,"seriesOrder":2373},"\u002Fposts\u002Fswdesign\u002Fsw-design-notes-27","软件分析与设计笔记 27：Paper 1 应试：从读案例到交卷的一次完整演算","拿一份完整的案例，从头到尾走一遍：怎么读案例列角色、怎么在四个小问之间分配时间、每一张图从哪一句话推出来、两张表怎么填、交卷前拿什么清单自查。附 C25 真题与样卷的题型分值对照。","2026-11-18",{"path":6946,"title":6947,"description":6948,"date":6949,"series":6939,"seriesOrder":2368},"\u002Fposts\u002Fswdesign\u002Fsw-design-notes-26","软件分析与设计笔记 26：总结：把整条链路串起来","系列收尾：从需求到代码的完整链路回顾、每一环的产出与验收方式、六条贯穿全系列的原则，以及一份可以直接拿去做项目自查的清单。","2026-11-17",{"path":6951,"title":6952,"description":6953,"date":6954,"series":6939,"seriesOrder":2357},"\u002Fposts\u002Fswdesign\u002Fsw-design-notes-25","软件分析与设计笔记 25：代码重构：坏味道与手法","重构不改变外部行为、只改善内部结构：四种常见坏味道与对应手法、为什么动手之前必须先有测试、什么时候该重构，以及重构和前面那些设计模型是什么关系。","2026-11-16",{"path":6956,"title":6957,"description":6958,"date":6959,"series":6939,"seriesOrder":2346},"\u002Fposts\u002Fswdesign\u002Fsw-design-notes-24","软件分析与设计笔记 24：设计原则：内聚、耦合与多态","好设计怎么衡量：内聚与耦合分别在说什么、一次从「差设计」到「多态重设计」的完整对照、抽象类与接口的选择依据，以及复用为什么会从优势变成风险。","2026-11-15",{"path":6961,"title":6962,"description":6963,"date":6964,"series":6939,"seriesOrder":2334},"\u002Fposts\u002Fswdesign\u002Fsw-design-notes-23","软件分析与设计笔记 23：设计建模：从对象模型到能实现的方案","分析模型能用但还不能直接开工：对象模型怎么映射到关系模型、继承映射的三种方案怎么选、数据访问层与 Data Broker 解决什么问题，以及三层架构与 MVC 的分工。","2026-11-14",{"path":6966,"title":6967,"description":6968,"date":6969,"series":6939,"seriesOrder":2329},"\u002Fposts\u002Fswdesign\u002Fsw-design-notes-22","软件分析与设计笔记 22：分析建模：边界、实体与控制对象","不经过分析直接写代码会踩什么坑、三种分析对象各管一段、怎么用顺序图完成一次用例实现，以及从顺序图导出类的属性、操作与关系的方法。","2026-11-13",{"path":6971,"title":6972,"description":6973,"date":6974,"series":6939,"seriesOrder":1641},"\u002Fposts\u002Fswdesign\u002Fsw-design-notes-21","软件分析与设计笔记 21：UML：类图与顺序图","为什么需要一种共同的画法：类符号三格怎么画、五种关系的符号与设计含义、每种关系落到 Java 是什么写法，顺序图的三要素怎么摆；以及这三种最容易找不到的符号在 draw.io 里各搜什么词。","2026-11-12",{"path":6976,"title":6977,"description":6978,"date":6979,"series":6939,"seriesOrder":1248},"\u002Fposts\u002Fswdesign\u002Fsw-design-notes-20","软件分析与设计笔记 20：面向对象概念：对象、关系与多态","面向对象不是「用某个语言写代码」：对象与类的区别、封装真正在保护什么、五种关系（依赖、关联、聚合、组合、继承）各自何时用，以及多态为什么能减少条件判断。","2026-11-11",{"path":6981,"title":6982,"description":6983,"date":6984,"series":6939,"seriesOrder":1243},"\u002Fposts\u002Fswdesign\u002Fsw-design-notes-19","软件分析与设计笔记 19：规范化与逻辑数据模型","一次改地址引发的数据不一致，讲清规范化的真正动机；UNF 到 3NF 每一步在解决什么问题，派生字段为什么不能存，优化为什么和规范化方向相反，以及逻辑数据模型在 3NF 之上补了什么。","2026-11-10",{"path":6986,"title":6987,"description":6988,"date":6989,"series":6939,"seriesOrder":1228},"\u002Fposts\u002Fswdesign\u002Fsw-design-notes-18","软件分析与设计笔记 18：数据库分析：实体、关系与数据字典","为什么不能拿到需求就动手建表：实体与关系怎么判定、基数为什么必须由业务方确认、数据命名要遵守什么规则，以及数据字典四列里最容易被空着的那一列。","2026-11-09",{"path":6991,"title":6992,"description":6993,"date":6994,"series":6939,"seriesOrder":1213},"\u002Fposts\u002Fswdesign\u002Fsw-design-notes-17","软件分析与设计笔记 17：用生成式 AI 做设计与开发：能用的场景与要防的坑","生成式 AI 在工作流里真正站得住的三个场景 —— 造示例数据、解释陌生代码、起草初稿；它为什么会复现社会偏见、为什么会编得像真的，以及哪些内容绝不能直接采用。","2026-11-08",{"path":6996,"title":6997,"description":6998,"date":6999,"series":6939,"seriesOrder":1198},"\u002Fposts\u002Fswdesign\u002Fsw-design-notes-16","软件分析与设计笔记 16：从 persona 到 URS：一份交付物的完整骨架","把前面十几篇串成一份能交出去的东西：用户需求规格说明书的九个部分、每一章来自哪个环节、由谁确认，以及面向决策者的提案该讲清哪三件事。","2026-11-07",{"path":7001,"title":7002,"description":7003,"date":7004,"series":6939,"seriesOrder":1183},"\u002Fposts\u002Fswdesign\u002Fsw-design-notes-15","软件分析与设计笔记 15：非功能需求：把「快、稳、安全」变成数字","为什么「系统要快」不是一条需求：非功能需求怎么量化，决定性能的用户量、交易量、数据量三张表怎么估，安全需求要写清什么，以及可靠性的「不可用」该怎么定义。","2026-11-06",{"path":7006,"title":7007,"description":7008,"date":7009,"series":6939,"seriesOrder":1172},"\u002Fposts\u002Fswdesign\u002Fsw-design-notes-14","软件分析与设计笔记 14：软件测试：层级、方法与等价类划分","「我们测过了」这句话问题在哪：为什么静态评审和动态测试缺一不可，五个测试层级各自验证什么，白盒与黑盒的差别，以及用等价类划分和边界值把无限输入变成有限用例的方法。","2026-11-05",{"path":7011,"title":7012,"description":7013,"date":7014,"series":6939,"seriesOrder":760},"\u002Fposts\u002Fswdesign\u002Fsw-design-notes-13","软件分析与设计笔记 13：需求获取：五种调查方法与一场访谈","需求从哪里来：五种事实调查方法各自适合回答什么、代价是什么，访谈从准备到记录的全过程，问卷设计里最容易犯的错，以及访谈记录必须写下来的那几项信息。","2026-11-04",{"path":7016,"title":7017,"description":7018,"date":7019,"series":6939,"seriesOrder":754},"\u002Fposts\u002Fswdesign\u002Fsw-design-notes-12","软件分析与设计笔记 12：前端设计：把流程变成屏幕","界面设计不是「画得好看」：从活动图走到屏幕的三步，CRUD 任务流怎么当检查表，界面必须回答的三个问题，信息架构与五种导航类型，视觉一致性与留白，以及移动端与 Web 端的差别。","2026-11-03",{"path":7021,"title":7022,"description":7023,"date":7024,"series":6939,"seriesOrder":737},"\u002Fposts\u002Fswdesign\u002Fsw-design-notes-11","软件分析与设计笔记 11：Agentic AI 与业务流程自动化","AI agent 到底是什么：五项能力与四个核心组件，什么场景该用定时任务、什么该用程序、什么才值得用 agent，两种实现路径的差别，必须提前防住的四类失败模式，以及设计方法从提示词到编排的演进。","2026-11-02",{"path":7026,"title":7027,"description":7028,"date":7029,"series":6939,"seriesOrder":720},"\u002Fposts\u002Fswdesign\u002Fsw-design-notes-10","软件分析与设计笔记 10：精炼用例模型：include、extend 与泛化","三种精炼用例关系的判断标准：include 什么时候用、它和 extend 的区别到底在哪、参与者泛化与用例泛化各解决什么问题，以及精炼到什么程度就该停手。","2026-11-01",{"path":7031,"title":7032,"description":7033,"date":7034,"series":6939,"seriesOrder":703},"\u002Fposts\u002Fswdesign\u002Fsw-design-notes-09","软件分析与设计笔记 09：功能需求（二）：从流程到业务实体","活动图画完之后，怎么从流程里筛出真正的业务实体：三条判断标准、哪些名词其实不该建实体、属性从哪里来，以及领域模型和后面的数据模型分别负责什么。","2026-10-31",{"path":7036,"title":7037,"description":7038,"date":7039,"series":6939,"seriesOrder":684},"\u002Fposts\u002Fswdesign\u002Fsw-design-notes-08","软件分析与设计笔记 08：功能需求（一）：用例模型与活动图","从用户故事到用例的翻译过程：什么才算「好」的参与者，系统边界怎么划，用例描述必须写清哪四件事，活动图怎么把分支、并行与泳道画清楚，以及这两个图在 draw.io 里各用哪个形状、最容易画错哪一笔。","2026-10-30",{"path":7041,"title":7042,"description":7043,"date":7044,"series":6939,"seriesOrder":669},"\u002Fposts\u002Fswdesign\u002Fsw-design-notes-07","软件分析与设计笔记 07：用户故事：把需求写成可验收的一句话","用户故事的三段结构，怎么从用户画像和数据地图里把它提取出来，一条故事多大算合适、时序为什么也是需求的一部分，以及验收标准怎么写才算真的可验收。","2026-10-29",{"path":7046,"title":7047,"description":7048,"date":7049,"series":6939,"seriesOrder":492},"\u002Fposts\u002Fswdesign\u002Fsw-design-notes-06","软件分析与设计笔记 06：范围界定（数据侧）：用数据校验你的判断","访谈结论和数字对不上时该怎么办：分析的四个层次分别在回答什么问题、为什么不能跳级、数据准备与搜集怎么做成一张应用地图，以及数据最容易在哪几个地方骗你。","2026-10-28",{"path":7051,"title":7052,"description":7053,"date":7054,"series":6939,"seriesOrder":474},"\u002Fposts\u002Fswdesign\u002Fsw-design-notes-05","软件分析与设计笔记 05：范围界定（用户侧）：用户画像与客户旅程图","为什么「所有用户」是一个陷阱，项目边界该怎么划，用户画像要写哪五个要素、最容易写成什么废纸，客户旅程图怎么把阶段、想法和情绪画在同一张纸上，以及怎么从这两样东西一步步推到可验证的需求。","2026-10-27",{"path":7056,"title":7057,"description":7058,"date":7059,"series":6939,"seriesOrder":97},"\u002Fposts\u002Fswdesign\u002Fsw-design-notes-04","软件分析与设计笔记 04：接手陌生案例的第一步：三问与一张表","拿到一个完全陌生的业务案例，怎么从零开始不跑偏：只问 Who、What、Why 三个问题，把「问题—事实—假设—理由」记成一张四列表，说清为什么假设必须写明理由，以及带着问题进访谈为什么比空手去有效得多。","2026-10-26",{"path":7061,"title":7062,"description":7063,"date":7064,"series":6939,"seriesOrder":83},"\u002Fposts\u002Fswdesign\u002Fsw-design-notes-03","软件分析与设计笔记 03：Agile 与 Scrum：迭代、角色与产出物","从「三周做完交付，客户说这不是我要的」讲起，说清瀑布式与迭代式的根本差别，Scrum 的三个角色和三种产出物，一个 sprint 里四次固定活动各自在解决什么问题，以及敏捷里最常见的几个误解。","2026-10-25",{"path":7066,"title":7067,"description":7068,"date":7069,"series":6939,"seriesOrder":68},"\u002Fposts\u002Fswdesign\u002Fsw-design-notes-02","软件分析与设计笔记 02：设计思维、用户驱动与数据驱动","从「客服要一个能一次看完所有排期的界面」这个翻车案例讲起，说清设计思维到底是什么、用户驱动与数据驱动各自能看见什么又看不见什么、为什么真正的落点是把两者合起来的 data-informed design，以及访谈中怎么问出有用的信息。","2026-10-24",{"path":7071,"title":7072,"description":7073,"date":7074,"series":6939,"seriesOrder":47},"\u002Fposts\u002Fswdesign\u002Fsw-design-notes-01","软件分析与设计笔记 01：课程地图与从需求到设计的主干","这一篇不写具体方法，先把整条链路铺开：软件分析与设计到底要解决什么问题，从需求到设计分成哪两段，中间有哪十几个环节，一份完整的交付物里应该有什么，以及后面 27 篇笔记怎么排、新人该按什么顺序读。","2026-10-23",{"path":7076,"title":7077,"description":7078,"date":7079,"series":7080,"seriesOrder":47},"\u002Fposts\u002Fjavaspring\u002Fspring-notes-01","Spring 学习笔记 01：IoC、依赖注入与第一个 Spring Boot 应用","从「手写 new 出来的三层结构」的痛点讲起，说清 IoC 容器、Bean 与依赖注入是怎么回事，再用 Maven 与 Spring Initializr 跑起第一个能返回 JSON 的应用。","2026-10-15","Spring 学习笔记",{"path":7082,"title":7083,"description":7084,"date":7079,"series":7080,"seriesOrder":68},"\u002Fposts\u002Fjavaspring\u002Fspring-notes-02","Spring 学习笔记 02：Spring Data JPA 基础——实体映射与 Repository","用 ORM 把类映射到表：@Entity、@Id、@GeneratedValue 怎么用，CrudRepository 三层接口怎么选，H2 与 MySQL 怎么配，以及 ddl-auto 到底该写哪个值。",{"path":7086,"title":7087,"description":7088,"date":7079,"series":7080,"seriesOrder":83},"\u002Fposts\u002Fjavaspring\u002Fspring-notes-03","Spring 学习笔记 03：JPA 查询——派生方法、JPQL 与分页排序","Repository 自带的方法只够按主键查，这篇讲三种自己造查询的方式：方法名派生、@Query 写 JPQL、原生 SQL，以及 Pageable 分页排序和投影返回。",{"path":7090,"title":7091,"description":7092,"date":7079,"series":7080,"seriesOrder":97},"\u002Fposts\u002Fjavaspring\u002Fspring-notes-04","Spring 学习笔记 04：JPA 关联映射与仓储测试","一对多、多对多怎么映射，谁负责维护外键，FetchType 与 CascadeType 该怎么选，顺带用 @DataJpaTest 与 AssertJ 把仓储层测起来。",{"path":7094,"title":7095,"description":7096,"date":7079,"series":7080,"seriesOrder":474},"\u002Fposts\u002Fjavaspring\u002Fspring-notes-05","Spring 学习笔记 05：Spring MVC 与 Thymeleaf 入门","一次页面请求在 Spring MVC 里走了哪几步，@Controller 怎么把数据交给模板，@PathVariable 与 @RequestParam 怎么取参数，以及控制器为什么必须是无状态的。",{"path":7098,"title":7099,"description":7100,"date":7079,"series":7080,"seriesOrder":492},"\u002Fposts\u002Fjavaspring\u002Fspring-notes-06","Spring 学习笔记 06：表单绑定与服务端校验","把表单字段绑到对象上，用 Bean Validation 注解做服务端校验，把错误信息显示回用户刚填的那一页，再补上自定义校验注解与全局异常处理。",{"path":7102,"title":7103,"description":7104,"date":7079,"series":7080,"seriesOrder":669},"\u002Fposts\u002Fjavaspring\u002Fspring-notes-07","Spring 学习笔记 07：Thymeleaf 片段复用与国际化","用 th:fragment 与 th:insert\u002Fth:replace 把导航栏、页脚抽成片段，页面套用统一布局，再用 messages.properties 与 LocaleResolver 做中英文切换。",{"path":7106,"title":7107,"description":7108,"date":7079,"series":7080,"seriesOrder":684},"\u002Fposts\u002Fjavaspring\u002Fspring-notes-08","Spring 学习笔记 08：HTTP Session 与会话状态管理","HTTP 无状态带来的问题，Cookie 与 Session 怎么分工，Spring 里读写会话的几种方式，以及会话固定、超时、多实例共享这些必须想清楚的事。",{"path":7110,"title":7111,"description":7112,"date":7079,"series":7080,"seriesOrder":703},"\u002Fposts\u002Fjavaspring\u002Fspring-notes-09","Spring 学习笔记 09：拦截器 HandlerInterceptor","登录检查、权限判断、请求耗时统计这类横切逻辑该放哪：HandlerInterceptor 的三个回调各在什么时机执行，怎么注册与排除路径，以及它和过滤器的分工。",{"path":7114,"title":7115,"description":7116,"date":7079,"series":7080,"seriesOrder":720},"\u002Fposts\u002Fjavaspring\u002Fspring-notes-10","Spring 学习笔记 10：Service 层与事务","一组数据库操作要么全成功要么全失败，靠 @Transactional 怎么做到；传播行为、隔离级别、回滚规则怎么选，以及自调用失效、乐观锁悲观锁这些实战里的坑。",{"path":7118,"title":7119,"description":7120,"date":7079,"series":7080,"seriesOrder":737},"\u002Fposts\u002Fjavaspring\u002Fspring-notes-11","Spring 学习笔记 11：REST API 基础——把 Service 暴露成接口","同一套 Service 怎么同时服务页面和客户端：@RestController 的路由与方法语义、状态码怎么给、DTO 怎么定，以及 MockMvc 端到端和切片测试的两种写法与各自的坑。",{"path":7122,"title":7123,"description":7124,"date":7079,"series":7080,"seriesOrder":754},"\u002Fposts\u002Fjavaspring\u002Fspring-notes-12","Spring 学习笔记 12：REST 进阶——版本、更新、跨域与文档化","接口能跑通之后要处理的几件事：URL 与响应结构怎么定、版本怎么演进、更新怎么做到可安全重试、CORS 怎么配、HATEOAS 与 Spring Data REST 该不该用。",{"path":7126,"title":7127,"description":7128,"date":7129,"series":6926,"seriesOrder":97},"\u002Fposts\u002Fjava\u002Fjava-functionalprogramming-notes","Java 函数式编程笔记：Lambda、函数式接口与 Streams","学习 Java 函数式编程时的个人笔记：Lambda 表达式的五步简写与方法引用、常见函数式接口、Stream 流水线与惰性求值，以及创建流、中间操作、终止操作与收集器的用法。示例代码均为自写，运行结果来自本地实测。","2026-10-13",{"path":7131,"title":7132,"description":7133,"date":7129,"series":6926,"seriesOrder":83},"\u002Fposts\u002Fjava\u002Fjava-generics-notes","Java 泛型笔记：泛型方法、有界类型与泛型类","学习 Java 泛型时的个人笔记：从重复的重载方法与多态尝试讲起，再到泛型方法与类型推断、有界泛型类型、Comparable 与 Number 边界，以及泛型类在集合中的用法。示例代码均为自写，运行结果来自本地实测。",{"path":7135,"title":7136,"description":7137,"date":7138,"series":7139,"seriesOrder":97},"\u002Fposts\u002Fmysql\u002Fmysql-learning-04","MySQL 学习笔记 04：数据操纵（增删改）","MySQL 学习笔记第四篇：INSERT 插入（含批量插入与 INSERT ... SELECT）、UPDATE 更新、DELETE 删除，以及各自的坑。","2026-10-10","SQL 学习笔记",{"path":7141,"title":7142,"description":7143,"date":7138,"series":7139,"seriesOrder":474},"\u002Fposts\u002Fmysql\u002Fmysql-learning-05","MySQL 学习笔记 05：DDL 概览","MySQL 学习笔记第五篇：数据定义语言概览——Schema、Table、View、Index、Constraints 这几类对象分别对应哪些 CREATE \u002F ALTER \u002F DROP 命令。",{"path":7145,"title":7146,"description":7147,"date":7138,"series":7139,"seriesOrder":492},"\u002Fposts\u002Fmysql\u002Fmysql-learning-06","MySQL 学习笔记 06：CREATE TABLE 与数据类型","MySQL 学习笔记第六篇：CREATE TABLE 的完整语法、常用数据类型的选型建议，以及外键的两种定义方式。",{"path":7149,"title":7150,"description":7151,"date":7138,"series":7139,"seriesOrder":669},"\u002Fposts\u002Fmysql\u002Fmysql-learning-07","MySQL 学习笔记 07：索引","MySQL 学习笔记第七篇：索引的作用与 B+ 树结构、单列与复合索引的创建、索引的代价与适用场景。",{"path":7153,"title":7154,"description":7155,"date":7138,"series":7139,"seriesOrder":684},"\u002Fposts\u002Fmysql\u002Fmysql-learning-08","MySQL 学习笔记 08：DROP 与 ALTER","MySQL 学习笔记第八篇：DROP 删除数据库对象、ALTER 修改表结构，以及常见的坑。",{"path":7157,"title":7158,"description":7159,"date":7138,"series":7139,"seriesOrder":703},"\u002Fposts\u002Fmysql\u002Fmysql-learning-09","MySQL 学习笔记 09：约束与数据完整性","MySQL 学习笔记第九篇：SQL 约束——NOT NULL、CHECK、PRIMARY KEY、FOREIGN KEY 等如何保证数据完整性，以及它们的对比。",{"path":7161,"title":7162,"description":7163,"date":7138,"series":7139,"seriesOrder":720},"\u002Fposts\u002Fmysql\u002Fmysql-learning-10","MySQL 学习笔记 10：视图","MySQL 学习笔记第十篇：视图（Views）的定义与特性、和表的对比、创建与使用，以及可更新视图的限制。",{"path":7165,"title":7166,"description":7167,"date":7138,"series":7139,"seriesOrder":737},"\u002Fposts\u002Fmysql\u002Fmysql-learning-11","MySQL 学习笔记 11：存储过程","MySQL 学习笔记第十一篇：存储过程（Stored Procedures）的概念、创建与调用、带参数的写法，以及优缺点。",{"path":7169,"title":7170,"description":7171,"date":7172,"series":7139,"seriesOrder":47},"\u002Fposts\u002Fmysql\u002Fmysql-learning-01","MySQL 学习笔记 01：MySQL 基础知识","MySQL 学习笔记第一篇：MySQL Server 与 Workbench 的安装，数据库与 DBMS 的基本概念，关系模型、ACID 事务、常见数据类型，以及后续的学习路线。","2026-10-09",{"path":7174,"title":7175,"description":7176,"date":7172,"series":7139,"seriesOrder":68},"\u002Fposts\u002Fmysql\u002Fmysql-learning-02","MySQL 学习笔记 02：SELECT 查询与过滤","MySQL 学习笔记第二篇：SELECT 的基本语法与逻辑执行顺序，WHERE 过滤（比较、LIKE、IN、BETWEEN、NULL）、各种 JOIN、UNION 与子查询。",{"path":7178,"title":7179,"description":7180,"date":7172,"series":7139,"seriesOrder":83},"\u002Fposts\u002Fmysql\u002Fmysql-learning-03","MySQL 学习笔记 03：聚合、分组与输出控制","MySQL 学习笔记第三篇：COUNT\u002FSUM\u002FAVG 等聚合函数、GROUP BY 分组、HAVING 过滤、ORDER BY 与 LIMIT，以及一条 SELECT 的完整逻辑执行顺序。",{"path":6924,"title":5,"description":6920,"date":6919,"series":6926,"seriesOrder":68},{"path":7183,"title":7184,"description":7185,"date":7186,"series":6926,"seriesOrder":47},"\u002Fposts\u002Fjava\u002Fjava-basics-notes","Java 基础语法笔记：从环境安装到方法与数组","学习 Java 基础语法时的个人笔记：JDK 安装、输入输出、变量与运算符、条件与循环、字符串、数组与方法。示例代码均为自写，运行结果来自本地实测。","2026-10-05",{"path":7188,"title":7189,"description":7190,"date":7191,"series":7192,"seriesOrder":47},"\u002Fposts\u002Fgit\u002Fgit-install-and-basics","Git 安装与基本使用","从装好 Git 到跑通日常提交流程，把最常用的几条命令和它们背后的三个区域讲清楚。","2026-10-04","Git 入门",{"path":7194,"title":7195,"description":7196,"date":7191,"series":7192,"seriesOrder":68},"\u002Fposts\u002Fgit\u002Flocal-remote-repository","本地远程仓库的部署","用自己的机器当 Git 服务器：建一个裸仓库、走 SSH 连上去，把本地提交推上去。",{"path":7198,"title":7199,"description":7200,"date":7191,"series":7201,"seriesOrder":47},"\u002Fposts\u002Fguide\u002Fguide-file-layout","文件都放在哪","文章、图片、封面分别放在仓库的什么位置，哪些目录可以放手改、哪些碰了会出问题。","博客使用指南",{"path":7203,"title":7204,"description":7205,"date":7191,"series":7201,"seriesOrder":68},"\u002Fposts\u002Fguide\u002Fguide-frontmatter","frontmatter 每个字段是什么意思","文章开头那段被横线包住的字段，逐个说明作用、默认行为和写错的后果。",{"path":7207,"title":7208,"description":7209,"date":7191,"series":7201,"seriesOrder":83},"\u002Fposts\u002Fguide\u002Fguide-markdown","正文怎么写 —— Markdown 与排版效果","标题、链接、图片、代码、表格分别怎么写，以及本站对它们做了哪些自定义处理。",1793268151875]