1. 程式人生 > 實用技巧 >Java面向物件簡單筆記

Java面向物件簡單筆記

面向物件程式設計(oop)

面向過程&面向物件

  1. 面向過程思想(線性思維)

步驟清晰簡單,第一步做什麼,第二步做什麼.....面

對過程適合處理一些較為簡單的問題

  1. 面向物件思想

物以類聚,分類的思維模式,思考問題首先會解決問題需要哪些分類,然後對這些分類進行單獨思考。最後,才對某個分類下的細節進行面向過程的思索。

面向物件適合處理複雜的問題,適合處理需要多人協作的問題!

  1. 對於描述複雜的事物,為了從巨集觀上把握、從整體上合理分析,我們需要使用面向物件的思路來分析整個系統。但是,具體到微觀操作,仍然需要面向過程的思路去處理。

什麼是面向物件

面向物件程式設計(Object-Oriented Programming, OOP)

面向物件程式設計的本質就是:以類的方式組織程式碼,以物件的形式組織(封裝)資料。

抽象 程式設計思想,持續的學習

三大特性:
封裝:包裝
繼承
多型

從認識論角度考慮是先有物件後有類。物件,是具體的事物。類,是抽象的,是對物件的抽象

從程式碼執行角度考慮是先有類後有物件。類是物件的模板。

方法及加深:

方法的定義:

  1. 修飾符

  2. 返回型別

      /*
        修飾符 返回值型別  方法名(...){
         //方法體
         return 返回值;
         }
         */
        public String sayHello() {
            return "Hello world";
        }
    
  3. break和return的區別:break跳出語句,結束迴圈;return結束方法,返回一個結果!

  4. 方法名:注意規範,駝峰命名,見名知意

  5. 引數列表:(引數型別,引數名)...

  6. 異常丟擲,

方法的呼叫:遞迴

  1. 靜態方法

  2. 非靜態方法

  3. 形參和實參

    程式碼:

    package com.oop.demo01;
    
    public class Demo03 {
        public static void main(String[] args) {
            //實際引數和形式引數的型別要對應!
            int add = Demo03.add(1, 5);
            System.out.println(add);
        }
    
        public static int add(int a, int b) {
            return a + b;
        }
    }
    
    
  4. 值傳遞和引用傳遞

    引用傳遞:

    package com.oop.demo01;
    
    //引用傳遞:物件,本質還是值傳遞
    public class Demo05 {
        public static void main(String[] args) {
            Person person = new Person();
            System.out.println(person.name);  //輸出null
    
            Demo05.change(person);
            System.out.println(person.name);  //ljy
        }
    
        public static void change(Person person) {
    
            //person是一個物件,指向的--->Person person = new Person();這是一個具體的人,可以改變屬性
            person.name = "ljy";
        }
    }
    
    //定義一個Person類,有一個屬性:
    class Person {
        String name;  //預設值為null
    }
    

值傳遞:

package com.oop.demo01;

//值傳遞
public class Demo04 {
    public static void main(String[] args) {
        int a = 1;
        System.out.println(a);

        Demo04.change(a);
        System.out.println(a);

    }

    //返回值為空
    public static void change(int a) {
        a = 10;

    }
}

  1. this關鍵字

類與物件的關係

類是一種抽象的資料型別,它是對某一類事物整體描述/定義,但是並不能代表某一個具體的事物

  1. 動物、植物、手機
  2. Person類、Pet類、Car類,這些類都是用來描述/定義某一類具體的事物應該具備的特點和行為

物件是抽象概念的具體例項

  1. 張三就是人的一個具體例項,張三家裡的旺財就是狗的一個具體例項。
  2. 能夠體現出特點,展現出功能的是具體的例項,而不是一個抽象的概念.

建立與初始化物件

使用new關鍵字建立物件

使用new關鍵字建立的時候,除了分配記憶體空間之外,還會給建立好的物件進行預設的初始化以及對類中構造器的呼叫。

類中的構造器也稱為構造方法,是在進行建立物件的時候必須要呼叫的。並且構造器有以下倆個特點:

  1. 必須和類的名字相同
  2. 必須沒有返回型別,也不能寫void

構造器必須要掌握

構造器作用:

  1. 使用new關鍵字,本質是在呼叫構造器

  2. 用來初始化值

構造器:

  1. 和類名相同
  2. 沒有返回值

注意點:定義有參構造之後,如果想使用無參構造,顯示的定義一個無參構造

程式碼練習:

package com.oop.Demo02;

//學生類
public class Student {

    //屬性:欄位
    String name;  //預設null
    int age;    // 預設0

    //方法
    public void stduy() {
        System.out.println(this.name + "在學習");
    }
}
 /*  //這個專案測試類  可以在Application中直接使用
  public static void main(String[] args) {
         //類:抽象的,例項化
        //類例項化後會返回一個自己的物件!
        //student物件就是一個Student類的具體例項

        Student 小明 = new Student();
        小明.name="小明明";
        小明.age=3;
        System.out.println(小明.name);
        System.out.println(小明.age);
    }
  */
package com.oop.Demo02;

//java--->class
public class Person {
    //一個類即使什麼都不寫 它也會存在一個方法
    //顯示的定義構造器
    String name;

    //例項化初始值
    public Person() {
        this.name = "ljy";
    }

    //有參構造:一旦定義了有參構造,無參就必須顯示定義
    public Person(String name) {
        this.name = name;
    }
}


/*
 public static void main(String[] args) {
        //new 例項化了一個物件
        Person person = new Person();
        System.out.println(person.name);
    }

 */

練習程式碼:

package com.oop.Demo03;

public class Pet {
    public String name;
    public int age;
    //無參構造

    public void shout() {
        System.out.println("叫了一聲");
    }
}
  /*
      public static void main(String[] args) {
        Pet dog = new Pet();
        dog.name = "xzl";
        dog.age = 20;
        dog.shout();

        System.out.println(dog.age);
        System.out.println(dog.name);

    }
   */

alt+insert 自動生成構造器

簡單小結類與物件

  1. 類與物件

    類是一個模板:抽象 ,物件是一個具體的

  2. 方法:

    定義、呼叫!

  3. 物件的引用

引用型別: 對應的基本型別(8個)

物件是通過引用來操作的:棧----->堆

  1. 屬性:欄位(field) 成員變數

    預設初始化:

    數字: 0 0.0

    char:u0000

    boolean:false

    引用:null

    屬性的定義:

    修飾符 屬性型別 屬性名= 屬性值!

  2. 物件的建立和使用

-必須使用new關鍵字創造物件,構造器 Person ljy= new Person();

物件的屬性 ljy.name

物件的方法 ljy.sleep()

  1. 類:

靜態的屬性 屬性

動態的行為 方法

封裝

高內聚,低耦合(高內聚就是類的內部資料操作細節自己完成,不允許外部干涉;低耦合:僅暴露少量的方法給外部使用。)

封裝(資料的隱藏)

通常,應禁止直接訪問一個物件中資料的實際表示,而應通過操作介面來訪問,這稱為資訊隱藏。

記住:屬性私有,get/set

意義:

  1. 提高程式的安全性,保護資料

  2. 隱藏程式碼的實現細節

  3. 統一介面

  4. 系統可維護提高了

練習程式碼:

package com.oop.Demo04;

//類            private:私有
public class Student {


    //屬性私有
    private String name;//名字
    private int id; //學號
    private char sex;//性別
    private int age;

    //提供一些可以操作這個屬性的方法
    //提供一些public的get、set方法

    //get 獲得這個資料
    public String getName() {
        return this.name;
    }

    //set給這個資料設定值
    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        if (age < 120 && age > 0) {
            this.age = age;
        } else {
            this.age = 3;
        }
    }
}

/*
 public static void main(String[] args) {
        Student s1 = new Student();

        s1.setName("ljy");
        System.out.println(s1.getName());

        s1.setAge(500); //不合法
        System.out.println(s1.getAge());
    }
 */

繼承

繼承的本質是對某一批類的抽象,從而實現對現實世界更好的建模。

extands的意思是"拓展"。子類是父類的擴充套件

Java中類只有單繼承,沒有多繼承(兒子只能一個有一個爸爸,但是爸爸可以有多個兒子)

繼承是類和類之間的一種關係。除此之外,類和類之間的關係還有依賴、組合、聚合等。

繼承關係的倆個類,一個為子類(派生類),一個為父類(基類)。子類繼承父類,使用關鍵字extends來表示。

子類和父類之間,從意義上講應該具有"is a"的關係.

子類繼承了父類就會擁有父類的全部方法

object類

supber

私有的可以被繼承,但是不能被訪問

package com.oop.Demo05extends;

//繼承
//Person 人   父類
public class Person {

    //public (修飾符)
    //protected
    // default
    //private
    protected String name = "ljy";

    public void print() {
        System.out.println("Person");
    }

}


package com.oop.Demo05extends;

//學生is人      派生類,子類
public class Student extends Person {
    private String name = "lijinyu";

  
    public void test(String name) {
        System.out.println(name);  //李晉宇
        System.out.println(this.name); //lijinyu
        System.out.println(super.name);//ljy
    }

}


package com.oop;

import com.oop.Demo05extends.Student;

public class Application {
    public static void main(String[] args) {

        Student student=new Student();
        student.test("李晉宇");


    }
}

練習2:

package com.oop.Demo05extends;

//繼承
//Person 人   父類
public class Person {

    //public (修飾符)
    //protected
    // default
    //private
    public Person(){
        System.out.println("Person無參構造執行");
    }
    protected String name = "ljy";

    public void print() {
        System.out.println("Person");
    }

}

package com.oop.Demo05extends;

//學生is人      派生類,子類
public class Student extends Person {
    public Student() {
        //隱藏程式碼;呼叫了父類的無參構造
        // super() 隱藏的   呼叫父類的構造器,必須要在子類構造器的第一行

        System.out.println("Student無參執行");
    }

    private String name = "lijinyu";

    public void print() {
        System.out.println("Student");
    }

    public void test1(String name) {
        print();//Student
        this.print();//Student
        super.print();//Person
    }

    public void test(String name) {
        System.out.println(name);  //李晉宇
        System.out.println(this.name); //lijinyu
        System.out.println(super.name);//ljy
    }

}


package com.oop;

import com.oop.Demo05extends.Student;

public class Application {
    public static void main(String[] args) {

        Student student = new Student();
        //student.test("李晉宇");
        // student.test1("李晉宇");


    }
}


重點筆記:

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

vs this.
   代表的物件不同
   this:本事呼叫者這個物件
   super:代表父類物件的應用
   前提:
   this:沒有繼承也可以使用
   super:只能在繼承條件下才能使用
   構造方法:
   this():呼叫的本類的構造
   super:父類的構造!

方法重寫

重寫都是方法的重寫,和屬性無關

總結:

重寫:需要有關係,子類重寫父類的方法
 1. 方法名必須相同
 2. 引數列表必須相同
 3. 修飾符:範圍可以擴大, public>protected>default>private
 4.丟擲的異常:範圍可以被縮小,但不能擴大:ClassNotFoundException-->Exception(大)

重寫,子類的方法和父類必須一致:方法體不同!

為什麼需要重寫:
1. 父類的功能子類不一定需要,或者不滿足
2. alt+insert ; override

重寫程式碼:

package com.oop.Demo05extends;

//重寫都是方法的重寫,和屬性無關
public class B {
    public void test() {
        System.out.println("B=>test()");
    }
}

package com.oop.Demo05extends;

public class A extends B {
    //override 重寫
    @Override
    public void test() {
        System.out.println("A=>test()");
    }
}


package com.oop;

import com.oop.Demo05extends.A;
import com.oop.Demo05extends.B;

public class Application {
    //靜態方法和非靜態的方法區別很大
    //靜態方法:方法的呼叫只和左邊有關,定義的資料型別有關
    //非靜態:重寫
    public static void main(String[] args) {
        //方法的呼叫紙盒左邊,定義的資料型別有關
        A a = new A();
        a.test();  //A
        //父類的引用指向了子類
        B b = new A(); // 子類重寫了父類的方法
        b.test();  //B

    }
}

多型

即同一方法可以根據傳送物件的不同而採用多種不同的行為方式。

一個物件的實際型別是確定的,但可以指向物件的引用的型別有很多

多型存在的條件:

  1. 有繼承關係
  2. 子類重寫父類方法
  3. 父類引用指向子類物件

注意事項:

  1. 多型是方法的多型,屬性沒有多型

  2. 父類和子類,有聯絡, 轉換異常 ClassCastException!

  3. 存在條件:繼承關係,方法需要重寫,父類的引用指向子類物件

static 方法,屬性類,不屬於例項

final 常量; private方法 三種都不可以重寫 更不能多型

package com.oop.Demo06;
public class Person {
    public void run() {
        System.out.println("run");
    }
}

package com.oop.Demo06;
public class Student extends Person {
    @Override
    public void run() {
        System.out.println("son");
    }

    public void eat() {
        System.out.println("eae");
    }
}

package com.oop;
import com.oop.Demo06.Person;
import com.oop.Demo06.Student;
public class Application {
    public static void main(String[] args) {
        //一個物件的實際型別是確定的
        //new student();
        // new Person();

        //可以指向的引用型別就不確定了:父類的引用指向子類

        //Student能呼叫的方法都是自己的或者繼承父類的!
        Student s1 = new Student();
        //Person父型別,可以指向子類,但是不能呼叫子類獨有的方法
        Person s2 = new Student();

        //物件能執行哪些方法,主要看物件左邊的型別,和右邊關係不大
        s1.run();     //子類重寫了父類的方法,執行子類
        s2.run();

    }

}

instanceof(型別轉換)

System.out.println(x instanceof y); //能不能編譯通過,看是否存在父子關係,存在就是true反正false

練習程式碼:

 public static void main(String[] args) {

     //object>string
     //object>Person>Teacher
     //object>Person>student
     Object object = new Student();

     System.out.println(object instanceof Student);//trun
     System.out.println(object instanceof Person);//trun
     System.out.println(object instanceof Object);//trun
     System.out.println(object instanceof Teacher);//False
     System.out.println(object instanceof String);//False
     System.out.println("============================");
     Person person = new Student();
     System.out.println(person instanceof Student);//trun
     System.out.println(person instanceof Person);//trun
     System.out.println(person instanceof Object);//trun
     System.out.println(person instanceof Teacher);//False
     //System.out.println(person instanceof String);//編譯報錯!
     System.out.println("============================");
     Student student = new Student();
     System.out.println(student instanceof Student);//trun
     System.out.println(student instanceof Person);//trun
     System.out.println(student instanceof Object);//trun
//   System.out.println(student instanceof Teacher);//編譯報錯!
 //  System.out.println(student instanceof String);//編譯報錯!
 }

小結:

  1. 父類的引用指向子類的物件
  2. 把子類轉換為父類(向上轉型)
  3. 把父類轉換為子類(向下轉型) 需要強制轉換
  4. 方便方法的呼叫,減少重複程式碼!

程式碼練習:

package com.oop.Demo07;

public class Person {
    public void run() {
        System.out.println("run");
    }
}

package com.oop.Demo07;

public class Student extends Person {
    public void go(){
        System.out.println("go");
    }
}

package com.oop;

import com.oop.Demo07.Person;
import com.oop.Demo07.Student;

public class Application {
    public static void main(String[] args) {

        //型別之間的轉換: 父      子

        // 高          低
        Person obj = new Student();

        //student將這個物件轉換為student型別,我們就可以使用student型別的方法了

        //子類轉換為父類,可能丟失自己本來的一些方法
        Student student = (Student) obj;
        student.go();
        //  ((Student) obj).go();  和上面兩行程式碼一樣

        /*
        Student ss = new Student();
        ss.go();
        Person person = student;

         */

    }

}

static關鍵詞

注意:非靜態的可以直接訪問靜態的,靜態的不能直接訪問非靜態的。

package com.oop.Demo08;

//static
public class Student {
    private static int age;  //靜態變數        多執行緒
    private double score;  //非靜態變數

    public void run() {

    }

    public static void go() {

    }

    public static void main(String[] args) {
        Student s1 = new Student();

        System.out.println(Student.age);
        // 非靜態的不能這樣訪問 推薦類名訪問  System.out.println(Student.score);
//        System.out.println(s1.age);
//        System.out.println(s1.score);
        //非靜態可以訪問靜態的  靜態的不能直接訪問非靜態的。

    }

}
package com.oop.Demo08;

public class Person {
    //2:賦初值~
    {
        //程式碼塊(匿名程式碼塊)
        System.out.println("匿名程式碼塊");
    }

    // 1   只執行一次~
    static {
        System.out.println("靜態程式碼塊");
    }

    //3
    public Person() { //構造器
        System.out.println("構造方法");


    }

    public static void main(String[] args) {
        Person person1 = new Person();
        System.out.println("======================");
        Person person2 = new Person();

    }
}
package com.oop.Demo08;
//靜態匯入包

import static java.lang.Math.random;
import static java.lang.Math.PI;

public class Test {
    public static void main(String[] args) {
        System.out.println(random());
        System.out.println(PI);
    }
}

抽象類

abstract修飾符可以用來修飾方法也可以修飾類,如果修飾方法,那麼該方法就是抽象方法;如果修飾類,那麼該類就是抽象類。
抽象類中可以沒有抽象方法,但是有抽象方法的類一定要宣告為抽象類。

抽象類,不能使用new關鍵字來建立物件,它是用來讓子類繼承的。
抽象方法,只有方法的宣告,沒有方法的實現,它是用來讓子類實現的。

子類繼承抽象類,那麼就必須要實現抽象類沒有實現的抽象方法,否則該子類也要宣告為抽象類。

package com.oop.Demo09;

//abstract 抽象類:類    extends:單繼承     (介面可以多繼承)
public abstract class Action {
    //約束~ 有人幫我們實現
    //abstract,抽象方法,只有方法的名字,沒有方法的實現
    public abstract void doSometing();

    //1.不能new這個類,只能靠子類去實現它:約束
    //2.抽象類可以寫普通的方法
    //3.抽象方法必須在抽象類中

    //思考: new   存在構造器? 存在的意義。
}
package com.oop.Demo09;

//abstract 抽象類:類    extends:單繼承     (介面可以多繼承)
public abstract class Action {
    //約束~ 有人幫我們實現
    //abstract,抽象方法,只有方法的名字,沒有方法的實現
    public abstract void doSometing();

    //1.不能new這個類,只能靠子類去實現它:約束
    //2.抽象類可以寫普通的方法
    //3.抽象方法必須在抽象類中

    //思考: new   存在構造器? 存在的意義:抽象出來,提高開發效率
}

介面

普通類:只有具體的實現

抽象類:具體實現和規範(抽象方法)都要

介面:只有規範,自己無法寫方法。 專業的約束,約束與實現分離,面對介面程式設計

介面就是規範,定義的是一組規則,體現了現實世界中“如果你是...則必須能..”的思想。如果你是天使,則必須能飛。如果你是汽車,則必須能跑。如果你好人,則必須幹掉壞人;如果你是壞人,則必須欺負好人。

介面的本質是契約,就像我們人間的法律一樣。制定好後大家都遵守。

OO(面向物件)的精髓,是對物件的抽象,最能體現這一點的就是介面。為什麼我們討論設計模式都只針對具備了抽象能力的語言(比如c++、java、c#等),就是因為設計模式所研究的,實際上就是如何合理的去抽象。

** 宣告類的關鍵詞是class,宣告介面的關鍵詞是interface**

作用:

  1. 約束
  2. 定義一些方法,讓不同的人實現
  3. 方法都是預設 public abstract
  4. 常量都是 public static final
  5. 介面不能被例項化~,介面中沒有構造方法
  6. implements可以實現多個介面
  7. 必須要重寫介面中的方法

練習程式碼:

package com.oop.Demo10;

public interface TimeService {
    void time();
}


package com.oop.Demo10;

//抽象的思維  ~ Java
//interface 定義關鍵字      介面都需要實現類
public interface UserService {
    //常量~ public static final(預設的)
    int age = 99;
    //介面中的所有定義都是抽象的 public abstract
    void add(String name);
    void delete(String name);
    void update(String name);
    void query(String name);
}

package com.oop.Demo10;

//抽象類:extends
//類 可以實現介面   implements 介面
//實現了介面的類 必須要重寫介面中的方法

//多繼承~利用介面實現多繼承~
public class UserServiceImpl implements UserService,TimeService {
    @Override
    public void time() {
   }
    @Override
    public void add(String name) {
    }
    @Override
    public void delete(String name) {
    }
    @Override
    public void update(String name) {
    }
    @Override
    public void query(String name) {
    }
}


內部類

內部類就是在一個類的內部在定義一個類,不如:A類中定義一個B類,那麼B類相對A類來說就稱為內部類,而A類相對B類來說就是外部類了。

  1. 成員內部類
  2. 靜態內部類
  3. 區域性內部類
  4. 匿名內部類

程式碼:

package com.oop.Demo11;

public class Outer {
    private int id =10;
    public void out(){
        System.out.println("這是外部類的方法");
    }

    public class Inner{
        public void in(){
            System.out.println("這是內部類的方法");
        }
        //獲得外部類的私有屬性
        public void getID(){
            System.out.println(id);
        }
    }
}

package com.oop;

import com.oop.Demo11.Outer;

public class Application {
    public static void main(String[] args) {
        //new  外部類
        Outer outer = new Outer();

        //通過這個外部類來例項化內部類
        Outer.Inner inner = outer.new Inner();
        inner.in();
        inner.getID();
    }

}


package com.oop.Demo11;

public class Outer {
    //區域性內部類
    public void method(){
        class Inner{
            public void in(){
                
            }
        }
    }

}

//一個Java類中可以有多個class類,但只能有一個public class

package com.oop.Demo11;

public class Test {
    public static void main(String[] args) {
        //沒有名字初始化類,不用降例項儲存到變數中
        new Apple().eat();

        UserService userService= new UserService(){
            @Override
            public void hello() {

            }
        };
    }
}
class Apple{
    public void eat(){
        System.out.println("1");
    }
}

interface UserService{
    void hello();

}

有要一起學習Java的小夥伴可以留下聯絡方法·