目錄
一.類和物件的初步認知
1.面向程序和面向物件
2.面向物件設計
二.類和類的實體化
1.什么是類
2.類的實體化
三.類的成員
1.成員變數
2.方法
3.static關鍵字
靜態成員變數
靜態成員變數儲存方式
靜態成員方法
總結-必看!!!
4.toString方法
5.匿名物件
四.封裝
1.private實作封裝
2.getter和setter方法
五.構造方法
1.基本語法
2.this關鍵字
六.代碼塊
1.什么是代碼塊
2.本地代碼塊
3.實體代碼塊
4.靜態代碼塊
一.類和物件的初步認知
1.面向程序和面向物件
面向程序:C語言是面向程序的,關注的是程序,分析出求解問題的步驟,通過函式呼叫逐步解決問題
面向物件:JAVA是基于面向物件的,關注的是物件,將一件事情拆分成不同的物件,靠物件之間的互動完成
面向程序:注重的是程序,在整個程序中所涉及的行為,就是功能,
面向物件:注重的是物件,也就是參與程序所涉及到的主體,是通過邏輯將一個個功能實作連接起來
舉個例子: 這里把衣服放進洗衣機、啟動洗衣機和將衣服拿出洗衣機都是對洗衣機的操作,這里洗衣機就是一個物件,洗衣機洗衣服的功能就包含在這個物件中,

2.面向物件設計
面向物件設計把握一個重要的經驗:誰擁有資料,誰對外提供操作這些資料(私有)的方法!

二.類和類的實體化
1.什么是類
類就是一類物件的統稱,物件就是這一類具體化的一個實體,
舉一個通俗的例子:我們在做餅干的時候會用到模具,模具就是一個類,而模具做出來的餅干就是物件,一個模具能做出多個餅干,那么一個類也能實體化多個物件,接下來用一段代碼來展示具體用法:
class Person{
//成員變數/欄位/屬性
public String name;
public String sex;
public int age;
//成員方法/行為
public void show(String name,String sex,int age){
System.out.println("姓名:"+name+" 性別:"+sex+" 年齡:"+age);
}
}
2.類的實體化
定義:用型別別創建物件的程序,稱為類的實體化
1. 類只是一個模型一樣的東西,限定了類有哪些成員
2. 一個類可以實體化出多個物件,實體化出的物件 占用實際的物理空間,存盤類成員變數
3. 做個比方,類實體化出物件就像現實中使用建筑設計圖建造出房子,類就像是設計圖,只設計出需要什么東 西,但是并沒有物體的建筑存在,同樣類也只是一個設計,實體化出的物件才能實際存盤資料,占用物理空間
那么怎么實體化一個物件呢?我們通過new來實作
怎么呼叫類里面的方法呢?我們可以通過 物件參考.成員變數/成員方法 來呼叫類里面創建的變數及方法,
接下來上一段代碼具體演示一下操作:
class Person{
//成員變數/欄位/屬性
public String name;
public String sex;
public int age;
//成員方法/行為
public void show(String name,String sex,int age){
System.out.println("姓名:"+name+" 性別:"+sex+" 年齡:"+age);
}
}
public class TestDemo {
public static void main(String[] args) {
Person person = new Person();//實體化物件
person.show("Sarah","女",18);//呼叫show方法
}
}
就跟我們上面舉的例子一樣,通過一份設計圖能建造多個房子,那么一個類也能實體化多個物件!

class Person{
//成員變數/欄位/屬性
public String name;
public String sex;
public int age;
//成員方法/行為
public void show(String name,String sex,int age){
System.out.println("姓名:"+name+" 性別:"+sex+" 年齡:"+age);
}
}
public class TestDemo {
public static void main(String[] args) {
//實體化多個物件
Person person1 = new Person();
Person person2 = new Person();
person1.show("Sarah","女",18);
}
}
三.類的成員
類的成員可以包含以下:欄位、方法、代碼塊、內部類和介面等,這里我們重點講解一下前三個
1.成員變數
定義在類中 、在方法外部的變數,我們稱為 "欄位" 或 "屬性" 或 "成員變數"(三種稱呼都可以, 一般不會嚴 格區分)
我們來看一段代碼,試著輸出一下成員變數的值
class Person{
//成員變數/欄位/屬性
public String name;
public String sex;
public int age;
}
public class TestDemo {
public static void main(String[] args) {
//實體化多個物件
Person person = new Person();
System.out.println(person.name);
System.out.println(person.sex);
System.out.println(person.age);
}
}

這里我們并沒有初始化這三組成員變數,為什么還能輸出null、null、0呢?我們在資料型別里面提到過,如果一個物件的成員變數沒有顯式設定初始值,將會輸出默認值,下面是默認值規則,供大家參考:

注意:不能對null進行訪問操作!因為null代表空參考,類似于C語言中的空指標,如果進行訪問操作則會發生例外
2.方法
就像我們前面講的洗衣機是一個物件,那么洗衣機洗衣服的功能就是洗衣機這個物件的方法這里,方法的定義就是 用于描述一個物件的行為!
class Person{
public String name ;
public int age;
public void show(String name,int age){
System.out.println("我叫"+name+",我今年"+age+"歲");
}
}
public class Test {
public static void main(String[] args) {
Person person = new Person();
person.show("Sarah",18);
}
}
這里的show方法就是person這個物件自我展示的行為!需要注意的是,這樣的 show 方法是和 person 實體相關聯的. 如果創建了其他實體, 那么 show 的行為就會發生變化
class Person{
public String name ;
public int age;
public void show(String name,int age){
System.out.println("我叫"+name+",我今年"+age+"歲");
}
}
public class Test {
public static void main(String[] args) {
Person person = new Person();
person.show("Wsy",18);
}
}

3.static關鍵字
靜態成員變數
我們成員變數分為 普通成員變數和靜態成員變數
普通成員變數也叫做實體的成員變數,靜態成員變數也叫做類變數
首先我們來看看怎么訪問靜態成員變數
class Demo{
//成員變數/欄位/屬性
public static int num1;//創建一個靜態成員變數
public int num2;//創建一個普通成員變數
}
public class TestDemo {
public static void main(String[] args) {
Demo demo = new Demo();
System.out.println(Demo.num1);
System.out.println(demo.num1);
}
}

我們發現通過方法名.靜態成員變數雖然能得到結果,但是會有警告,所以我們最好通過類.靜態成員變數來訪問 靜態成員變數
靜態成員變數儲存方式
我們知道物件是儲存到堆疊上的,那么靜態成員變數是儲存到哪的呢?
class Demo{
//成員變數/欄位/屬性
public static int num1;//創建一個靜態成員變數
public int num2;//創建一個普通成員變數
}
public class TestDemo {
public static void main(String[] args) {
Demo demo = new Demo();
Demo.num1++;
demo.num2++;
System.out.println(Demo.num1);
System.out.println(demo.num2);
System.out.println("-------------------");
Demo demo1 = new Demo();
Demo.num1++;
demo1.num2++;
System.out.println(Demo.num1);
System.out.println(demo1.num2);
}
}
來看看運行結果:

為什么在第二次++后num1和num2的值不一樣呢?我們發現他們一個是靜態成員變數,一個是成員變數,我們來具體分析一下他們儲存的位置

通過分析,我們發現由static修飾的靜態成員變數壓根不依賴于物件!因為它并沒有存放在堆上面,而是放在方法區里!無論你new多少個物件,num1就這么一個,所以num1的結果是2!
來看一個例子來看看靜態成員變數的特點
class Demo{
//成員變數/欄位/屬性
public static int num1;//創建一個靜態成員變數
public int num2;//創建一個普通成員變數
}
public class TestDemo {
public static void main(String[] args) {
Demo.num1++;
System.out.println(Demo.num1);
}
}

我們知道,如果訪問普通成員變數不初始化一個物件是會報錯的!但是靜態成員變數卻能正常運行!歸根結底,還是我們前面說的,靜態成員變數不依賴于物件!!
我們再來看一段代碼看看是否會報錯
class Demo{
//成員變數/欄位/屬性
public static int num1;//創建一個靜態成員變數
public int num2;//創建一個普通成員變數
}
public class TestDemo {
public static void main(String[] args) {
Demo demo = null;
System.out.println(demo.num1);
}
}

我們前面提到了,null.任何東西都會出現空指標參考例外,那么這個時候為什么不報錯呢?這里的 demo代表demo不指向任何物件,而我們已經說過靜態成員變數的訪問時不依賴于物件的,所以這里并沒有發生例外,但如果通過 demo訪問普通成員變數的話就會報錯!
靜態成員方法
成員方法也分為兩種,一種是普通成員方法,一種是靜態成員方法,
普通的成員方法又叫做實體的成員方法,靜態的成員方法也叫做類方法,
我們先來看一下靜態成員方法如何呼叫!請看代碼
class Demo{
//成員變數/欄位/屬性
public String name;
public static void eat(String name){
System.out.println(name+"在吃飯");
}
public void sleep(String name){
System.out.println(name+"在睡覺");
}
}
public class TestDemo {
public static void main(String[] args) {
Demo.eat("Sarah");
}
}

靜態成員方法能直接通過 類名.方法進行訪問 而普通成員方法需要先實體化一個物件,然后通過 物件名.方法 進行訪問
同理可推到出,在靜態的成員方法內部也是不可以呼叫普通成員方法的,除非實體化一個物件

注意:我們曾經寫的方法為了方便直接呼叫, 都統一加上了 static. 但實際上一個方法具體要不要帶 static, 都需要是情形而定.
靜態的在類加載的時候就已經定義好了,具體在后面的JVM中會講解到,
總結-必看!!!
普通方法內部:不能定義靜態方法變數static 能呼叫靜態方法
靜態方法內部:可以通過實體化物件來呼叫普通方法
4.toString方法
關于toString方法,我們來看一段代碼
class Person{
public String name ;
public int age;
public void show(String name,int age){
System.out.println("我叫"+name+",我今年"+age+"歲");
}
}
public class Test {
public static void main(String[] args) {
Person person = new Person();
System.out.println(person);
}
}

這里先科普一下序列化和反序列化
序列化:把一個物件變成字串
反序列化:把字串變成對像
我們發現這里列印的是一個地址,按住ctrl,點擊println,發現呼叫的是valueOf方法,同樣的方法發現最后呼叫的是Object 的 toString 方法來列印

我們可以自己寫一個toString方法,大家可以自己去實作,這里主要講IDEA自己生成的toString方法,快捷鍵是alt+insert

使用toString方法的代碼和運行結果如下
class Person{
public String name ;
public int age;
public void show(String name,int age){
System.out.println("我叫"+name+",我今年"+age+"歲");
}
@Override//重寫
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
public class Test {
public static void main(String[] args) {
Person person = new Person();
System.out.println(person);
}
}

ps:雙引號里面的內容可以自己進行修改
5.匿名物件
沒有參考的物件稱為匿名物件
匿名物件只能在創建物件時使用
如果一個物件只是用一次, 后面不需要用了, 可以考慮使用匿名物件
用法展示:
public static void main(String[] args) {
new Person().name = "Sarah";
new Person().age = 18;
}
四.封裝
面向物件編程的三大特征:繼承 封裝 多型
在我們寫代碼的時候經常會涉及兩種角色: 類的實作者和類的呼叫者
封裝的本質:讓類的呼叫者不必太多的了解類的實作者是如何實作類的, 只要知道如何使用類就行了. 這樣就降低了類使用者的學習和使用成本, 從而降低了復雜程度
1.private實作封裝
private/ public 這兩個關鍵字表示 " 訪問權限控制 " .被 public 修飾的成員變數或者成員方法 , 可以直接被類的呼叫者使用被 private 修飾的成員變數或者成員方法 , 不能被類的呼叫者使用
具體private應該在哪種情況下使用呢 ,我們來看一段代碼
class Person{
public String name = "張三";
public int age = 18;
}
public class Test {
public static void main(String[] args) {
Person person = new Person();
System.out.println("我叫"+person.name+",我今年"+person.age+"歲");
}
}
這段運行起來沒有任何問題,但是如果我們想把name改成myName,類的使用者就必須大規模得修改自己的代碼,其次,類的使用者也必須清楚Person類內部的實作,這樣學習成本太高,那么這個時候,我們可以使用封裝
class Person{
private String name ;
private int age;
public void show(){
System.out.println("我叫"+name+",我今年"+age+"歲");
}
}
public class Test {
public static void main(String[] args) {
Person person = new Person();
person.show("Sarah",18);
}
}

1.此時欄位已經使用 private 來修飾, 類的呼叫者 (main 方法中 ) 不能直接使用, 而需要借助 show 方法, 此時類的使 用者就不必了解 Person 類的實作細節2.同時如果類的實作者修改了欄位的名字, 類的呼叫者不需要做出任何修改 ( 類的呼叫者根本訪問不到 name, age 這樣的欄位)
private 不光能修飾欄位, 也能修飾方法通常情況下我們會把欄位設為 private 屬性, 但是方法是否需要設為 public, 就需要視具體情形而定 . 一般我們希望一個類只提供 " 必要的 " public 方法, 而不應該是把所有的方法都無腦設為 public
2.getter和setter方法
class Person{
private String name ;
private int age;
public void show(){
System.out.println("我叫"+name+",我今年"+age+"歲");
}
}
public class Test {
public static void main(String[] args) {
Person person = new Person();
person.name = "Sarah";
person.show();
}
}
這段代碼報錯,我們來看看報錯原因:
這個時候,如果需要獲取/修改private這個屬性,就需要使用gette和setter方法
class Person{
private String name ;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;//this參考,呼叫該方法的物件
}
public void show(){
System.out.println("我叫"+name+",我今年"+age+"歲");
}
}
public class Test {
public static void main(String[] args) {
Person person = new Person();
person.setName("Sarah") ;
person.setAge(18);
person.show();
}
}
getName 即為 getter 方法, 表示獲取這個成員的值setName 即為 setter 方法, 表示設定這個成員的值當 set 方法的形參名字和類中的成員屬性的名字一樣的時候,如果不使用 this, 相當于自賦值, this 表示當前實體的參考
生成getter和setter方法的快捷鍵跟生成toString方法一樣:alt+insert
五.構造方法
1.基本語法
構造方法是用來構造物件的,是一種特殊方法,使用new關鍵字實體化物件的時候會被自動呼叫,用于完成初始化操作
1. 方法名稱必須與類名稱相同2.構造方法沒有回傳值型別宣告3. 每一個類中一定至少存在一個構造方法(沒有明確定義,則系統自動生成一個無參構造)
1.如果類中沒有提供任何的建構式,那么編譯器會默認生成一個不帶有引數的建構式2.若類中定義了構造方法,則默認的無參構造將不再生成3.構造方法支持多載 . 規則和普通方法的多載一致
class Person{
private String name ;
private String sex ;
private int age;
//默認建構式 構造物件
public Person(){
this.name = "A";
this.sex = "男";
this.age = 18;
}
//帶有三個引數的構造方法
public Person(String name,String sex,int age){
this.name = name;
this.sex = sex;
this.age = age;
}
public void show(){
System.out.println("name: "+name+" sex: "+sex+" age: "+age);
}
}
public class Test {
public static void main(String[] args) {
Person person1 = new Person();
person1.show();
Person person2 = new Person("B","女",18);
person2.show();
}
}

2.this關鍵字
this代表當前物件的參考
this關鍵字共有三種使用方法
1.this.data:呼叫當前物件的屬性
2.this.func():呼叫當前物件的方法
3.this():呼叫當前物件的其他構造方法 (只能存放在建構式中)
接下來我們具體看看怎么使用,第一種用法其實我們在上面已經使用過,第二種用法也跟第一種用法大同小異,只不過一個呼叫的是屬性,一個呼叫的是方法
public Person(String name,String sex,int age){
this.name = name;
this.sex = sex;
this.age = age;
}
接下來我們具體講一下第三種使用
public Person(){
this("A","女",18);
}
需要注意的是,this()只能呼叫一個構造方法,且必須放在構造方法里的第一行使用
六.代碼塊
1.什么是代碼塊
代碼塊就是使用{}定義的一段代碼
代碼塊分為四種:
本地代碼塊、靜態代碼塊、實體代碼塊、同步代碼塊
2.本地代碼塊
public class Main {
public static void main(String[] args) {
{
int a = 10;
System.out.println(a);
}
}
}
用法比較少見,這里不再贅述
3.實體代碼塊
也叫構造代碼塊,一般用于初始化實體成員變數
class People{
private String name;
private int age;
{
this.name = "A";
this.age = 18;
}
public void show(){
System.out.println("name: "+name+" age: "+age);
}
}
public class Main {
public static void main(String[] args) {
People p = new People();
p.show();
}
}
4.靜態代碼塊
使用 static 定義的代碼塊, 一般用于初始化靜態成員屬性,
class People{
private String name;
private int age;
private static int count = 0;//靜態成員變數 由類共享資料 方法區
{
this.name = "A";
this.age = 18;
System.out.println("I am instance init()!");
}
static {
count = 10;//只能訪問靜態資料成員
System.out.println("I am static init()!");
}
public void show(){
System.out.println("name: "+name+" age: "+age);
}
}
public class Main {
public static void main(String[] args) {
People p = new People();
p.show();
}
}

所以我們知道執行順序為:
靜態代碼塊(只能執行一次、不能呼叫this方法、不被實體化都能執行)
實體代碼塊
構造方法
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/351037.html
標籤:其他
上一篇:設計模式(二)————觀察者模式
