Java 面向物件的特徵
1.繼承
在定義和實現一個類的時候,可以在一個已經存在的類的基礎之上來進行,把這個已經存在的類所定義的內容作為自己的內容,
並可以加入若干新的內容,或修改原來的方法使之更適合特殊的需要,這就是繼承。繼承是子類自動共享父類資料和方法的機制,
這是類之間的一種關係,提高了軟體的可重用性和可擴充套件性。
使用繼承
編寫父類
class pet {
//公共屬性和方法
}
編寫子類,繼承父類
class dog extends pet {
//子類特有的屬性和方法
}
class cat extends pet {
//子類特有的屬性和方法
}
繼承的特性
單根性
只能繼承一個類,不能多重繼承
傳遞性
從父類繼承來的元素,可以被子類繼承
子類訪問父類成員
使用super關鍵字
訪問父類構造方法
//構造器
public dog() {
// 訪問父類構造方法
// super();
super("二哈",2);
}
訪問父類構造屬性
super.name;
訪問父類方法
super.print();
不可被繼承的資源
不可繼承被私有化的屬性和方法
構造方法
作用
繼承的出現提高了程式碼的複用性。
繼承的出現讓類與類之間產生了關係,提供了多型的前提。
注意
Java只支援單繼承,不允許多重繼承。
即一個子類只能有一個父類。
但一個父類可以派生出多個子類
方法的重寫(override)
在子類中可以根據需要對從父類中繼承來的方法進行改造。
在程式執行時,子類的方法將覆蓋父類的方法。
要求
重寫方法必須和被重寫方法具有相同的方法名稱、引數列表和返回值型別。
重寫方法不能使用比被重寫方法更嚴格的訪問許可權。
重寫和被重寫的方法須同時為static的,或同時為非static的。
子類方法丟擲的異常不能大於父類被重寫方法的異常。
注意
如果父類的一個方法定義成private訪問許可權,在子類中有相同的方法,則不叫重寫,因為子類無法訪問到
package mytest;
public class A{
private void privateFunc() {
System.out.println("A privateFunc");
}
void defaultFunc() {
System.out.println("A defaultFunc");
}
protected void protectedFunc() {
System.out.println("A protectedFunc");
}
public void publicFunc() {
System.out.println("A publicFunc");
}
}
package mytest;
public class B extends A{
// 不是重寫,而是定義了另外一個函式,重寫的前提是有訪問許可權
private void privateFunc() {
System.out.println("B privateFunc");
}
// 重寫
void defaultFunc() {
System.out.println("B defaultFunc");
}
// 重寫
protected void protectedFunc() {
System.out.println("B protectedFunc");
}
// 重寫
public void publicFunc() {
System.out.println("B publicFunc");
}
}
package mytest;
public class Test {
public static void main(String[] args) {
A a = new B();
B b = new B();
// a.privateFunc(); // 只能在類內部呼叫
a.defaultFunc();
a.protectedFunc();
a.publicFunc();
// b.privateFunc(); // 只能在類內部呼叫
b.defaultFunc();
b.protectedFunc();
b.publicFunc();
}
}
輸出:
B defaultFunc
B protectedFunc
B publicFunc
B defaultFunc
B protectedFunc
B publicFunc
2.封裝
封裝是保證軟體部件具有優良的模組性的基礎,封裝的目標就是要實現軟體部件的“高內聚、低耦合”,防止程式相互依賴性而帶來的
變動影響。在面向物件的程式語言中,物件是封裝的最基本單位,面向物件的封裝比傳統語言的封裝更為清晰、更為有力。面向物件
的封裝就是把描述一個物件的屬性和行為的程式碼封裝在一個“模組”中,也就是一個類中,屬性用變數定義,行為用方法進行定義,方法
可以直接訪問同一個物件中的屬性。通常情況下,只要記住讓外匯返傭http://www.fx61.com/變數和訪問這個變數的方法放在一起,將一個類中的成員變數全部定義成私有的,只有這個類自己的方法才可以訪問到這些成員變數,這就基本上實現物件的封裝,就很容易找出要分配到這個類上的方法了,就基本上算是會面向物件的程式設計了。把握一個原則:把對同一事物進行操作的方法和相關的方法放在同一個類中,把方法和它操作的資料放在同一個類中。
例如,人要在黑板上畫圓,這一共涉及三個物件:人、黑板、圓,畫圓的方法要分配給哪個物件呢?由於畫圓需要使用到圓心和半徑,
圓心和半徑顯然是圓的屬性,如果將它們在類中定義成了私有的成員變數,那麼,畫圓的方法必須分配給圓,它才能訪問到圓心和半徑
這兩個屬性,人以後只是呼叫圓的畫圓方法、表示給圓發給訊息而已,畫圓這個方法不應該分配在人這個物件上,這就是面向物件的
封裝性,即將物件封裝成一個高度自治和相對封閉的個體,物件狀態(屬性)由這個物件自己的行為(方法)來讀取和改變。一個更便於
理解的例子就是,司機將火車剎住了,剎車的動作是分配給司機,還是分配給火車,顯然,應該分配給火車,因為司機自身是不可能有那
麼大的力氣將一個火車給停下來的,只有火車自己才能完成這一動作,火車需要呼叫內部的離合器和剎車片等多個器件協作才能完成剎車
這個動作,司機剎車的過程只是給火車發了一個訊息,通知火車要執行剎車動作而已。
import java.util.Date;
public class Emp {
private String name;
private int age;
private String gender;
private int salary;
private Date hiredate;
public Emp() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public int getSalary() {
return salary;
}
public void setSalary(int salary) {
this.salary = salary;
}
public Date getHiredate() {
return hiredate;
}
public void setHiredate(Date hiredate) {
this.hiredate = hiredate;
}
}
封裝的好處
隱藏類的實現細節;
只能通過規定方法訪問資料;
方便加入控制語句;
方便修改實現;
封裝的步驟
修改屬性可見性 – 設為private
public class pet {
// 建立屬性並修改可見性
private String name;
private int age;
}
建立get/set方法 – 用於屬性讀寫
// 建立get方法
public String getName() {
return name;
}
// 建立set方法
public void setName(String name) {
this.name = name;
}
在get/set方法中加入控制語句 – 對屬性進行合法判斷
public void setAge(int age) {
// 加入控制語句
if(age > 0 && age < 100){
this.age = age;
}
}
- 多型性
多型性是指允許不同類的物件對同一訊息作出響應。
實現多型的3個條件:1、必須有子類繼承父類。2、必須有方法覆蓋。3、必須有父類的引用指向子類。
多型性包括引數化多型性和包含多型性。多型性語言具有靈活、抽象、行為共享、程式碼共享的優勢,
很好的解決了應用程式函式同名問題。
使用多型實現思路
編寫父類
class Pet {
//吃東西
public void eat(){
}
}
編寫子類,子類重寫父類方法
class Dog extends Pet {
//重寫父類方法
public void eat(){
System.out.println("吃骨頭");
}
}
執行時,使用父類型別,子類物件
class cat extends Pet {
Pet pet = new Dog();
}
只能呼叫父類有的方法
編譯看左,執行看右
Pet pet = new Dog();
4.抽象
抽象就是找出一些事物的相似和共性之處,然後將這些事物歸為一個類,這個類只考慮這些事物的相似和共性之處,
並且會忽略與當前主題和目標無關的那些方面,將注意力集中在與當前目標有關的方面。例如,看到一隻螞蟻和大象,
你能夠想象出它們的相同之處,那就是抽象。抽象包括行為抽象和狀態抽象兩個方面。例如,定義一個Person類,如下:
class Person{
String name;
int age;
}
人本來是很複雜的事物,有很多方面,但因為當前系統只需要瞭解人的姓名和年齡,所以上面定義的類中只包含姓名和年齡這兩個屬性,
這就是一種抽像,使用抽象可以避免考慮一些與目標無關的細節。我對抽象的理解就是不要用顯微鏡去看一個事物的所有方面,
這樣涉及的內容就太多了,而是要善於劃分問題的邊界,當前系統需要什麼,就只考慮什麼。
抽象包括兩個方面,一是資料抽象,二是過程抽象。
資料抽象——就是用程式碼的形式表示現時世界中一類事物的特性,就是針對物件的屬性。比如建立一個鳥這樣的類,鳥都有以下屬性:
一對翅膀、兩隻腳、羽毛等。抽象出來的類都是鳥的屬性,或者成員變數。
過程抽象——就是用程式碼形式表示現實世界中事物的一系列行為,就是針對物件的行為特徵。比如鳥會飛、會叫等。抽象出來的類一般