JavaSE_kuang
JavaSE——kuang——個人版
個人歸納,基于狂神筆記,視頻
多寫點
前言—預科—入門
Java:一個帝國的誕生
C語言帝國的統治
反抗
一鳴驚人
開拓疆土
帝國的誕生
Java的特征和優勢(重要)
Java三大版本
JDK,JRE,JVM
JDK
Java Development KIt 包括:JRE的超集,包含編譯器和調試器等用于程序開發的文件
JRE
Java Runtime Environment(JRE)包含:Java虛擬機、庫函數、運行Java應用程序和Applet所必須文件
JVM
Java VIrtual Machine 是一種規范,可以使用軟件來實現,也可以使用硬件來實現,就是一個虛擬的用于執行bytecodes字節碼的計算機。它也定義了指針集、寄存器集、結構棧、垃圾收集堆、內存區域。
Java的跨平臺實現的核心是不同平臺使用不同的虛擬機
Java開發環境搭建(新手來看)
百度搜索JDK,找到下載地址,瀏覽Oracle的網站。JDK下載地址
HelloWorld
環境安裝好了,測試代碼一定要寫一個HelloWorld!儀式感!!!
找個文件夾,存放即將要寫的代碼!!
新建文件 Hello.java
編寫我們的helloWorld程序!
public class Hello{public static void main(String[] args){System.out.println("Hello,world!!!");} }保存文件,打開命令行,利用javac編輯!
javac Hello.java // 如果沒有報錯,查看文件夾下是否有一個新的文件 // Hello。class // 如果沒有出現,恭喜!說明你遇到了你在學Java當中的第一個Bugjava 執行!
java Hello//成功輸出Hello,world!!!如果出現錯誤,檢查字母大小是否有錯誤,或者是否標點符號錯誤,文件名錯誤等等,一定要確定成功輸出,我們之后再來研究,它是怎么輸出的!
編寫Java程序時,應該注意一下幾點:
- 大小寫敏感:Java是大小寫敏感的,這就意味著標識符Hello與hello是不同的。
- 類名(大駝峰式):對于所有的類來說,類名的首字母應該大寫。如果類名由若干單詞組成,那么每個單詞的首字母都應該大寫,例如:MySwaggerConfig。
- 方法名(小駝峰式):所有的方法名都應該以小寫字母開頭。如果方法包含有若干單詞,則后面的每一個單詞首字母大寫。例如:getUserInfo。
- 源文件名:源文件名必須和類名相同。當保存文件的時候,你應該使用類名作為文件名保存(切記Java是大小寫敏感的),文件名的后綴為.java。(如果文件名和類名不相同則會導致編譯錯誤)。
- 主方法入口:所有Java程序由public static void main(String[] args){ }方法開始執行。
Java 程序運行機制
計算機的高級編譯語言類型:編譯型,解釋型。Java語言是兩種類型的結合;(以后在拓展,我自己都不是很理解;)
第一步:編譯
利用編譯器(javac)將源程序編譯成字節碼文件。字節碼文件名:源文件名.class
第二步:運行
利用虛擬機(解釋器,java)解釋執行 .class 字節碼文件
總結
- 暫時不想寫
源程序編譯成字節碼文件。字節碼文件名:源文件名.class
總結
- 暫時不想寫
安裝IDEA
IDEA 目前最好用的Java 智能開發工具,高效,簡單,好用。
網站官網:https://www.jetbrains.com/
目前IntelliJ IDEA有免費的社區版(功能相對較少),和收費的旗艦版(功能比較全面);
安裝步驟,網上太多了,大同小異,多卸載,多安裝幾次,自然熟練;
? 其他事項:
2-JavaSE:基礎語法
注釋
記筆記,沒啥好說的,用它(Ctrl + /)。
項目結構復雜時,看到亂七八糟的的全英文,頭疼,為了你的頭發多寫注釋吧,當你寫一個類時,注釋他是什么實體,一個屬性,什么屬性,一個方法,什么方法;以后你的代碼便是一目了然,好不痛快!
注釋不會別執行,是給我們寫代碼的人看的,書寫注釋是一個非常好的習慣,在很多大公司都是強制要求各位去進行編寫注釋!比如,我們的BAT三大巨頭等等。。。。
Java中的注釋有三種:
單行注釋:只能注釋當前行,以//開始,直到行結束
//輸出Hello,World!多行注釋:注釋一段文字,以 /* 開始,*/ 結束;
/*這是我們Java程序的主入口,main方法也是程序的主線程。 */文檔注釋:用于生產API文檔,配合JavaDoc。
// 注:文檔注釋現在只做了解,在學習JavaDoc時候我們會詳細給大家說,目前知道有這樣的注釋就好。
/*** 個人碼詳情* @param param* @return */【狂神建議】平時寫代碼,要注意注釋的規范性,一個好的程序員,一定是有非常良好的編程習慣的,希望大家能夠從小事開始鍛煉自己的行為習慣!
標識碼
每個人從出生開始就有一個名字,咱們生活中的所有事物也都有名字,這名字時誰規定的呢?回答是:造物主,誰生產出來的誰規定名字,在我們程序中也不例外。
我們作為造物主,需要給所有的東西給上一個名字,比如我們的HelloWorld程序:
Hello是類名,也是我們的文件名。他前面的public class是關鍵字,不過是搞Java那群人已經定義好的有特殊作用的, 下面的每一個代碼都有自己的意思和名字對吧,就是用來區分!和我們的名字一樣,拿來被叫或稱呼的,程序一切都源自于生活,一定要把學程序和生活中的一切聯系起來,你會發現這一切都是息息相關的。
我們來看看有哪些是Java自己定義好的關鍵字呢?(不能拿來作標識符)
Java 所有的組成部分都需要名字、類名、變量名以及方法名都被稱為標識符。
關于 Java 標識符,有以下幾點需要注意:
- 所有的標識符都應該以字母(A-Z 或者 a-z),美元符($)、或者下劃線(_)開始
- 首字母之后可以是字母(A-Z 或者 a-z),美元符($)、或者下劃線(_)或者數字的任何字符組合
- 不能使用關鍵字作為變量名或方法名
- 標識符是大小寫敏感的
- 合法標識符舉例:age、$salary、_value、 _1_value
- 非法標識符舉例:123abc、-salary、#abc
【可以使用中文命名,但是一般不建議這樣去用,也不建議使用拼音。。。】
數據類型
Java是一種強類型語言,每個變量都必須聲明其類型。
1 強弱類型語言
強類型語言也稱為強類型定義語言。要求變量的使用嚴格符合規定,所有變量都必須先定義后才能使用。
弱類型語言也稱為弱類型定義語言。與強類型定義相反。想VB,PHP等就屬于弱類型語言。
2數據類型
Java的數據類型分為兩大類:基本數據和引用數據類型【記住了,就這兩個類型,但他可以兜得你頭暈】
如果你頭暈的話,以下代碼能幫你快速上手,所有要敲代碼,記筆記,搜整歸納。
電腦32位和64位的區別?
32位操作系統只可以使用32位的cpu,而64位的CPU既可以安裝32位操作系統也可以安裝64位操作系統。尋址能力簡單點說就是支持的內存大小能力,64位系統最多可以支達128 GB的內存,而32位系統最 多只可以支持4G內存。 32位操作系統只可以安裝使用32位架構設計的軟件,而64位的CPU既可以安裝使用32位軟件也可以安裝使用64位軟件。現在的電腦都是64位了!回歸正題,自己定義一些變量試試!!!
//八大基本類型//整數 int num1 = 1000000; //最常用 4字節 byte num2 = 111; //-128--127 1字節 short num3 = 11111; //2字節 long num4 = 1111111L; //long類型要在數字后加L 8字節//小數:浮點數 float num5 = 1.111F; //float類型要在數字后加F 4字節 double num6 = 3.14159265358979; //8字節//字符 char aaa = 'a'; //注意單引號不是雙引號,2個字節 //String name = "李四"; //字符串String是類不是關鍵字//布爾型:是非 boolean flag = true; //1位System.out.println(flag);【Java語言的整型常數默認為int型,浮點數默認是Double】
3、整數拓展
在我們計算機中存在很多進制問題,十進制,八進制等等的問題,他們怎么表示呢?
十進制整數, 如 ——————99,-200.0; 八進制整數,要求以0開頭 如 ——————015; 十六進制整數,要求 0x 或 0X 開頭 如 ——————0X15演示代碼
//整數拓展 進制 二進制(0b開頭) 十進制 八進制(0開頭) 十六進制(0x開頭) int i1 = 0b10; int i2 = 010; int i3 = 0x10;System.out.println(i1); System.out.println(i2); System.out.println(i3);4、浮點型拓展
【金融面試問:銀行金融業務用什么類型表示?】
浮點類型flout,double的數據不適合在不容出錯的金融計算領域。
如果需要進行不產生舍入誤差的精確數字計算,需要使用BigDecimal類。
大數值:
- BigInteger實現了任意精度的整數運算
- BigDecimal實現了任意精度的浮點運算
浮點數使用總結:
5、字符型拓展
當引號用來表示字符常量。例如’A’是一個字符,"A"是一個字符串。
char類型用來表示在Unicode編碼表中的字符。
// 字符擴展 char c1='a'; char c2='中'; //我們通過單引號來表示字符常量 System.out.println(c1); System.out.println((int)c1); System.out.println(c2); System.out.println((int)c2); //強制轉換可以把字符轉換成數字,所有的字符本質還是數字 // Unicode 編碼表:97=a 65=A (本質上還是數字) // 2字節 65536字符 Excel最長有2的16次方=65536 //U0000 UFFFF char c3='\u0061'; System.out.println(c3);//a //轉義字符(轉義字符它有特殊的意思) // \t 制表符 // \n 換行 // 轉義字符有非常的多,可以自己去查詢一下System.out.println("Hello\tWorld"); System.out.println("Hello\nWorld"); System.out.println("===============================");【思考題】
String sa = new String("Hello World"); String sb=new String("Hello World"); System.out.println(sa==sb); //false 兩個對象是不同的 String sc = "Hello World"; String sd="Hello World"; System.out.println(sc==sd); //true 對象那可以了解 從內存分析內存級別分析
6、布爾型拓展
boolean類型(一位,不是一個字節)。就是0|1
//布爾值擴展 boolean flag=true; if (flag==true){} if (flag){} //老手 Less is More!類型轉換
由于Java是強類型語言,所以要進行有些運算的時候,需要用到類型轉換。
低-------------------------->高byte,short,char,int,long,float,Double數據類型轉換必須滿足如下規則:
-
不能對boolean類型進行類型轉換
-
不能把對象類型轉換成不相干類的對象
-
在把容量大的類型轉換為容量小的類型時必須使用強制類型轉換
-
轉換過程中可能導致溢出或損耗精度,例如:
int i = 128; byte b = (byte) i;//內存溢出 -128 -
浮點數到整數的轉換是通過舍棄小數得到的,而不是四舍五入。
1、自動類型轉換
自動類型轉換:容量小的數據類型可以自動轉換為容量大的數據類型。
2、強類型轉換
強制類型轉換,又被稱為造型,用于顯式的轉換一個數值的類型
(type)var,條件是轉換的數據類型必須是兼容的。
char c = 'a'; int i1 = c + 1; System.out.println(i1); System.out.println((char) i1);3、常見錯誤和問題+JDK7拓展
操作比較大的數時,需要留意是否溢出,尤其是整數操作時;
//操作比較大的數,注意溢出 //JDK7新特性,數字之間可以用下劃線分割 ——二進制整數以0b開頭即可 int money = 10_0000_0000; System.out.println(money); //1000000000(10 億) 不會輸出下劃線 int years = 20; int total = money*years; System.out.println(total); //-1474836480 ,計算時內存溢出 System.out.println("============================"); long total2 = money*years; //-1474836480 默認是int,轉換之前已經存在問題 long total3 = money*((long)years);//先將一個數轉換為long System.out.println(total2); //-1474836480 System.out.println(total3); //20000000000L和l的問題
- 不要命名名字為l的變量
- long類型使用大寫L而不是小寫。
變量,常量
1、變量(variable)
變量是什么,是可以變化的量!
Java是一種強類型語言,每一個變量都必須聲明其類型
Java變量是程序中最基本的存儲單元,其要素包括變量名,變量類型和作用域
變量聲明后,才能為其分配相應長度的存儲單元。格式為
注意事項
- 每個變量都有類型,類型可以是基本類型,也可以是引用類型。
- 變量名必須是合法的標識符。
- 變量聲明是一條完整的語句,因此沒一個聲明都必須以分號結束
2、變量作用域
變量根據作用域可劃分為三種:
- 類變量(靜態變量:static variable):獨立于方法之外的變量,用static修飾。
- 實例變量(成員變量:member variable):獨立于方法之外的變量,不過沒有static修飾。
- 局部變量(lacal variable):類的方法中的變量。
3、常量
常量(Constant):初始化(initializa)后不能再改變值!不會變動的值。finally
final 常量名 = 值; final double PI = 3.14;final String LOVE = "hello";常量名一般使用大寫字符。
4、變量的命名規范(規范需要遵守)
運算符(operator)
Java 語言支持如下運算符:
- 算術運算符:+,-,*,/,%,++,–,
- 賦值運算符:=
- 關系運算符:>,<,>=,<=,==,!=,instanceof
- 邏輯運算符:&&,||,!
- 位運算符:&,|,^,~,>>,<<,>>>(了解!!!)
- 條件運算符:? :
- 拓展賦值運算符:+=,-=,*=,/=
1、二元運算符
2、取模運算
3、一元運算符
**自增(++)自減(–)**運算符是一種特殊的算術運算符。
//++ -- 自增,自減 一元運算符 int a = 3; System.out.println(a); //先賦值后自增 3 int b = a++; System.out.println(a); //先自增后賦值 4 int c = ++a; System.out.println(a); //5 System.out.println(b); //3 System.out.println(c); //5 System.out.println("======================="); //冪運算 2^3 借助工具類Math,來操作 double pow = Math.pow(2, 3); System.out.println(pow);4、邏輯運算符(注意其中的短路方式)
5、位運算符
6、拓展運算符
7、字符串連接符
“+” 運算符兩側的操作數中**只要有一個是字符串(String)**類型,系統會自動把另外一個操作數轉換為字符串然后在進行連接。(字符串的拼接)
8、三目條件運算符
9、運算符優先級
public static void main(String[] args) {boolean flag = 1<4*5&&122>3||'q'+3<5;System.out.println(flag); //true }包機制
在Java中采用包機制處理開發者定義的類名沖突問題。、
包的作用:為了更好地組織類,Java提供了包機制,用于區別類名的命名空間。
1、包的作用
2、創建包
包聲明應該在源文件的第一行,每一個源文件只能有一個包聲明,這個文件的每個類型都應用于它。
一般利用公司域名倒置作為包名;com.baidu.www
3、import
為了能夠使用某一個包的成員,我們需要在Java 程序中明確導入該包。使用”import“語句可完成此功能。其語法格式為:
import package1[.package2...].(classname|*); import java.lang.System;JavaDoc
1、簡介
JavaDoc是一種將注解生成HTML文檔的技術,生成的HTML文檔類似于Java的API,易讀且清晰明了。
javadoc命令是用來生成自己API文檔的,使用方式:使用命令行在目標文件所在目錄輸入javadoc + 文件名.java.
先看一段樣例代碼
/*** @author Hua* @version 1.0* @since 1.8*/public class Doc {String name;/** 這是一個JavaDoc測試程序* @param name* @return* @throws Exception*/public String test(String name) throws Exception{return name;} }簡單介紹
- 以/* 開始,以/結束。
- @author —— 作者名
- @version —— 版本號
- @since —— 指明需要最早使用的jdk版本
- @param —— 參數名
- @return —— 返回值情況
- @throws —— 異常拋出情況
2、命令行生成Doc
javadoc -encoding UTF-8 -charset UTF-8 Doc.java回顧及總結
這一章,學習Java基礎。
- 安裝使用了IDEA
- 使用注釋
- 了解Java的關鍵字
- 數據類型
- 怎么定義一個變量
- 怎么操作這些變量
- 如何生成一篇完整的JavaDoc文檔
- 。。。
- 補充:規范書:阿里巴巴開發手冊
不積跬步,無以至千里;不積小流,無以成江海!
簡單的東西,更不能忽視,平日多學多練,高手和普通人的差距就是平日花的時間多。
3-JavaSE:流程控制
用戶交互Scanner
1、Scanner對象(需要記住)
java.util.Scanner是Java5 的新特征,我們可以通過Scanner 類來獲取用戶的輸入。基本語法:
Scanner s = new Scanner(System.in);2、 next & nextLine
//創建一個掃描器對象用于接收鍵盤輸入的數據 Scanner scanner = new Scanner(System.in); //Hello World! System.out.println("用next方法接收");//判斷用戶有沒有輸入字符串 if (scanner.hasNext()){//用next方式接收String str = scanner.next();//程序會等待用戶輸入完畢System.out.println("輸出內容:"+ str); } //String str = scanner.nextLine(); //System.out.println("輸入的數據為:"+str); //Hello World!//凡是I/O類使用完畢記得關閉以節約資源 scanner.close(); //創建一個掃描器對象用于接收鍵盤輸入的數據 Scanner scanner = new Scanner(System.in); //Hello World! System.out.println("用nextLine方法接收");//判斷用戶有沒有輸入字符串 if (scanner.hasNextLine()){//用next方式接收String str = scanner.nextLine();//程序會等待用戶輸入完畢System.out.println("輸出內容:"+ str); } //String str = scanner.nextLine(); //System.out.println("輸入的數據為:"+str); //Hello World!//凡是I/O類使用完畢記得關閉以節約資源 scanner.close();兩者區別
- next():
- 一定要讀取到有效字符后可以結束輸入
- 對輸入有效字符之前遇到的空白,next() 方法會自動將其去掉。
- 只有輸入有效字符后才將其后面輸入的空白作為分隔符或者結束符。
- next() 不能得到帶有空格的空字符串。
- nextLine():
- 以Enter為結束符,也就是說 nextLine() 方法返回的是輸入回車之前的所有字符。
- 可以獲得空白
3、其他方法
如果要輸入 int 或 float 類型的數據,在 Scanner 類中也有支持,但是在輸入之前最好先使用hasNextXxx() 方法進行驗證,在使用 nextXxx() 來讀取。
順序結構
JAVA的基本結構就是順序結構,除非特別指明,否則就按照順序一句一句執行。
順序結構是最簡單的算法結構。
選擇結構
1、if但選擇結構
if(布爾表達式){//如果布爾表達式為true將執行的語句 }2、if雙選擇結構
if(布爾表達式){//如果布爾表達式為true }else {//如果布爾表達式為false }3、if多選擇結構
if(布爾表達式 1){//如果布爾表達式 1為true }else if(布爾表達式 2){//如果布爾表達式 2為true }else if(布爾表達式 3){//如果布爾表達式 3為true }else {//如果以上布爾表達式都被為false }案例:(一個就夠了)
//考試分數大于60就是及格,小于60就不及格 Scanner scanner = new Scanner(System.in); System.out.println("請輸入成績:"); int score = scanner.nextInt();//equals:判斷字符串是否相等 if(score == 100) {System.out.println("恭喜滿分"); }else if (score < 100 && score >= 90){System.out.println("A級"); }else if (score < 90 && score >= 80){System.out.println("B級"); }else if (score < 80 && score >= 70){System.out.println("C級"); }else if (score < 70 && score >= 60){System.out.println("D級"); }else if (score < 60 && score >= 0){System.out.println("不及格!"); }else {System.out.println("成績輸入不合法!"); } System.out.println("End"); scanner.close();4、嵌套的if結構
使用嵌套的if…else 語句是合法的,(但要注意效率問題)
if(布爾表達式 1){//如果布爾表達式 1位true,if(布爾表達式 2){//如果布爾表達式 2位true,} }5、switch多選擇結構
多選擇結構還有一個實現方式就是switch case 語句。
switch(expression){case value://語句break; //可選case value://語句break; //可選default://可選//語句 }- default 在沒有case語句的值和變量值相等的時候執行,default分支不需要 break 語句。
- switch case 執行時,一定會先進行匹配,匹配成功返回當前 case 的值,再根據是否有break,判斷是否持續輸出,或是跳出判斷。
- 【case 穿透】
- 【JDK7增加了字符串表達式】
循環結構
三種循環結構
- while 循環
- do…while 循環
- for 循環
1、while 循環
while(布爾表達式){//循環體 }我們需要一個讓表達式失效的方式來結束循環。
- 循環內部控制
- 外部設立標志位
- …(待補充)
2、do…while 循環
do…while 循環和 while 循環相似,不同的是,do…while 循環至少會執行一次。
do {//循環體 }while(布爾表達式);3、For循環(用的最多了)(簡化代碼提高可讀性)
for循環語句是支持迭代的一種通用結構,是最有效、最靈活的循環結構。
for循環執行的次數是在執行前就確定的。語法格式:
for(初始化; 布爾表達式; 更新){//循環體 }關于for 循環有以下幾點說明:
- 最先執行初始化步驟??梢月暶饕环N類型,但可初始化一個或多個循環控制變量,也可以是空語句。
- 然后,檢測布爾表達式的值。如果為 true,循環體被執行。如果為false,循環終止,開始執行循環體后面的語句。
- 執行一次循環后,更新循環控制變量(迭代因子控制循環變量的增減)。
- 再次檢測布爾表達式。循環執行上面的過程。
4、練習(重中之重)(理解第一步,其他都是練習)
【練習一:計算0—100之間的奇數和偶數的和】
//練習1:計算1到100之間的奇數和偶數的和 int oddSum = 0; int evenSum = 0;for (int i = 0; i <= 100; i++) {if (i%2!=0) {//奇數oddSum+=i;}else {//偶數evenSum+=i;} } System.out.println("奇數的和:"+ oddSum); System.out.println("偶數的和:"+ evenSum);【練習2:用while或for循環輸出1-1000之間能被5整除的數,并且每行輸出3個】
//練習2:用while或for循環輸出1-1000之間能被5整除的數,并且每行輸出3個 //練習3:打印九九乘法表 for (int i = 1; i <= 1000; i++) {if (i%5==0){System.out.print(i +"\t"); //水平制表轉義字符}if (i%(5*3)==0){ //注意if (i%5*3==0)錯誤, % 優先級與 * 同級,從左向右依次運算//System.out.println(); //與print區別輸出后換行,print輸出后不換行System.out.print("\n"); //換行轉義字符} }【練習3:打印九九乘法表】
//練習3:打印九九乘法表 //9*9乘法表 //1.我們先打印第一列,這個大家應該都會 //2.我們把固定1再用一個循環包起米 //3.去掉重復項,i<=j //4.調整樣式 for (int i = 1; i <= 9; i++) {for (int j = 1; j <= i; j++) {System.out.print(i+"*"+j+"="+i*j+"\t");}System.out.println(); }【練習,題目要多少有多少,??途W,藍橋,多著呢,可以練習】
5、增強for循環
for(聲明語句 : 表達式){//循環體 }聲明語句: 聲明新的局部變量,該變量的類型必須和數組元素的類型匹配。其作用域限定在循環語句塊,其值與此時數組元素的值相等。
表達式: 表達式是要訪問的數組名,或者是返回值為數組的方法。
int[] numbers = {1,0,2,4}; for (int i = 0; i < 4; i++) {System.out.println(numbers[i]); } System.out.println("==================="); //遍歷數組或集合 for (int x:numbers){System.out.println(x); }break & continue
1、break 關鍵字
break 主要用在循環語句或者 switch 語句中,用來跳出整個語句塊。
break 跳出最里層的循環,并且繼續執行該循環下面的語句。
2、continue 關鍵字
continue 適用于任何循環控制結構中。作用是讓程序立刻跳轉到下一次循環的迭代。
3、兩者區別
break在任何訊循環語句的主體部分,均可用break控制循環的流程。break用于強行退出循環,不執行循環中剩余的語句。(break語句也在switch語句中使用)
continue語句在循環語句體中,用于終止某次循環過程,即跳過循環體中尚未執行的語句,接著進行下一次是否執行循環的判斷。
4、帶標簽的contimue
4-JavaSE:方法
方法
1、何謂方法
引言:System.out.printIn(),那么它是什么呢?
- printIn() 是一個方法。
- System 是系統類
- out 是標準輸出對象
什么是方法?
Java方法是語句的集合,它們在一起執行一個功能。
- 方法是解決一類問題的步驟的有序組合
- 方法包含于類或對象中
- 方法在程序中被創建,在其他地方被引用
設計方法的原則:方法的本意是功能塊,就是實現某個功能的語句塊的集合。我們設計方法的時候,最好保持方法的原子性,就是一個方法只能完成1個功能,這樣利于我們后期的拓展。
方法的優點
- 使程序變得更簡短而清晰
- 有利于程序維護
- 可以提高程序開發的效率
- 提高了代碼的重用性
回顧:方法的命名規則?
2、方法的定義
Java的方法類似于其他語言的函數,是一段用來完成特定功能的代碼片段,一般情況下,定義一個方法包含以下語法:
修飾符 返回值類型 方法名(參數類型 參數名){...方法體...return 返回值; }方法包含一個方法頭和一個方法體。下面是一個方法的所有部分:
- **修飾符:**修飾符,這是可選的,告訴編譯器如何調用該方法。定義了該方法的訪問類型。
- **返回值類型:**方法可能會返回值。return ValueType是方法返回值的數據類型。有些方法執行所需要的操作,但沒有返回值。在這種情況下,return ValueType是關鍵字void。
- **方法名:**是方法的實際名稱。方法名和參數表共同構成方法簽名。
- **參數類型:**參數像是一個占位符。當方法被調用時,傳遞值給參數。這個值被稱為實參或變量。參數列表是指方法的參數類型、順序和參數的個數。參數是可選的,方法可以不包含任何參數。
- 形式參數:在方法被調用時用于接收外界輸入的數據。
- 實參:調用方法時實際傳給方法的數據,
- **方法體:**方法體包含具體的語句,定義該方法的功能。
3、方法調用
Java支持兩種調用方法的方式,根據方法是否返回值來選擇。
當程序調用一個方法時,程序的控制權交給了被調用的方法。當被調用方法的返回語句執行或者到達方法體閉括號時候交還控制權給程序。
當方法返回一個值的時候,方法調用通常被當做一個值。例如:
int larger = max(30, 40)Java 支持兩種調用方法的方式,根據方法是否返回值來選擇。
當程序調用一個方法時,程序的控制權交給了被調用的方法。當被調用方法的返回語句執行或者到達方法體閉括號時候交還控制權給程序。
示例代碼:
public static void main(String[] args) {int max = max(10,20);System.out.println(max); }public static double max(int num1, int num2) {int result = 0;if (num1 == num2) {System.out.println("num1 == num2");return 0;}if (num1 > num2){return num1;}else {return num2;} }JAVA中只有值傳遞!
4、方法的重載(重寫,別混)
一個類的兩個方法擁有相同的名字,但是有不同的參數列表叫做方法的重載。
- Java編譯器根據方法簽名判斷哪個方法應該被調用。
- 方法重載可以讓程序更清晰易讀。執行密切相關任務的方法應該使用相同的名字。
- 重載的方法必須擁有不同的參數列表。你不能僅僅依據修飾符或者返回類型不同來重載方法。
5、拓展命令行傳參
6、可變參數
Jdk1.5開始,Java支持傳遞同類型的可變參數給一個方法。
聲明格式:
typeName...parameterName一個方法中只能指定一個可變參數,它必須是方法的最后一個參數。任何普通的參數必須在它之前聲明。
public static void main(String[] args) {//調用可變參數的方法printMax(34,2,5,64,98);printMax(new double[]{45,56,2}); }public static void printMax(double... numbers) {if (numbers.length == 0) {System.out.println("No argument passed");return;}double result = numbers[0];//排序for (int i = 1; i < numbers.length; i++) {if (numbers[i] > result){result = numbers[i];}}System.out.println("The max value is "+ result); }7、遞歸(小重點吧)
遞歸就是A方法調用A方法!自己調用自己。
利用遞歸可以用簡單的程序來解決一些復雜的問題。它通常把一個大型復雜的問題層層轉化為一個與原
問題相似的規模較小的問題來求解,遞歸策略只需少量的程序就可描述出解題過程所需要的多次重復計
算,大大地減少了程序的代碼量。遞歸的能力在于用有限的語句來定義對象的無限集合。
遞歸結構包括兩個部分:
遞歸頭。解答:什么時候不調用自身方法。如果沒有頭,將陷入死循環。
遞歸體。解答:什么時候需要調用自身方法。
【演示:利用代碼計算5的乘階!】
public static void main(String[] args) {System.out.println(f(5)); }public static int f(int n) {if (n == 1){return 1;}else {return n*f(n-1);} }能不用遞歸就不用遞歸,遞歸都可以用迭代來代替。 ?我不理解
總結和作業(流程與方法)
- 用戶交互Scanner
- 順序結構
- 選擇結構
- 循環結構
- break & continue
- 方法
作業:
- 寫一個計算器,要求實現加減乘除功能,并且能夠循環接收新的數據,通過用戶交互實現。思路推薦:
- 寫4個方法:加減乘除
- 利用循環+switch進行用戶交互
- 傳遞需要操作的兩個數
- 輸出結果
5-JavaSE:數組
數組概述
關于數組我們可以把他看作是一個類型的所有數據的一個集合,并用一個數組下標來區分或指定每一個數,(注意:數組的下標是從0開始的,所以10個數的話,下標就是0-9,a(0)=1)。使用數組會讓程序變得簡單,而且避免了定義多個變量的麻煩。
數組的定義:
- 數組是相同類型數據的有序集合。
- 數組描述的是相同類型的若干個數據,按照一定的先后次序排列組合而成。
- 其中,每一個數據稱作一個數組元素,每個數組元素可以通過一個下標來訪問它們。、
數組的四個基本特點:
數組聲明創建
1、聲明數組
首先必須聲明數組變量,才能在程序中使用數組。下面是聲明數組變量的語法:
dataType[] arrayRefvar; // 首選的方法 或 dataType arrayRefvar[]; // 效果相同,但不是首選方法2、創建數組
Java語言使用new操作符來創建數組,語法如下:
arrayRefvar = new dataType[arraySize];上面的語法語句做了兩件事:
- 一、使用 dataType[arraySize] 創建了一個數組。
- 二、把新創建的數組的引用賦值給變量 arrayRefVar
數組變量的聲明,和創建數組可以用一條語句來完成,如下所示:
dataType[] arrayRefVar = new dataType[arraySize];數組的元素是通過索引訪問的。數組索引從0開始,所以索引值從0到 arrayRefVar.length-1.
獲取數組長度:
arrays.length【演示聲明,創建,一個數組,并賦值,進行訪問】
int[] nums;//1. 聲明一個數組 nums = new int[10];//2. 創建一個數組//3. 給數組元素賦值 nums[0] = 1; nums[1] = 2; nums[2] = 3; nums[3] = 4; nums[4] = 5; nums[5] = 6; nums[6] = 7; nums[7] = 8; nums[8] = 9; nums[9] = 10;System.out.println("nums[9] == "+nums[9]);//計算所有元素的和 int sum = 0; //獲取數組長度:array.lenth for (int i = 0; i < nums.length; i++) {sum+=nums[i]; } System.out.println("總和為 "+ sum);3、內存分析
Java內存分析:
4、三種初始化
靜態初始化
除了用new 關鍵字來產生數組以來,還可以直接在定義數組的同時就為數組元素分配空間并賦值。
int[] a = {1,2,3}; Man[] mans = {new Man(1,1), new Man(2,2)};動態初始化
數組定義,為數組元素分配空間、賦值的操作、分開進行。
int[] a = new int[2]; a[0] = 1; a[1] = 2;數組的默認初始化
數組是引用類型,它的元素相當于類的實例變量,因此數組一經分配空間,其中的每個元素也被按照實例變量同樣的方式被隱式初始化。
int[] a = new int[2]; //0,0 boolean[] b = new boolean[2]; // false,false String[] s = new String[2]; //null,null5、數組邊界
下標的合法區間:[0, lenth-1],如果越界就會報錯;
int[] a = new int[2]; System.out.printf(a[2]);**ArrayIndexOutBoundsException:**數組下標越界異常!
6、小結
- 數組是相同數據類型(數據類型可以為任意類型)的有序集合
- 數組也是對象。數組元素相當于對象的成員變量(詳情請見內存圖、以后整個此類筆記)
- 數組長度是確定的,不可變的。如果越界,則報:ArrayIndexOutBoundsException
數組使用
數組的元素類型和數組的大小都是確定的,所以當處理數組元素時候,我們通常使用基本循環或者 For-Each 循環。
【以下實例完整地展示了如何創建、初始化和操作數組】
int[] arrays = {1,2,3,4,5}; //靜態初始化//打印全部數組元素 for (int i = 0; i <arrays.length; i++) {System.out.println(arrays[i]); } System.out.println("============"); //計算所有數組之和 int sum = 0; for (int i = 0; i <arrays.length; i++) {sum +=arrays[i]; } System.out.println(sum); System.out.println("============"); //查找最大元素 int max = arrays[0]; for (int i = 1; i <arrays.length; i++) {if (max < arrays[i]) {max = arrays[i];} } System.out.println(max); System.out.println("============");1、 For-Each 循環
JDK 1.5 引進了一種新的循環類型,被稱為 For-Each 循環或者加強型循環,它能在不使用下標的情況下遍歷數組。語法格式如下:
for(type element : array){System.out.prinfIn(element); } //示例 //打印全部數組元素JDK1.5,沒有下標 for (int array: arrays) {System.out.print(array+ " "); }2、數組作方法入參
數組可以作為參數傳遞給方法。
//打印數組元素方法 public static void printArray(int[] arrays) {for (int i = 0; i <arrays.length; i++) {System.out.print(arrays[i] + " ");}System.out.println("============"); }3、數組作返回值
//反轉數組 public static int[] reverse (int[] arrays) {int[] result = new int[arrays.length];for (int i = 0; i <arrays.length; i++) {result[i] = arrays[arrays.length-i-1];}return result; }result 數組作為函數的返回值。
多維數組
多維數組可以看成是數組的數組,比如二維數組就是一個特殊的一維數組,其中的每一個元素都是一個一維數組。
多維數組的動態初始化(以二維數組為例)
// 為每一維分配空間,格式如下 typeLength1為行,typeLength2為列 type[][] typeName = new type[typeLength1][typeLength2]; int[][] a = new int[2][5]多維數組的引用(以二維數組為例)
int[][] arrays = {{1,2},{2,3},{3,4,6},{4,5}}; for (int i = 0; i < arrays.length; i++) {for (int j = 0; j < arrays[i].length; j++) {System.out.print(arrays[i][j] +" ");}System.out.println(); }arrays.length 和 arrays[i].length
Array 類
數組的工具類 java.util.Arrays
由于數組對象本身并沒有什么方法可以供我們調用,但API中提供了一個工具類Arrays供我們使用,從而可以對數據對象進行一些基本的操作。
Arrays類中的方法都是static修飾的靜態方法,在使用的時候可以直接使用類名進行調用,而”不用“使用對象來調用(注意,是”不用“,而不是”不能“)
java.util.Arrays 類能方便地操作數組,使用之前需要導包!
具有以下常用功能:
- 給數組賦值:通過 fill 方法。
- 對數組排序:通過 sort 方法,按升序。
- 比較數組:通過 equals 方法比較數組中元素值是否相同
- 查找數組元素:通過 binarySearch 方法能對排序好的數組進行二分查找法操作
1、打印數組
2、數組排序
3、二分法查找
4、元素填充
5、數組轉換為List集合
int[] a = {1,5,565,15,6546,464,564,6546,46,46,46,4}; System.out.println(a);//哈希碼 [I@1b6d3586 //打印數組元素 Arrays.sort(a); System.out.println(Arrays.binarySearch(a, 12));// 二分法查找 ,必須先對數組進行排序 Arrays.fill(a,2,4,0);// 元素填充 System.out.println(Arrays.toString(a)); List<int[]> list = Arrays.asList(a);常見排序算法(有興趣的話,下次補個額外的基礎算法筆記)
1、 冒泡排序(Bubble Sort)
冒泡排序,是一種計算機科學領域的比較簡單的排序算法。
冒泡排序算法的原理如下:
2、選擇排序(Selection sort)
選擇排序是一種簡單直觀的排序算法。它的工作原理是每一次從待排序的數據元素中選出最小(或最大)的一個元素,存放在序列的起始位置,然后,再從剩余未排序元素中繼續尋找最小(大)元素,然后放到排序序列的末尾。以此類推,直到全部待排序的數據元素排完。選擇排序是不穩定的排序方法。
累了,休息了3、有空全部補上
稀疏數組
(69條消息) Java實現稀疏數組_Marvellous丶的博客-CSDN博客
用作棋盤很是合適。
6-JavaSE:面向對象
面向過程&面向對象
面向過程的思維模式
面向對象的思維模式
對于描述復雜的事物,為了從宏觀上把握、從整體上合理分析,我們需要使用面向對象的思路來分析整個系統。但是,具體到微觀操作,仍然需要面向過程的思路去處理。
OOP詳解
1、什么是面向對象
Java 的編程語言是面向對象的,采用這種語言進行編程稱為面向對象編程(Object-Oriented Programming,OOP)。
面向對象編程的本質就是:以類的方式組織代碼,以對象的組織(封裝)數據。
抽象(abstract)
忽略。。。有待考量
封裝(Encapsulation)
封裝是面向對象的特征之一,是對象和類概念的主要特性。封裝是把過程和數據包圍起來,對數據的訪問只能通過指定的方式。
在定義一個對象的特性的時候,有必要決定這些特性的可見性,即哪些特性對外部是可見的,哪些特性用于表示內部狀態。
通常,應禁止直接訪問一個對象中的數據的實際表示,而應通過操作接口來訪問,這稱為信息隱藏。
信息隱藏是用戶對封裝性的認識,封裝則為信息隱藏提供支持。
封裝保證了模塊具有較好的獨立性,使得程序維護較為容易。對應用程序的修改僅限于類的內部,因而可以將程序修改帶來的影響減少到最低限度。(懂一點的,看完應該頗有收獲)
繼承(inheritance)
繼承是一種聯結類的層次模型,并且允許和支持類的重用,它提供了一種明確表述共性的方法。
? 新類繼承了原始類后,新類就繼承了原始類的特性,新類稱為原始類的派生類(子類),而原始類稱為新類的基類(父類)。
? 派生類(子類)可以從它的基類(父類)那里繼承方法和實例變量,并且派生類(子類)中可以修改或增加新的方法使之更適合特殊的需要繼承性很好的解決了軟件的可重用性問題。比如說,所有的Windows應用程序都有一個窗口,它們可以看作都是從一個窗口類派生出來的。但是有的應用程序用于文字處理,有的應用程序用于繪圖,這是由于派生出了不同的子類,各個子類添加了不同的特性。
多態(polymor phism)
多態性是指允許不同類的對象對同一信息作出相應。
? 多態性語言具有靈活、抽象、行為共享、代碼共享的優勢,很好的解決了應用程序函數同名問題。
相同類域的不同對象,調用相同方法,表現出不同的結果。(吃飯-飽了-沒飽)
從認知論角度考慮是先有對象后有類。對象,是具體的事物。類,是對對象的抽象。
從代碼運行角度考慮是先有類后有對象,類是對象的模板。
2、類與對象的關系
類是一種抽象的數據類型,它是對某一類事物整體描述/定義,但是并不能代表某一具體的事物。
例如:我們生活中所說的詞語:動物、植物、手機、電腦等等。這些也都是抽象的概念,而不是指某一個具體的東西。
例如:Person類、Pet類、Car類等,這些類都是用來描述/定義某一具體的事物應該具備的特點和行為,對象是抽象概念的具體實例
Student s = new Student("tom", 20); s.study(); Car c = new Car("BYD",8,30); c.run();==在java中,沒有類就沒有對象,而類又是根據具體的功能需求,進行實際的分析,最終抽象出來的。
3、對象和引用的關系
引用“指向”對象
使用類類型、數組類型、接口類型聲明出的變量,都可以指向對象,這種變量就是引用類型變量,簡稱引用。
在程序中,創建出對象后(new),直接使用并不方便,所以一般會用一個引用類型的變量去接收這個對象,這個就是所說的引用指向對象。
總結:對象和引用的關系,就如同電視機和遙控器,風箏和線的關系一樣。
方法回顧及加深
方法一定是定義在類中的,屬于類的成員。
1、方法的定義
格式: 修飾符 返回類型 方法名(參數列表) throws 異常{... }1. 修飾符
public、static、abstract、final等等都是修飾符,一個方法可以有多個修飾符。例如程序入口main方法,就使用了public static這兩個修飾符 注:如果一個方法或者屬性有多個修飾符,這多個修飾符是沒有先后順序的2. 返回類型
方法執行完,如果又要返回的數據,那么就要聲明返回數據類型,如果沒有返回類型就必須寫void只有構造方法(構造器)不寫任何返回類型也不寫void //return 結束方法,返回一個結果 public String satHello(){return "hello,World!"; } public void print(){return; } public int max(int a,int b){return a>b?a:b; }【思考】:聲明返回類型的方法中一定要出現return語句,那么沒有返回類型(void)的方法中,能不能出現return語句?
注:break 和 return 的區別
return 語句的作用:
break 語句的作用
3.方法名
遵循java中標識符的命名規則即可。4.參數列表
根據需求定義,方法可以是無參的,也可以是有一個參數,也可以有多個參數5.異常拋出類型
如果方法中的代碼在執行過程中,可能會出現一些異常情況,那么就可以在方法上把這些異常聲明并拋出,也可以同時聲明拋出多個異常,使用逗號隔開即可。 public void readFile(String file) throws IOException{} public void readFile(String file) throws IOException,ClassNotFoundException{}2、方法調用
在類中定義了方法,這個方法中的代碼并不會執行,當這個方法被調用的時候,方法中的代碼才會被一行一行順序執行。()
1.非靜態方法
沒有使用 static 修飾符修飾的方法,就是非靜態方法。
調用這種方法的時候,是一定要使用對象的。因為非靜態方法是屬于對象的。(非靜態屬性也是一樣的)
【例子】
//學生類 public class Student {//方法 非靜態方法public void say(){System.out.println("學生說話了!");} } -------------------------------------------- //實例化這個類new //對象類型對象名=對象值 Student student = new Student();//非靜態方法 student.say();2.靜態方法
使用 static 修飾符修飾的方法,就是靜態方法。
調用這種方法德時候,可以使用對象調用,也可以使用類來調用,但是推薦使用類進行調用,因為靜態方法時屬于類的。(靜態屬性也是一樣的)
【例子】
public class Student {public static void say(){System.out.println("學生說話了!");} } -------------------------------------------- Student.say();//靜態方法 static3. 類中方法之間的調用
假設同一個類中有兩個方法,a方法和b方法,a和b都是非靜態方法,相互之間可以直接調用。
//靜態方法和類一起加載 public void a(){b(); }//非靜態方法:類實例化后 才存在 public void b(){a(); }- 都是非靜態,或都是靜態,a,b方法可以相互直接調用
- 一個靜態,一個非靜態,非靜態可以調用靜態,但靜態方法不能調用非靜態方法(先后產生的關系)
- 另外:在同一個類中,靜態方法內不能直接訪問到類中的非靜態屬性.
3、調用方法時的傳參
1.形參和實參
public void test(int a){ //a是方法test的形參//... } ----------------------- int x = 3; t.test(x);// x是方法test的實參 //不關心參數的名字,關注于變量的類型以及變量接收的值2.值傳遞和引用傳遞(好好理解,挺重要的)
調用方法進行傳參時,分為值傳遞和引用傳遞兩種。
如果參數的類型是基本數據類型,那么就是值傳遞。
如果參數的類型是引用數據類型,那么就是引用傳遞。
值傳遞是實參把自己變量本身存的簡單數值賦值給形參.
引用傳遞是實參把自己變量本身存的對象內存地址值賦值給形參.
所以值傳遞和引用傳遞本質上是一回事,只不過傳遞的東西的意義不同而已.
4、this關鍵字
在類中,可以使用this 關鍵字表示一些特殊的作用。
1.this在類中的使用
- 【區別成員變量和局部變量】
- 【調用類中的其他方法】
- 【調用類中的其他構造器】注 :this的這種用法,只能在構造器中使用,普通方法是不能使用的,且該代碼只能在第一句。
2.this關鍵字在類中的意義
this 在類中表示當前類將來創建出的對象。
創建與初始化對象
使用new關鍵字創建對象
使用new關鍵字創建的時候,除了分配內存空間之外,還會給創建好的對象進行默認的初始化以及對類中構造器的調用。
那么對main方法中的以下代碼: Student s = new Student(); 1)為對象分配內存空間,將對象的實例變量自動初始化默認值為0/false/null。(實例變量的隱式賦 值) 2)如果代碼中實例變量有顯式賦值,那么就將之前的默認值覆蓋掉。(之后可以通過例子看到這個現象) 例如:顯式賦值 private String name = "tom"; 3)調用構造器 4)把對象內存地址值賦值給變量。(=號賦值操作)構造器
類中的構造器也稱為構造方法,是在進行創建對象的時候必須要調用的。并且構造器有以下兩個特點:
構造器的作用
構造器重載
除了無參構造器之外,很多時候我們還會使用有參構造器,在創建對象時候可以給屬性賦值.
構造器之間的調用
使用this關鍵字,在一個構造器中可以調用另一個構造器的代碼。
注意:this的這種用法不會產生新的對象,只是調用了構造器中的代碼而已.一般情況下只有使用new關鍵字才會創建新對象。
默認構造器
在java中,即使我們在編寫類的時候沒有寫構造器,那么在編譯之后也會自動的添加一個無參構造器,這個無參構造器也被稱為默認的構造器
內存分析
JAVA程序運行的內存分析
棧 stack:
堆 heap:
放置new出來的對象!
堆是一個不連續的內存空間,分配靈活,速度慢!
方法區(也是堆):
被所有線程共享!
用來存放程序中永遠是不變或唯一的內容。(類代碼信息、靜態變量、字符串常量)
引用類型的概念
屬性(field,或者叫成員變量)
類的方法
方法是類和對象動態行為特征的抽象。方法很類似于面向過程中的函數。面向過程中,函數是最基本單位,整個程序有一個個函數調用組成;面向對象中,整個程序的基本單位是類,方法是從屬于類或對象的。
封裝
白話:該露的露,該藏的藏
專業:我們程序設計要追求“高內聚,低耦合”。
高內聚是類的內部數據操作細節自己完成,不允許外部干涉;低耦合:僅暴露少量的方法給外部使用。
封裝(數據的隱藏)
在定義一個對象的特性的時候,有必要決定這些特性的可見性,即哪些特性對外部是可見的,那些特性用于表示內部狀態。
通常,應禁止直接訪問一個對象中數據的實際表示,而應通過操作接口來訪問,這稱為信息隱藏。
1、封裝的步驟
設置 通過set方法,命名格式:set屬性名();屬性的首字母要大寫
設置 通過get方法,命名格式:get屬性名();屬性的首字母要大寫
2、作用和意義
良好的封裝,便于修改內部代碼,提高可維護性。
良好的封裝,可進行數據完整性檢測,保證數據的有效性。
3、方法重載
類中有很多方法,有著相同的方法名,但是方法的參數各不相同,這種情況被稱為方法的重載。方法的重載可以提供方法調用的靈活性。
【思考:HelloWorld中的System.out.printIn()方法,為什么可以把不同類型的參數傳給這個方法?方法的重載】
public class Test{ public void test(String str){ }public void test(int a){ } }方法重載必須滿足以下條件
在java中,判斷一個類中的兩個方法是否相同,主要參考兩個方面:方法名字和參數列表
繼承
現實世界中的繼承無處不在。比如
繼承的本質是對某一批類的抽象,從而實現對現實世界更好的建模。
為什么需要繼承?繼承的作用?
【注】Java中類只有單繼承,沒有多繼承!接口可以多繼承!
1、繼承
子類中繼承了父類中的屬性和方法后,在子類中能不能直接使用這些屬性和方法,適合這些屬性和方法原有的修飾符(public、
protected、default、private)相關的。
父類中的構造器是不能被子類繼承的,但是子類的構造器中,會隱式的調用父類中的無參構造器(默認使用super 關鍵字)
2、Object類
java中的每一個類都是“直接”或“間接”的繼承Object類。所以每一個對象都和Object類有“is a”的關系。從API文檔中,可以看到任何一個類最上層的父類都是Object。(Object類本身除外)AnyClass is a Object。
System.out.println(任何對象 instanceof Object);在Object類中,提供了一些方法被子類繼承,那么就意味著,在java中,任何一個對象都可以調用這些被繼承過來的方法。(因為Object 是所有類的父類)
例如:toString方法、equals方法、getClass方法等
注:Object類中的每一個方法之后都會使用到
3、Super關鍵字
子類繼承父類之后,在子類中可以使用this 來表示訪問或調用子類中的屬性或方法,使用super 就表示訪問或調用父類中的屬性和方法。
1-super的使用
【訪問父類中的屬性】
public class Person{protected String name = "zs"; } ------------------------------------- public class Student extends Person{private String name = "lisi";public void test(String name){System.out.printfIn(name);System.out.printfIn(this.name);System.out.printfIn(super.name);} }【調用父類中的方法】
public class Person{public void print(){System.out.println("Person");} } ------------------------------------- public class Student extends Person{public void print(){System.out.println("Student");}public void test(){print();this.print();super.print();} }【調用父類中的構造器】
public class Person{} ------------------------------------- public class Student extends Person{//編譯通過,子類構造器中會隱式的調用父類的無參構造器// superpublic Student(){} }- 當父類沒有無參構造時,子類會編譯報錯
【顯式的調用父類的有參構造器】
public class Person{protected String name;public Person(String name){this.name = name;} } public class Student extends Person { //編譯通過,子類構造器中顯式的調用父類的有參構造器public Student(){super("tom");} }- 注:不管是顯式還是隱式的父類的構造器,super語句一定要出現在子類構造器中第一行代碼。所以this和super不可能同時使用它們調用構造器的功能,因為它們都要出現在第一行代碼位置。
【super使用的注意的地方】
【super 和 this 的區別】
代表的事物不一樣:
【super 和 this 的區別】
- this:代表所屬方法的調用者對象。
- super:代表父類對象的引用空間。
- this:在非繼承的條件下也可以使用。
- super:只能在繼承的條件下才能使用。
- this:調用本類的構造方法。
- super:調用的父類的構造方法。
4、方法重寫(override)
【例子】
A類繼承B類 A和B中都一個相同的靜態方法test B a = new A(); a.test();//調用到的是B類中的靜態方法test A a = new A(); a.test();//調用到的是A類中的靜態方法test //可以看出靜態方法的調用只和變量聲明的類型相關 //這個和非靜態方法的重寫之后的效果完全不同重寫的語法
ClassNotFoundException --> Exception
總結:
多態
多態性是OOP中的一個重要特性,主要是用來實現動態聯編的
多態可以讓我們不用關心某個對象到底是什么具體類型,就可以使用該對象的某些方法,從而實現更加靈活的編程,提高系統的可擴展性。
1、認識多態
允許不同類的對象對同一消息做出響應。即同一消息可以根據發送對象的不同而采用多種不同的行為方式。
相同類域的不同對象,調用相同的方法,執行結果是不同的
2、重寫、重載和多態的關系
重載是編譯時的多態
- 調用重載的方法,在編譯期間就要確定調用的方法時誰,如果不能確定則編譯報錯
重寫是運行時多態
- 調用重寫的方法,在運行期間才能確定這個方法到底是哪個對象中的。這個取決于調用方法的引用,在運行期間所指向的對象是誰,這個引用指向哪個對象那么調用的就是哪個對象中的方法。(java中的方法調用,是運行時動態和對象綁定的)
3、多態的注意事項
4、多態存在的條件
以下三種類型的方法是沒有辦法表現出多態特性的(因為不能被重寫):
5、方法綁定(method binding)
執行調用方法時,系統根據相關信息,能夠執行內存地址中代表該方法的代碼。分為靜態綁定和動態綁定。
靜態綁定:
? 在編譯期完成,可以提高代碼執行速度。
動態綁定:
通過對象調用的方法,采用動態綁定機制。這雖然讓我們編程靈活,但是降低了代碼的執行速度。這也是Java比C、C++速度慢的主要因素之一。Java中除了final類、final方法、static方法。所有方法都是JVM在運行期才進行動態綁定的。
多態:如果編譯時類型和運行類型不一致,就會造成多態。
6、instanceof 和 類型轉換
1、instanceof
System.out.println(x instanceof Y); //該代碼能否編譯通過,主要是看聲明變量x的類型和Y是否存在子父類的關系.有"子父類關"系就編譯通過, 沒有子父類關系就是編譯報錯. //之后學習到的接口類型和這個是有點區別的。 //輸出結果是true還是false,主要是看變量x所指向的對象實際類型是不是Y類型的"子類型".2、類型轉換
【總結】
如Father father=new Son0;
如father就是一個指向子類對象的父類引用,把father賦給子類引用son 即Son son=(Son)
father;其中father前面的(Son)必須添加,進行強制轉換。
修飾符
1、static修飾符
static變量
- 在類中,使用static修飾的成員變量,就是靜態變量,反之為非靜態變量。
- 靜態變量屬于類的,"可以"使用類名來訪問,非靜態變量是屬于對象的,"必須"使用對象來訪問。
- 靜態變量對于類而言在內存中只有一個,能被類的所有實例所共享。實例變量對于類的每個實例都有一份,它們之間互不影響。
- 在加載類的過程中為靜態變量分配內存,實例變量在創建對象時分配內存,所以靜態變量可以使用類名來直接訪問,而不需要使用對象來訪問.。
static方法
- 在類中,使用static修飾的成員方法,就是靜態方法,反之為非靜態方法。
- 靜態方法"不可以"直接訪問類中的非靜態變量和非靜態方法,但是"可以"直接訪問類中的靜態變量和靜態方法。注意:this和super在類中屬于非靜態的變量.(靜態方法中不能使用)
- 非靜態方法"可以"直接訪問類中的非靜態變量和非靜態方法,也"可以"直接訪問類中的靜態變量和靜態方法
- 父類的靜態方法可以被子類繼承,但是不能被子類重寫。父類的非靜態方法不能被子類重寫為靜態方法 ;
代碼塊和靜態代碼塊
- 【類中可以編寫代碼塊和靜態代碼塊】
- 匿名代碼塊是在創建對象的時候自動執行的,并且在構造器執行之前。同時匿名代碼塊在每次創建對象的時候都會自動執行.
靜態代碼塊是在類加載完成之后就自動執行,并且只執行一次. - 匿名代碼塊的作用是給對象的成員變量初始化賦值,但是因為構造器也能完成這項工作,所以匿名代碼塊使用的并不多。
靜態代碼塊的作用是給類中的靜態成員變量初始化賦值。 - 注:在構造器中給靜態變量賦值,并不能保證能賦值成功,因為構造器是在創建對象的時候才指向,但是靜態變量可以不創建對象而直接使用類名來訪問.
創建和初始化對象的過程
注:子類中非靜態屬性的顯示賦值是在父類構造器執行完之后和子類中的匿名代碼塊執行之前的時候
靜態導入
2、final修飾符
修飾類
用final修飾的類不能被繼承,沒有子類。
修飾方法
用final修飾的方法可以被繼承,但是不能被子類的重寫。
修飾變量
用fifinal修飾的變量表示常量,只能被賦一次值.其實使用fifinal修飾的變量也就成了常量了,因為值不會再變了。
3、abstract 修飾符
abstract修飾符可以用來修飾方法也可以修飾類,如果修飾方法,那么該方法就是抽象方法;如果修飾類,那么該類就是抽象類。
1、抽象類和抽象方法的關系
抽象類中可以沒有抽象方法,但是有抽象方法的類一定要聲明為抽象類。
注:子類繼承抽象類,那么就必須要實現抽象類沒有實現的抽象方法,否則該子類也要聲明為抽象類。
思考1 : 抽象類不能new對象,那么抽象類中有沒有構造器?
抽象類是不能被實例化,抽象類的目的就是為實現多態中的共同點,抽象類的構造器會在子類實例化時調 用,因此它也是用來實現多態中的共同點構造,不建議這樣使用!思考2 : 抽象類和抽象方法意義(為什么要編寫抽象類、抽象方法)
打個比方,要做一個游戲。如果要創建一個角色,如果反復創建類和方法會很繁瑣和麻煩。建一個抽象類 后。若要創建角色可直接繼承抽象類中的字段和方法,而抽象類中又有抽象方法。如果一個角色有很多種 職業,每個職業又有很多技能,要是依次實例這些技能方法會顯得想當笨拙。定義抽象方法,在需要時繼 承后重寫調用,可以省去很多代碼。 總之抽象類和抽象方法起到一個框架作用。很方便后期的調用和重寫 抽象方法是為了程序的可擴展性。重寫抽象方法時即可實現同名方法但又非同目的的要求。接口
1、接口的本質
普通類:只有具體實現
抽象類:具體實現和規范(抽象方法)都有!
接口:只有規范!
【為什么需要接口?接口和抽象類的區別?】
- 接口就是比“抽象類”還“抽象”的“抽象類”,可以更加規范的對子類進行約束。全面地專業地實現了:規范和具體實現的分離。
- 抽象類還提供某些具體實現,接口不提供任何實現,接口中所有方法都是抽象方法。接口是完全面向規范的,規定了一批類具有的公共方法規范。
- 從接口的實現者角度看,接口定義了可以向外部提供的服務。
- 從接口的調用者角度看,接口定義了實現者能提供哪些服務。
- 接口是兩個模塊之間通信的標準,通信的規范。如果能把你要設計的系統之間模塊之間的接口定義好,就相當于完成了系統的設計大綱,剩下的就是添磚加瓦的具體實現了。大家在工作以后,做系統時往往就是使用“面向接口”的思想來設計系統。
【接口的本質探討】
- 借口就是規范,定義的是一組規則,體現了現實世界中“如果你是。。。則必須能。。?!钡乃枷?。如果你是天使,則必須能飛。如果你是汽車,則必須能跑。如果你好人,則必須干掉壞人;如果你是壞人,則必須欺負好人。
- 接口的本質是契約,就像我們人間的法律一樣。制定好后大家都遵守。
- OOP的精髓,是對對象的抽象,最能體現這一點的就是接口。為什么我們討論設計模式都只針對具備了抽象能力的語言(比如C++、java、C#等),就是因為設計模式所研究的,實際上就是如何合理的去理解抽象。
2、接口與抽象類的區別
抽象也是類,除了可以寫抽象方法以及不能直接new對象之外,其他的和普通類沒有什么不一樣的。接口已經是另一種類型了,和類是有本質的區別的,所以不能用類的標準去衡量接口。
聲明類的關鍵字是class,聲明接口的關鍵字是interface
- 抽象類是用來繼承的,java中的類是單繼承。
- 類A繼承了抽象類B,那么類A的對象就屬于B類型了,可以使用多態。
一個父類的引用可以指向這個父類的任意子類對象。
注:繼承的關鍵字是extends - 接口是用來被類實現的,java中的接口可以被多實現。
類A實現接口B、C、D、E…那么類A的對象就屬于B、C、D、E等類型了,可以使用多態。
一個接口的引用,可以指向這個接口的任意實現類對象。
注:實現的關鍵字是implements
3、接口中的方法都是抽象方法
接口中可以不寫任何方法,但是如果寫方法了,該方法必須是抽象方法
public interface TimeService {//默認就是public abstract修飾的void timer(); }4、接口中的變量都是靜態常量(public static final修飾)
接口中可以不寫任何屬性,但如果寫屬性了,該屬性必須是public static final修飾的靜態常量。
注:可以直接使用接口名訪問其屬性。因為是public static修飾的
注:聲明的同時就必須賦值(因為接口中不能編寫靜態代碼塊)
5、一個類可以實現多個接口
public class Student implements A,B,C,D{ //Student需要實現接口A B C D中所有的抽象方法 //否則Student類就要聲明為抽象類,因為有抽象方法沒實現 } main: A s1 = new Student(); B s2 = new Student(); C s3 = new Student(); D s4 = new Student();注:
s1只能調用接口A中聲明的方法以及Object中的方法
s2只能調用接口B中聲明的方法以及Object中的方法
s3只能調用接口C中聲明的方法以及Object中的方法
s4只能調用接口D中聲明的方法以及Object中的方法
注:必要時可以類型強制轉換
例如 : 接口A 中有test() , 接口B 中有run()
A s1 = new Student(); s1.test(); B s2 = new Student(); s2.run(); if(s1 instanceof B){ ((B)s1).run(); }6、一個接口可以繼承多個父接口
注:一個引用所指向的對象,是有可能實現任何一個接口的。(java中的多實現)
7、接口的作用
接口的最主要的作用是達到統一訪問,就是在創建對象的時候用接口創建
【接口名】 【對象名】 = new 【實現接口的類】
作用:1. 約束2. 定義一些方法,讓不同人實現-- 10 ----》 13. public abstract4. public static final5. 接口不能被實例化~,接口中沒有構造方法~6. implements可以實現多個接口7. 必須要重寫接口中的方法-內部類
接口完了,就是內部類了。
很多時候,我們創建類的對象的時候并不需要使用很多次,每次只使用一次,這個時候我們就可以使用內部類了。
1、內部類概述
內部類就是在一個類的內部在定義一個類,比如,A類中定義一個B類,那么B類相對A類來說就稱為內部類,而A類相對于B類來說就是外部類了。
內部類不是在一個Java源文件中編寫兩個平行的兩個類,而是在一個類的內部再定義另外一個類。我們可以把外邊的類稱為外部類,在其內部編寫的類稱為內部類。
內部類分為四種:
2、成員內部類(實例內部類、非靜態內部類)
注:成員內部類中不能寫靜態屬性和方法
【定義一個內部類】
//在A類中申明了一個B類,此B類就在A的內部,并且在成員變量的位置上,所以就稱為成員內部類 public class Outer {private int id = 10 ;public void out(){System.out.println("這是外部類的方法");}//內部類 加個Static 就是靜態內部類class Inner{public void in() {System.out.println("這是內部類的方法");}//獲得外部類的私有屬性--public void getId() {System.out.println(id);}} }【實例化內部類】
實例化內部類,首先需要實例化外部類,通過外部類去調用內部類
public class Application {public static void main(String[] args) {//newOuter o1 = new Outer();//通過這個外部類來實例化內部。Outer.Inner i1 = o1.new Inner();i1.in();i1.getId();} }【成員內部類能干什么?】
3、靜態內部類
使用static關鍵字修飾的內部類就叫靜態內部類。
static一般只修飾變量和方法,平常不可以修飾類,但是內部類卻可以被static修飾。
注意:
偶們上面說的內部類能夠使用外部類的方法和屬性,在靜態內部類中就行了,因為靜態內部類沒有了指向外部類對象的引用。除非外部類中的方法或屬性也是靜態的。這就回歸到了static關鍵字的用法。
靜態內部類能夠直接被外部類給實例化,不需要使用外部類對象
OUter.Inner inner = new Outer.Inner();靜態內部類中可以聲明靜態方法和靜態變量,但是非靜態內部類中就不可以聲明靜態方法和靜態變量
4、局部內部類
局部內部類是在一個方法內部聲明的一個類
局部內部類中可以訪問外部類的成員變量及方法
局部內部咧中如果要訪問該內部類所在方法中的局部變量,那么這個局部變量就必須是final修飾的
//局部內部類 public void method(){class Inner{public void in(){}} }5、匿名內部類
在這四種內部類中,以后的工作可能遇到最多的是匿名內部類,所以說匿名內部類是最常見的一種內部類。
什么是匿名對象?如果一個對象只要使用一次,那么我們就需要new Object().method()。就可以了,而不需要給這個實例保存到該類型變量中去。這就是匿名對象。
【匿名對象】
public class Test {public static void main(String[] args) {//沒有名字初始化類,不用講實例保存到變量中---new Apple().eat();} }class Apple{public void eat(){System.out.println("eat");} }匿名內部類跟匿名對象是一個道理:
匿名對象:我只需要使用一次,那么我就不用聲明一個該類型類型變量來保存對象了,
匿名內部類:我也只需要使用一次,那么我就不需要在類中先定義一個內部類,而是等待需要用的時候,我就在臨時實現這個內部類,因為用次數少,可能就這一次,那么這樣寫內部類,更方便。不然先寫出一個內部類的全部實現來,然后就調用它一次,豈不是用完之后就一直將其放在那,那就沒必要那樣。
- 如果依托的是類,那么創建出來的匿名內部類就默認是這個類的子類
- 如果依托的是接口,那么創建出來的匿名內部類就默認是這個接口的實現類。
- 匿名內部類的聲明及創建對象必須一氣呵成。并且之后能反復使用,因為沒有名字。
總結
以上是生活随笔為你收集整理的JavaSE_kuang的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 空间数据与空间分析不确定性原理——学习笔
- 下一篇: php html转换成word,php如