java的面向對象
面向對象
-
物以類聚,分類的思維模式,思考問題首先解決問題需要哪些分類,然後對這些分類進行單獨思考,最後對各個分類下的過程進行思考。
-
對於描述複雜問題的事物,為了從宏觀上把握,從整體上合理分析,我們需要使用面向對象來分析整個系統,但是,具體的微觀操作,仍然需要使用面向過程的思路去處理。
-
以類的方式組織程式碼,以對象的組織(封裝)數組
三大特性:
封裝
繼承
多態
類內包含兩部分: 屬性和方法。
對象是類的實例化,
語法:類名 對象名=new 類名();
默認情況下對象的屬性都有默認值,int類型為零,String類型為null等等
構造器 (構造方法)
- new對象本質就是調用構造器。(無返回值)
- 構造器一般用來初始化值。
構造器在生成對象時默認調用,分為有參和無參,當有參存在時,無參必須顯示定義(寫出來),當我們有參無參均未寫時,系統自動添加無參構造(默認隱藏)。構造器只能是public修飾,因為在main()中定義對象時選需要調用構造器。
使用 this.屬性名 用來訪問調用的對象的屬性。有多個屬性時可以重載多個構造器。
在IDEA中使用Alt+Insert可以選擇construct可以快速創建構造器。
eg:
package Creat;//類一
public class Creat01 {
public String name;
int age;
public Creat01()
{
this.age=10;
this.name="待輸入";
}
public Creat01(String name) {//一個參數
this.name = name;
}
public Creat01(String name, int age) {//兩個參數
this.name = name;
this.age = age;
}
}
import Creat.Creat01;
public class Application { //類二
public static void main(String[] args) {
Creat01 xiaoming=new Creat01();//創建時調用無參構造器
Creat01 xiaohong=new Creat01("xiaohong");//創建時調用一個參數的構造器
Creat01 xiaohei=new Creat01("xiaohei",18);//創建時調用兩個參數的構造器
System.out.println(xiaoming.name);
System.out.println(xiaohong.name);
System.out.println(xiaohei.name);
}
}
註:
main方法在棧里,main()結束程式也就結束了,
static靜態方法區,類調用的時候和類一起載入。存放在堆中。
引用類型在沒有賦值的情況下默認為null
封裝:
我們的程式設計要追求 高內聚,低耦合,高內聚就是指類的內部數據操作細節自己完成,不允許外部干涉;低耦合:僅僅暴露少量的方法給外部用
屬性私有:get/set
可以理解為不再對屬性直接修改,將屬性賦予私有屬性,通過定義方法對屬性修改。get為得到屬性,set為修改屬性。
在IDEA中,Alt+Insert可以自動生成get和set對屬性進行修改。(getter setter)
在定義類中屬性(變數),方法時,一般使用public,private,protected修飾,在這之中只有public作用下可以在main()方法中直接訪問。
public:可以被繼承,可以直接在main()中通過對像直接訪問和修改
private:不可被繼承,不可再main()中通過對象直接訪問,通過方法進行修改和訪問
protected:可被繼承,不可直接通過對象訪問,通過方法修改訪問
default:不作任何修飾時系統默認為此修飾。可被繼承,不可直接通過對象訪問,通過方法修改訪問。
繼承:類之間的關係
繼承的本質是對某一批類的抽象。
extends的意思是擴展,子類是父類的擴展,子類會繼承父類的屬性和方法,private屬性下的東西無法繼承,默認下的屬性default。
super關鍵字與this類似,super指代的是父類中所繼承的與子類中同名的屬性區分方法。例如super.name;指代的是繼承自父類的name屬性,this.name指代的是子類原本的那麼屬性,他們可能同名但是並非同一個值。同樣的super();是調用父類的構造器(默認情況下,隱式的寫在子類構造器的第一行,當我們人為寫出時只能放在第一行,否則報錯),this();指的是子類構造器,方法也是同理的。
tip:
this();和super();不能同時在子類構造器中顯式的寫出,因為兩者都要求要寫在第一行,否則會報錯,因此直接不寫出即可,自動隱式生成。父類沒有無參構造。子類生成時也會報錯!除非寫出super(參數);
super只能出現在子類的構造器或者方法中。只有繼承才可以使用。
註:
java中只有單繼承,沒有多繼承。在java中所有類默認繼承object類。
在IDEA中Ctrl+H可以查看繼承的分級情況。
eg:
//父類
package Inherit;
public class Inherit01 {
String name="father";//default屬性下的變數
public int age=52; //public 下的
private double high=170.0; //private下的不能被繼承
protected double weight=69;//protected
public Inherit01()
{
name="Tom";
age=53;
high=171;
weight=68;
}
}
//子類
package Inherit;
public class Inherit02 extends Inherit01{
public Inherit02 ()
{
// super();//調用父類構造器
}
String name="son";
int age=21;
double high=181.0;
double weight=70;
public void test01(String name){ //如果在參數中定義的有同名變數,那麼單寫變數名指代的是參數中的變數
//想要指代自己定義的需要使用this指針
System.out.println("自己定義的:"+this.name+" "+age+" "+high+" "+weight);
System.out.println("繼承獲得的:"+super.name+" "+super.age+" "+super.weight);
//私有private下的high未能得到繼承
System.out.println("傳入參數的同名變數:"+name);
}
}
//應用
import Inherit.Inherit02;
public class Application {
public static void main(String[] args) {
//繼承的測試程式碼
Inherit02 inherit02=new Inherit02();
inherit02.test01("傳入的name");
}
}
重寫:
重寫必須要有繼承關係,是子類對父類方法的重寫。
- 方法名必須相同
- 參數列表必須相同
- 修飾符的範圍只能擴大不能縮小 public>protected>default>private
- 拋出異常的範圍只能縮小不能擴大
不能是static的靜態函數
子類和父類的方法名一致,但是方法體不同。
為什麼要重寫?
父類的方法子類不一定需要,或者不一定滿足需求
IDEA中的重寫快捷鍵: Alt+insert—–>override
靜態方法的調用中,僅僅和左邊的定義有關。例如:A類繼承自B類。若兩者都含有靜態方法test()
A a=new A();
B b=new A(); //父類的引用指向子類的,僅可調用父類中有的方法。
a.test(); //調用的是A中寫的test()
b.test(); //調用的時B中 的方法test()
若不是靜態方法,而是普通的方法,則test在A中的定義直接實現了test方法的重寫。
不能重寫的方法:
- static 方法,屬於類的,不屬於實例
- final 常量的,在常量池
- private 方法
多態:
同一方法根據發送對象不同而採取不同的欣行為方式
一個對象的實際類型是確定的,但是可以指向對象的引用類型(父類,有關係的類)有很多。
多態是方法的多態,屬性沒有多態
存在條件:繼承關係,方法需要重寫,父類的引用指向子類的對象 father f1=new son();
instanceof:
使用比較x和Y的關係,x為對象,Y為一個類。
如果X和Y存在父子關係則可以通過編譯,否則無法通過編譯,比較返回結果的true或false
如果對象X屬於類Y或者其父類產生的對象則為true,否則為false
要進行強制的了類型轉換:
子類轉換為父類可能丟失自己本身的一些方法。
只能是父類引用指向子類的對象。
父類轉換為子類需要強制轉換,通過強制的轉換,通過降級或升級使其能夠調用它本身的一些其他方法
((Student)object).方法(); //強制轉換的方法