1. 程式人生 > 實用技巧 >面向物件oop

面向物件oop

面向物件(oop)

1.初識面向物件

面向過程思想

具體的 步驟清晰,第一步做什麼,第二步做什麼

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

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

從程式碼的角度看考慮是先有類後有物件。

2.方法的回顧和加深

   public static void main(String[] args) {

// 例項化 這個類new
//非靜態方法 ↓ 1.
Student student = new Student();
student.say();
// 2. ↓
new Student().say();
//靜態方法直接呼叫 ↓ static
//Student.say();
}

}

3.物件的建立分析

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

例如抽象的概念:動物,植物等

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

創建於初始化物件

使用new關鍵字建立物件

一個專案應該只存在一個main方法

一個類裡面 只有屬性和方法

構造器

package com.oop.Demo2;

public class Person {
public String name;
public int age;
//構造器 Alt+(fn)insert
public Person() {
}
//有參構造: 一旦有參構造 想用new物件的話 必須顯式定義出來無參構造
public Person(String name) {
this.name = name;
}
//例項化初始值
//1.使用new關鍵字,本質是在呼叫構造器
//2.用來初始化值
public Person(String name, int age) {
this.name = name;
this.age = age;
}
}
//測試類
/** public class Application {
public static void main(String[] args) {
//例項化了一個物件
Person person = new Person("awdaw",13);
System.out.println(person.name);
System.out.println(person.age);
}
}
* 構造器:
* 1.必須和類名相同
* 2.沒有返回值
* 作用:
* 1. new 本質在呼叫構造方法
* 2. 初始化物件的值
* 注意點:
* 1.定義有參構造之後,如果想使用無參構造,顯示的定義一個無參的構造
* this.XXX 代表這個類的

*/

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

建立物件與記憶體分析

小結類與物件

1.類與方法

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

2.方法

定義,呼叫

3.物件的引用

引用型別:基本型別(8種)

物件是通過引用來操作的,從 棧 → 堆

4.屬性:欄位Field 成員變數

預設初始化:

數:0 0.0

char: u0000

boolean: false

其他引用: 都為null

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

5.物件的建立與使用

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

物件的屬性 names . name

物件的方法 names . say( )

6.類 ( 一個類中 只有屬性和方法)

靜態的屬性 就是屬性

動態的方法 方法

4.重點:面向物件的三大特性(封裝,繼承,多型)

封裝(屬性私有 get,set)

追求“高內聚,低耦合

高內聚:就是類的內部資料操作細節自己完成,不允許外部干涉,

低耦合:僅暴露少量的方法給外部使用,

屬性私有,get/set

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

package com.oop.Demo03;
//類 private私有
public class Student {
//屬性私有
private String name;//名字
private int age; //年齡
private char sex; //性別

//因為私有 所以要提供一些可以操作這些屬性的方法
// 提供一個public的get、set方法
//get 獲取這個資料
public String getName(){
return name;

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

this.name = name;
}

public int getAge() {

return age;
}
// set內可以判斷安全性
public void setAge(int age) {
if (age > 120 || age < 0) {
this.age = 3;
} else {
this.age = age;
}
}

public char getSex() {
return sex;
}

public void setSex(char sex) {

this.sex = sex;
}

}

測試類

package com.oop;

import com.oop.Demo03.Student;

public class Application {
public static void main(String[] args) {
Student s1 = new Student();
s1.setName("wawa");
System.out.println(s1.getName());
s1.setAge(666);//不合法
System.out.println(s1.getAge());
}
/**封裝的意義
* 1.提高程式的安全,保護資料
* 2.隱藏程式碼的實現細節
* 3.統一介面 get set
* 4.提高了系統的可維護性
*/

}

繼承

繼承的本質是對某一批類的抽象

extends 的意思是“擴充套件”,子類是父類的擴充套件。

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

//Student子類 繼承 Person父類 
public class Student extends Person{
}

四個優先順序

//public

//protected(受保護的)

//default(預設的)

//private(私有) 用get /set方法操作

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

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

子類和父類之間具有“is ”的關係。

java中類只有單繼承,沒有多繼承

object類

java中所有的類 都預設直接或間接繼承object ctrl+h可以檢視繼承關係

super

方法也是和屬性一樣的呼叫

但是許可權私有的 private 父類的方法 子類通過super不能呼叫

super 注意點:

1.super呼叫父類的構造方法,必須在構造方法的第一個

2.super必須只能出現在子類的方法或者構造方法中!

3.super和this不能同時出現呼叫構造方法。同時則報錯

4.定義有參構造之後,如果想使用無參構造,顯示的定義一個無參的構造

對比 this

代表的物件不同

this:本省呼叫者這個物件

super:代表父類物件的應用

前提

this:沒有繼承也可以使用

super:只能在繼承條件才能使用

構造方法

this():本類的構造

super():父類的構造!

方法重寫 Override

重寫 只和非靜態方法有關

測試類

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


}

}

子類A

public class A extends B{

@Override// 註解 有功能的註釋
public void text() {
System.out.println("A");
}
}

父類B

//重寫 只有方法
public class B {

public void text(){
System.out.println("B輸出");
}

}

非靜態才能重寫:需要有繼承關係,子類重寫父類的方法!

1.方法名必須相同

2.引數列表必須相同,否則就變成方法過載了

3.修飾符: 範圍可以擴大 public 》 protected》Default》private

4.丟擲異常: 範圍可以被縮小 但不能擴大ClassnotFoundException <--Exception(大)

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

為什麼需要重寫???

  1. 父類的功能,子類不一定需要,或者不一定滿足!

  2. Alt +Insert override

多型

package com.oop.Demo06;

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

}
/*
多型注意
1.多型是方法的多型,屬性沒有多型
2.父類和子類,有聯絡 型別轉換異常! ClassCastException
3.存在條件: 繼承關係,方法需要重寫,
兩個類都有,父類引用指向子類物件!執行子類

個別方法不能被重寫
1. static 方法,屬於類,不屬於例項
2. final 常量 定值
3. private方法: 私有
*/

子類

public class Student extends Person{
@Override
public void run() {
System.out.println("DD打我");
}
public void eat(){
System.out.println("coco");

}
}

測試類

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();
Object s3 = new Student();


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

}

}

多型注意
1.多型是方法的多型,屬性沒有多型
2.父類和子類,有聯絡 型別轉換異常! ClassCastException
3.存在條件: 繼承關係,方法需要重寫,
兩個類都有,父類引用指向子類物件!執行子類

個別方法不能被重寫
1. static 方法,屬於類,不屬於例項
2. final 常量 定值
3. private方法: 私有

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

一個物件型別是確定的,但可以指向物件的引用的型別有很多(父類,有關係的類)

多型存在的條件

有繼承關係

子類重寫父類方法

父類引用指向子類物件

注意 多型是方法的多型,屬性名沒有多型性

instanceof 判斷一個物件是什麼型別

System.out.println(X instanceof Y);//判斷能不能編譯

X與Y存在有關係就可以

public class Application {
public static void main(String[] args) {
//型別轉換之間 父 子
Student student = new Student();
// 高 轉 低 可以任意轉換無影響 ↓
Person student1 = new Student();
//想讓student1這個物件person類 執行 Student類的方法以及獨有的run方法
//低轉高 就要強制轉換
Student student11 = (Student) student1;
//強制轉換利用student11物件就可以使用Student
student11.run();
}
}

student物件類 想使用Student類的方法 ((Student)student) . run()

/*

1.父類的引用指向子類的物件

2.把子類轉為父類,向上轉型,反之父類轉子類向下轉型:需要強制轉換可能會丟失些方法

3.方便方法呼叫,減少重複的程式碼

static關鍵字詳解

static靜態方法 可以在類中任意呼叫也可被非靜態方法呼叫

public class Student {
private static int age;//靜態的變數
private double score; //非靜態的變數

public void run(){

}
public static void go(){

}
public static void main(String[] args) {
run();//直接調不行,
//必須 new 物件呼叫
new Student().run();

static 多執行緒會用到

public class Person {

{
//程式碼塊(匿名程式碼快) 2.匿名程式碼塊 可以用來賦一些初始值
}
static{
//靜態程式碼塊 且執行一次 1.最先執行 跟類一起載入
}

public Person() {
//構造方法 3.最後執行構造
}
}

package com.oop.Demo08;
//靜態匯入包
import static java.lang.Math.PI;
import static java.lang.Math.*;
public class Text {
public static void main(String[] args) {
System.out.println(random());
}
//通過final定義的類不能繼承了,
}

通過 final 定義的類不能繼承了,