JavaSe第三天筆記小記
JavaSE第三天學習小記
1、java陣列
與c++中的陣列概念一致,把不同的只是語法
public class Hello { public static void main(String[] args) { /*效果相同 int[] arr; // 首選 int arr[]; // 可用,但java中不建議用 */ int[] array1 = new int[5]; // 開闢五個存放int型別的陣列 int[] array2 = {1, 2, 3}; // 開闢分別存放1,2,3的陣列 System.out.println("獲取陣列大小:" + array1.length); } }
基本特點:
- 長度確定,一旦被建立,大小不可改變
- 存放元素必須是同一型別
- 陣列中的元素可以是任何資料型別,包括基本型別和引用型別
- 陣列變數屬於引用型別,陣列也可以看作是物件,陣列中的每個元素相當於該物件的成員變數
- 陣列本身就是物件,java物件是在堆中的,因此陣列無論儲存原始型別還是其他物件型別,陣列本身都是在堆中的
三種初始化方式
1、靜態初始化
int[] arr = {1,2,3};
Man[] mans = {new Man(1), new Man(2)};
2、動態初始化
int[] arr = new int[2];
arr[0] = 1;
arr[1] = 2;
3、陣列的預設初始化
- 陣列是引用型別,它的元素相當於類的例項變數,因此陣列一經分配空間,其中的每個元素也被按照例項變數同樣的方式被隱式初始化
2、記憶體分析
3、Arrays類
java中的一個工具類,包含在java.util.Arrays
包中
- 陣列本身沒有方法供我們呼叫,所以API中提供了一個工具類Arrays供我們使用,從而可以對資料物件進行一些基本的操作
- 檢視JDK幫助文件
- Arrays類中的方法都是static修飾的靜態方法,在使用的時候可以直接使用類名進行呼叫,而“不用”使用物件呼叫(是“不用”而不是“不能“)
常用方法:
- 給陣列賦值:通過fill方法
- 對陣列排序:通過sort方法,預設是從小到大排序
- 比較陣列:通過equals方法比較陣列中元素值是否相等
- 查詢陣列元素:通過binarySearch方法能對排序好的陣列進行二分查詢法操作
4、氣泡排序
動圖演示:
import java.util.Arrays;
public class Hello {
public static void main(String[] args) {
int[] arr = {21, 26, 12, 45, 23, 9, 12, 3, 3, 7};
sort(arr);
System.out.println(Arrays.toString(arr));
}
public static void sort(int[] a) {
// 氣泡排序演算法實現
for (int i = 0; i < a.length - 1; i++) {
for (int j = 0; j < a.length - 1 - i; j++) {
if (a[j + 1] < a[j]) {
int tmp = a[j];
a[j] = a[j + 1];
a[j + 1] = tmp;
}
}
}
}
}
結果:[3, 3, 7, 9, 12, 12, 21, 23, 26, 45]
5、面向物件
java中的面向物件思想與c++大體一致
- 以類的方式組織程式碼,以物件的方式組織(封裝)資料
5.1 構造器
即構造方法(c++裡面的建構函式)
- 必須和類的名字相同
- 不能有返回型別,也不能寫void
- 使用new關鍵字建立物件的本質是在呼叫構造器
- 一旦定義了有參構造,就沒有預設的隱式無參建構函式,因此需要顯式定義
5.2 訪問許可權
修飾符 | 描述 | 大白話 |
---|---|---|
private | 私有的,被private修飾的類、方法、屬性、只能被本類的物件所訪問 | 我什麼都不跟別人分享。只有自己知道 |
default | 預設的,在這種模式下,只能在同一個包內訪問 | 我的東西可以和跟我一塊住的那個人分享 |
protected | 受保護的,被protected修飾的類、方法、屬性、只能被本類、本包、不同包的子類所訪問 | 我的東西我可以和跟我一塊住的那個人分享。另外也可以跟不在家的兒子分享訊息,打電話 |
public | 公共的,被public修飾的類、方法、屬性、可以跨類和跨包訪問 | 我的東西大家任何人都可以分享 |
5.3 封裝
- 程式設計追求“高內聚,低耦合”
- 資料的隱藏,通常應禁止直接訪問一個物件中資料的實際表示,而應通過操作介面來訪問
- 屬性私有,get/set
5.4 繼承
- 繼承的本質是對某一批類的抽象,從而實現對現實世界更好的建模
extends
的意思是擴充套件,子類是父類的擴充套件- java中只有單繼承,沒有多繼承
class People {
String name;
int age;
}
public class Student extends People{
// 繼承了父類,具有父類的屬性
}
object類
- java中所有的類,都預設直接或者間接繼承Object
super
- super呼叫父類的構造方法,必須在構造方法的第一行
- super必須只能出現在子類的方法或者構造方法中
- super和this不能同時呼叫構造方法
- 只能在繼承條件下才可以使用
this
- 與super相比代表的物件不同:本身呼叫者這個物件
- 沒有繼承也可以使用
this(); // 呼叫本類的構造
super(); // 呼叫父類的構造
5.5 重寫與多型
重寫:子類的方法與父類的方法必須相同,但是方法體不同
為什麼需要重寫:
- 父類的功能子類不一定需要或者不一定滿足
重寫的條件:
- 方法名必須相同
- 引數列表必須相同
- 修飾符:範圍可以擴大但是不能縮小
- 丟擲的異常:範圍可以被縮小但是不能擴大
多型:即同一方法可以根據傳送物件的不同而採取多種不同行為
- 一個物件的實際型別是確定的,但是指向這個物件的引用的型別卻有很多
- instanceof
存在的條件:
- 有繼承關係
- 子類重寫父類方法
- 父類引用指向子類物件
注意事項:
- 多型是指方法的多型,屬性沒有多型
- 父類和子類,有聯絡
- 繼承關係,方法需要重寫,父類引用指向子類物件
靜態方法的呼叫(不叫重寫)
class A{
public static void test(){
System.out.println("A==>test()");
}
}
public class B extends A{
public static void test(){
System.out.println("B==>test()");
}
public static void main(String[] args) {
// 構造一個A類的物件
A a1 = new A();
a1.test();
// 父類引用指向了子類
A a2 = new B();
a2.test();
}
}
執行結果:
A==>test()
A==>test()
分析:靜態方法的呼叫只和左邊,即定義的資料型別有關
非靜態方法的重寫與呼叫
class A{
public void test(){
System.out.println("A==>test()");
}
}
public class B extends A{
// 子類重寫了父類的方法
public void test(){
System.out.println("B==>test()");
}
public static void main(String[] args) {
// 構造一個A類的物件
A a1 = new A();
a1.test();
// A型別的變數實際接受B型別的物件
A a2 = new B();
a2.test();
}
}
執行結果:
A==>test()
B==>test()
分析:非靜態方法的呼叫和左邊和右邊都有關
- 物件能否執行方法?得看指向這個物件的引用類中有沒有這個方法,即父類指向子類,不能呼叫子類獨有的方法
- 物件執行什麼方法?得看右邊物件實際的型別來決定
5.6
class A{
}
public class B extends A{
public static void main(String[] args) {
B bb = new B();
System.out.println(bb instanceof A);
}
}
執行結果:
true
6、static
“static方法就是沒有this的方法。在static方法內部不能呼叫非靜態方法,反過來是可以的。而且可以在沒有建立任何物件的前提下,僅僅通過類本身來呼叫static方法。這實際上正是static方法的主要用途。”
用途:方便在沒有建立物件的情況下來進行呼叫(方法/變數)。
- static方法
static方法一般稱作靜態方法,因為不依賴任何物件,所以不存在this。
在靜態方法中不能訪問類的非靜態成員變數和非靜態成員方法,因為非靜態成員方法/變數都是必須依賴具體的物件才能夠被呼叫。
- static變數
static變數也稱作靜態變數,靜態變數和非靜態變數的區別是:靜態變數被所有的物件所共享,在記憶體中只有一個副本,它當且僅當在類初次載入時會被初始化。而非靜態變數是物件所擁有的,在建立物件的時候被初始化,存在多個副本,各個物件擁有的副本互不影響。
static成員變數的初始化順序按照定義的順序進行初始化。
- static程式碼塊
static關鍵字還有一個比較關鍵的作用就是 用來形成靜態程式碼塊以優化程式效能。static塊可以置於類中的任何地方,類中可以有多個static塊。在類初次被載入的時候,會按照static塊的順序來執行每個static塊,並且只會執行一次。
因此,很多時候會將一些只需要進行一次的初始化操作都放在static程式碼塊中進行。
注意
與C/C++中的static不同,Java中的static關鍵字不會影響到變數或者方法的作用域
在Java中能夠影響到訪問許可權的只有private、public、protected(包括包訪問許可權)這幾個關鍵字
在C/C++中static是可以作用域區域性變數的,但是在Java中切記:static是**不允許用來修飾區域性變數****
7、抽象類
// 抽象類, 抽象的抽象
public abstract class Action{
// 制定約束,讓別人來實現
// 只有方法定義,沒有方法的具體實現
public abstract void doSomething();
}
- 抽象類不能建立物件,即不能new,只能靠子類去實現,而它本身只是制定了約束
- 抽象類中可以寫普通的方法
- 抽象方法必須在抽象類中,即如果一個類包含抽象方法,那麼該類必須是抽象類。
- 抽象類中不一定包含抽象方法,但是有抽象方法的類必定是抽象類。
- 任何子類必須重寫父類的抽象方法,或者宣告自身為抽象類。
- 構造方法,類方法(用 static 修飾的方法)不能宣告為抽象方法。
抽象類的建構函式
雖然抽象類不能被例項化,但可以有建構函式。由於抽象類的建構函式在例項化派生類之前發生,所以,可以在這個階段初始化抽象類欄位或執行其它與子類相關的程式碼。
8、介面
普通類:只有具體實現
抽象類:具體實現和規範(抽象方法)都有
介面:只有規範,專業的約束,約束和實現分離:面向介面程式設計
關鍵字:interface implements
- 介面中的所有方法的定義都是抽象的,即public abstract,可省略,屬性都為public static final
- java不支援多繼承,但是支援實現多介面,間接實現多繼承
- 介面沒有構造方法
interface A {
void say();
}
// 實現介面
public class Action implements A{
@Override
public void say() {
System.out.println("Hello World!");
}
public static void main(String[] args) {
new Action().say();
}
}
執行結果:
Hello World!
9、內部類(奇葩!)
首先說明本質:無限套娃
9.1 成員內部類
public class Outer{
int age = 11;
public void out(){
System.out.println("外部類的方法");
}
// 成員內部類
public class Inner{
public void in(){
System.out.println("內部類的方法");
}
}
public static void main(String[] args) {
// 正常建立物件的形式
Outer outer = new Outer();
// 呼叫成員內部類的方法
// 通過Outer的物件new一個Inner的物件,用Outer.Inner型別的引用接受
Outer.Inner in = outer.new Inner();
in.in();
}
}
9.2 區域性內部類
public class Outer{
public void method(){
// 區域性內部類
class Inner {
public void in(){
}
}
}
}
9.3 匿名內部類
interface User{
void say();
}
public class Outer{
public static void main(String[] args) {
new User(){
@Override
public void say() {
System.out.println("實現了介面的方法");
}
};
}
}