面向物件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{
父類B
//重寫 只有方法
public class B {
public void text(){
System.out.println("B輸出");
}
}
非靜態才能重寫:需要有繼承關係,子類重寫父類的方法!
1.方法名必須相同
2.引數列表必須相同,否則就變成方法過載了
3.修飾符: 範圍可以擴大 public 》 protected》Default》private
4.丟擲異常: 範圍可以被縮小 但不能擴大ClassnotFoundException <--Exception(大)
重寫:子類方法必須和父類必須一致, 方法體不同
為什麼需要重寫???
-
父類的功能,子類不一定需要,或者不一定滿足!
-
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{
測試類
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 定義的類不能繼承了,