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詳解
注意:
- super調用父類的構造方法,必須在構造方法的第一個
- super必須只能出現在子類的方法或者構造方法中!
- 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 方法重寫
(父類的功能,子類不一定需要,或者不一定滿足!故需要重寫)
重點:需要有繼承關係,子類重寫父類的方法!
- 方法名必須相同
- 參數列表必須相同
- 修飾符:範圍可以擴大但不能縮小: public -> protected -> default -> private
- 拋出異常:範圍可以被縮小但不能擴大。(破洞只能越填越小)
重寫中子類的方法和父類方法頭一致;方法體不同!
-
案例展示:
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!