Day06 JavaSE面向對象OOP(上) (Object-Oriented Programming)

JavaSE 面向對象OOP(上)

一、面向對象概述

1 面向過程&面向對象區別

  • 面向過程

    • 第一步做什麼,第二步做什麼…
    • 面向過程適合處理一些簡單的問題。
  • 面向對象

    • 分類的思維模式,首先分類,隨後逐個解決分類下的細節。
    • 面向對象適合處理負責的問題,適合多人協作的問題。
    • 以類的方式組織代碼,以對象組織封裝數據
  • 面向對象三大特性:封裝、繼承、多態

2 方法回顧+補充

  • 方法的定義
    • 修飾符
    • 返回類型
    • break: 跳出循環或switch, return:結束方法
    • 方法名:注意命名規範 見名知意
    • 參數列表:(參數類型,參數名) …
    • 異常拋出: 隨後填坑。
  • 方法的調用
    • 靜態方法
    • 非靜態方法
    • 實參、形參
    • 值傳遞(Java)和引用傳遞 可查看我之前的blog,點擊查看詳情
    • this關鍵字

靜態方法和非靜態方法調用的補充案例:

package com.oop.demo01;
//該類內含靜態方法與非靜態方法
public class Student {
    //static 修飾的方法和類一起加載的
    //而非靜態方法是在類實例化之後生成

    //靜態方法
    public static void say(){
        System.out.println("Say!");
    }
    //非靜態方法
    public void write(){
        System.out.println("Write!");
    }
}
package com.oop.demo01;
//該類爲測試類
public class Demo02 {
    public static void main(String[] args) {
        //靜態方法 static
        //調用方法:類名.方法名;
        Student.say(); //Say!

        //非靜態方法 沒有static
        //調用方法:對象類型 對象名 = new 對象類名; 使用實例對象操作方法;
        Student st = new Student();
        st.write();//Write!
    }
}

注意兩種方法各自的調用方式!

3 類和對象

  • 類是一種抽象的數據類型,它是對某一類事物的整體描述/定義,但是並不能代表某個具體的事物。
  • 對象是類的實例。
  • 也可理解爲:類是一個模版:抽象; 對象是一個具體的實例。

創建類和對象的案例:

package com.oop.demo02;

//學生類 (屬性+方法)
public class Student {

    //屬性:字段/成員變量
    String name;//null
    int age; //0

    //方法:
    public void study(){
        System.out.println(this.name+" is studying");
    }
    public void nostudy(){ System.out.println(this.name+" is not studing");}
}
package com.oop.demo02;

//測試類:一個項目應該只有一個main方法
public class Application {
    public static void main(String[] args) {

        //類:抽象的,實例話
        //類實例化後會返回一個自己的對象
        //對象就是一個Student類的具體實例

        Student j = new Student();
        Student d = new Student();

        j.name = "Jever";
        j.age = 19;
        d.name = "Demut";
        d.age = 23;

        System.out.println(j.name);
        j.study();
        System.out.println(d.name);
        d.nostudy();
    }
}
//運行結果:
/*
運行結果:
Jever
Jever is studying
Demut
Demut is not studing
 */

4 創建對象 <-構造器->

  • 構造器:

    • 和類名相同
    • 沒有返回值
  • 作用:

    • new 本質是在調用構造器
    • 初始化對象的值
  • 注意:

    • 定義了有參構造之後,如果想使用無參構造,需要顯示的定義一個無參的構造器。
  • 構造器案例:

    package com.oop.demo02;
    //Person類(此類僅包含屬性與構造器)
    public class Person {
        String name;
        int age;
    
        //實例化初始值
        //無參構造器
        public Person(){
        }
    
        //有參構造器
        public Person(String name, int age){
            this.name = name;
            this.age = age;
        }
    }
    
    package com.oop.demo02;
    //測試類
    public class Application2 {
        public static void main(String[] args) {
            //使用有參量的構造器
            Person person = new Person("Jever",19);
    
            System.out.println(person.name);    //Jever
            System.out.println(person.age);     //19
        }
    }
    

5 創建對象內存分析

  • 代碼如下:
package com.oop.demo03;
//Pet類  (屬性+方法)
public class Pet {
    String name;
    int age;

    //無參構造會自動生成

    public void shout(){
        System.out.println("Shouting!");
    }
    public static void eat(){
        System.out.println("Eating");
    }
}
package com.oop.demo03;
//測試類 生成兩實例對象,並進行操作
public class Application {
    public static void main(String[] args) {
        Pet dog = new Pet();
        dog.name =  "旺財";
        dog.age = 3;
        dog.shout();
        System.out.println(dog.name);
        System.out.println(dog.age);
        Pet cat = new Pet();
        Pet.eat();
    }
}
  • 該過程示意圖如下:
    對象生成示意圖

二、面向對象三大特性

1 封裝

  • 該露的露,該藏的藏

    • 程序設計要追求“高內聚,低耦合”。高內聚就是類的內部數據操作細節自己完成,不允許外部干涉;低耦合指僅僅暴露少量的方法給外部使用。
  • 封裝值數據的隱藏

    • 通常應禁止直接方位一個對象中數據的實際表示,而是應通過操作接口來訪問,這稱爲封裝。
  • 屬性私有,get/set(可在set中進行安全性的判斷)

  • 封裝的作用:

    • 提高程序安全性,保護數據
    • 隱藏代碼的實現細節
    • 統一接口
    • 增加系統可維護性

案例展示:

package com.oop.demo04;
//屬性私有,get/set
public class Student {
    //以下屬性私有,數據被封裝
    private String name;  //姓名
    private int id;     //學號
    private char gender;  //性別
    private int age; //年齡 注意不可無限增長

    //提供一些可以操作私有屬性的方法!
    //提供public 的get、set方法

    //get 獲得這個數據
    public String getName(){
        return this.name;
    }
		public int getAge(){
        return this.age;
    }
    
    //set 給私有數據設置值
    public void setName(String name){
        this.name = name;
    }
    public void setAge(int age){//進行安全性判斷
        if (age>110 || age<0){//不合法
            this.age = 0;
        }else {
            this.age = age;
        }
    }
}
package com.oop.demo04;
//測試類
public class Application {
    public static void main(String[] args) {
        Student s1 = new Student();
        s1.setName("Jever");
        System.out.println(s1.getName());
        s1.setAge(999);
        System.out.println(s1.getAge());
    }
}

2 繼承

2.1 繼承基礎

  • 繼承的本質是對某一批類的抽象,從而實現對現實世界更好的建模。
  • 使用關鍵字extends(擴展)。子類是父類的擴展。
  • Java中類只有單繼承,沒有多繼承。
  • 所有類默認繼承object類。

繼承案例:

package com.oop.demo05;
//Person類:父類
public class Person {
    //public
    //protected
    //default
    //private
    private String name; //子類無法繼承

    public void say(){
        System.out.println("I am saying!");
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getName() {
        return name;
    }
}
package com.oop.demo05;
//學生類
public class Student extends Person{}
package com.oop.demo05;
//測試類
public class Application {
    public static void main(String[] args) {
        Student st = new Student();
        st.say();
    }
}

注意訪問時方法權限的問題!

2.2 super詳解

注意:

  1. super調用父類的構造方法,必須在構造方法的第一個
  2. super必須只能出現在子類的方法或者構造方法中!
  3. super和this不能同時調用構造方法!

VS this:

  • 代表對象不同:

    • this: 調用本類對象;
    • super: 代表父類對象應用
  • 前提:

    • this:沒有繼承時也可以使用;
    • super:只能在繼承條件下纔可以使用。
  • 構造方法:

    • this():本類的構造;
    • super(): 父類的構造。

案例展示:

package com.oop.demo05;
//在Java中,所有的類都默認繼承Object類。
//Person類:父類
public class Person {
    public Person(){
        System.out.println("Person無參構造器!");
    }

    protected String name = "Demut";
    public void print(){
        System.out.println("Person");
    }
}
package com.oop.demo05;
//學生類
public class Student extends Person{
  
    public Student(){
        //此處隱藏了super();
        //調用了父類的無參構造器,且調用父類的構造器語句必須在子類的第一行。
        super();
        System.out.println("Student無參構造器!");

    }

    private String name = "Jever";
    public void print(){
        System.out.println("Student");
    }
    public void test1(){
        System.out.println(this.name);//使用this訪問本類中name  Jever
        System.out.println(super.name);//使用super訪問父類中name  Demut
    }
    public void test2(){
        this.print(); //使用this訪問本類中方法  Student
        super.print(); //使用super訪問父類中的方法  Person
    }
}
package com.oop.demo05;
//測試類
public class Application {
    public static void main(String[] args) {
        Student s = new Student();
        s.test1();
        s.test2();
    }
}
/*
測試結果:
    Person無參構造器!
    Student無參構造器!
    Jever
    Demut
    Student
    Person
 */

2.3 方法重寫

(父類的功能,子類不一定需要,或者不一定滿足!故需要重寫)

重點:需要有繼承關係,子類重寫父類的方法!

  1. 方法名必須相同
  2. 參數列表必須相同
  3. 修飾符:範圍可以擴大但不能縮小: public -> protected -> default -> private
  4. 拋出異常:範圍可以被縮小但不能擴大。(破洞只能越填越小)

重寫中子類的方法和父類方法頭一致;方法體不同!

  • 案例展示:

    package com.oop.demo05;
    //父類:A
    public class A {
        public static void test(){
            System.out.println("A=>test()");
        }
        public void test2(){
            System.out.println("A=>test2()");
        }
    }
    
    package com.oop.demo05;
    //子類:B
    public class B extends A{
        public static void test(){
            System.out.println("B=>test()");
        }
        @Override//重寫
        public void test2() {
            System.out.println("B=>test2()");
        }
    }
    
    package com.oop.demo05;
    //測試類
    public class Application2 {
    
        //靜態方法和非靜態方法的區別很大!!!
        //重寫與靜態方法無關,只與非靜態有關!
        public static void main(String[] args) {
            //方法的調用只和左邊定義的數據類型有關。
            B b = new B();
            b.test();   //B=>test()
            //父類的引用指向了子類
            A a = new B();
            a.test();   //A=>test()
    
            b.test2();  //B=>test2()
            a.test2();  //B=>test2()
        }
    }
    

寫在最後

熱愛可抵歲月漫長!

To Demut and Dottie!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章