自己總結物件導向程式設計的總結

小科學家發表於2009-04-11

物件導向的思想:
    它是超乎語言之上的概念,其它物件導向思想的語言都是一樣的。
物件導向的三大特徵:封裝,繼承,多型。
封裝:對外部不可見,封裝資料,可以起到保護作用,不會一不小會漏掉一些資料。
繼承:用於擴充套件類的功能,在JAVA中只有單繼承,如果要實現像C++那樣多繼承,在JAVA中就要用到介面,它可以避免了多繼承中成員方法,成員變數的重複的特點。
多型:(最重要)

下面我對物件導向的其中一部分知識點做出概括:

物件的定義:
  類名 物件名 = new 類名();舉例:Student stu = new Student();
  我分析一下這裡的機制。首先在棧記憶體有Student型別的name:stu, value:xx(這個值是與堆記憶體的聯絡----指標)。因為在堆記憶體存的就是一個個物件模組,所以new出來的Student這個實際物件就會在堆記憶體出現。此時就會執行Student的構造方法,然後返回物件例項的引用。俗點說,大家只要記住這點就好了:宣告一個物件(棧記憶體中開闢了一個空間),例項化一個物件(堆記憶體開闢了空間,此時物件的引用stu就擁有了Student使用權)。
棧:物件名,堆:物件屬性,全域性程式碼區:所有方法的程式碼,全域性資料區:存放static型別的資料

垃圾收集器的機制:最簡單的理解如下:
  在程式中,不再有任何指向的空間---垃圾空間。JAVA中的垃圾是由JVM回收,自動完成


封裝:讓使用者只能通過實現定製好的方法來訪問資料,可以方便地加入控制邏輯,限制對屬性的不合理操作,也便於修改,增強程式碼的可維護性。就用private關鍵字實現封裝。採用SetXxx()和GetSxx()來訪問封裝類內部的成員方法和成員變數。private起到了讓外部看不到。就起到了封裝,不會隨便漏掉資料了。

 

JAVA許可權修飾符: public protected private
private:只能訪問類內部的成員方法和成員變數
default:除了擁有private功能之外,其他物件還可以訪問同一個包中類的成員方法和成員變數。當我們定於成員方法或成員變數時,不寫任何修飾符的時候,就預設用default。一般不寫default。也就是說default類只能被同一個包中的類訪問
protected:除了擁有default能訪問同一個包中的方法和屬性之外,還可以訪問子類的方法和屬性。
public : 這個不用說了,任何地方都可以訪問本類的方法和屬性。
定義class的許可權修飾只能用public 和default。

匿名物件:比如new Student().sing();它的意思是呼叫Student類的sing()方法。
特點:可以不定義物件引用的名稱,而直接呼叫這個物件的方法。
使用:如果對一個物件只需要進行一次方法的呼叫,那麼就可以使用匿名物件。
常用:經常將匿名物件作為實參傳遞給一個方法呼叫。

String類的使用:
①特點:String類中的內容一旦宣告則不可改變
   解釋:不可以嘗試通過方法改變已經宣告字串的內容。這點可以從記憶體角度來解釋。
②兩種使用方法:第一:private String name1 = "劉少科"; 第二:private String name2 = new String("劉少科");如果大家這樣輸出:System.out.print(name1==name2);System.out.print(name1.equals(name2));輸出內容前者是false後者是true。
equals:是兩個內容的比較,字串的內容或者物件裡面的內容
"==":數值比較,比較的是記憶體地址的值是否相等。這點大家可以參考有關文件,我不詳細介紹了。
總結:直接賦值----只開闢了一個空間,使用new:開闢了兩個空間(其中有一個是垃圾空間)
③ String使用了JAVA中的共享設計模式:舉例:private String name1="劉少科"; private name2 = "劉少科"; System.out.private(name1==name2);是TRUE還是FALSE?String類非常特別。解釋:當你定義name2時,如果已經定義了內容一樣了name1,則name2不會再生成另外一塊空間,此時,name1和name2都會指向"劉少科",所以它們的地址是一樣的,怎上面的返回值肯定是true。
④補充:舉例:String str="liushaoke"; for(int i=0;i<100;i


構造方法:
①特點:它具有與類名相同的名稱,它不含返回值型別的定義,也沒有返回值
②呼叫機制:構造方法在例項化物件時被自動呼叫,主要用來為類中的屬性作初始化工作
③形式:如果沒有寫構造方法,則每當例項化物件時,自動生成一個無參的什麼都不做的構造方法,如果明確寫了無參構造方法,則不會再自動生成無參的構造方法。構造方法的過載我會在後面在總結。建議:無論採用哪種方法為類中的屬性賦值,最好都經過Setter方法,由Setter方法對輸入的內容進行檢測,而Getter方法只是將內容簡單地返回。


方法重寫(overwrite/override):有幾個基本原則
①在子類中可以根據需要對從父類中繼承來的方法進行重寫。
②重寫方法必須和被重寫方法具有相同的方法名稱,引數列表和返回型別。
③重寫方法不能使用被重寫方法更嚴格的訪問許可權
注意:第二點很容易犯錯誤,一定要copy原來的方法,如果自己寫的話,極容易出錯,這種錯誤很難找,要有這種重寫的意識。

方法過載(overload):
特點:方法名相同。但是引數的型別或個數不同l。

this的使用:
①在類的方法定義中使用的this關鍵字代表使用該方法的物件的引用。
②當必須指出當前使用方法的物件時是誰?這時候就要用到this。
③有時候用this可以處理方法中成員變數和引數重名的情況,比如
private String name;
public void run(String name){
 this.name = name;
}
④this可以看成一個變數,它的值是當前物件的引用。
對第四點解釋:它不是任何物件的引用,this是指向自己本身的類的引用,它是堆記憶體的,與棧記憶體沒有任何一點關係。因為它是指向自己本身。俗點說this就是當前的類,只不過是一個引用。
⑤this呼叫本類屬性,本類方法,構造方法這三點,是this的基本運用,也是最常用的,綜合起來就是一點------表示當前物件。舉例:
class Student{
  private String name;private String age;
  public Student(){}
  public Student(String name){ this.name=name}
  public Student(String name,String age){this(name);this.age=age}
}
我在這裡舉這個例子就可以說明前面的一些理論。注意,構造方法過載中的this(name);這個一定要放在Student含兩個引數構造方法的首行。


super的使用:和this很相似
①呼叫父類的方法:呼叫父類的特定構造方法。如 super();super(name);super(name,age);
 我舉個例子:
 class a extends Student{
  public void printStuInfor(){
   super();
   super("劉少科");
   super("劉少科",22);
  }
}
也就是說可以通過super(),裡面根據傳入的引數區呼叫父類中指定的構造方法,預設是呼叫無參構造方法
②呼叫父類中被覆蓋的方法:通過呼叫super().父類的方法就可以在例項化子類時呼叫父類的方法------------相當方法被重寫了,所以這時在子類就可以增加自己新的方法就可以了,預設就會執行super()方法。


this與super() 的區別:
   兩者用法很相似。
   this與super呼叫構造的操作能同時在一個構造方法出現嗎?肯定不行,只能用一個。

 

static的用法:
①static屬性可以被static和非static型別的方法所使用,非static屬性不可以被static方法使用。
②static宣告的屬性,表示此屬性為公有屬性,也就是說:所有物件都可以訪問此屬性。它是存放在全域性資料區。可以用類名加點來直接訪問static屬性。如果你想嘗試通過某個具體的物件改變static屬性的內容,對不起,你改不了。
③靜態方法不能呼叫非靜態屬性和方法,非靜態方法可以呼叫靜態屬性和方法。
④static程式碼塊:
  首先解釋一下JAVA的四種程式碼塊的區別:
  一,普通程式碼塊:是寫在一個方法之中的語句塊
  二,構造塊:是直接寫在類中的一個語句塊,構造塊優先於構造方法執行
  三,靜態塊:是直接寫在類中的,通過static宣告的語句塊,優先於構造塊和構造方法,主要作用是為靜態屬性初始化,只執行一次。
  四,同步程式碼塊:經典的用處是在多執行緒的執行緒同步。


繼承的使用:
   特點:實現功能的擴充套件,良好的擴充套件性有利於以後功能的擴充套件。
   規定:JAVA只支援單繼承,沒有多繼承,就像一個小孩只有一個血緣關係的父親。
   注意:子類可以繼承父類中的公有屬性和共有方法,而不能直接操縱父類中的私有方法。
        可以通過封裝的特性來訪問父類的私有屬性和私有方法。
   補充:要先有父類才能有子類的產生,所以當你例項化子類時,它會先執行父類的構造方法,先產生父類,之後才會執行子類的有關方法。它會呼叫super();如果在子類沒有寫super();在例項化時會自動掉用預設的super();

final關鍵字的使用:-----相當於太監。呵呵呵
①final標記的淚不能被繼承
②標記的方法不能被子類重寫
③final標記的變數(成員變數或區域性變數)即成為常量,只能賦值一次。
全域性常量的定義:public static final。資料存在全域性資料區。final定義的變數一般用大寫。


抽象類:
①定義:類和方法必須用abstract修飾
②原則:抽象類不能被直接例項化,抽象方法只能宣告,而不需要實現。
③含有抽象方法的類必須被宣告為抽象類,抽象類的子類必須重寫父類的抽象方法。
注意:抽象類必須有子類,子類如果不是抽象類的話,則必須重寫抽象類的全部方法
我問大家:抽象類可以有構造方法嗎?還有抽象類可以用final宣告嗎?
解釋:構造方法是物件例項化時使用的。子類物件在例項化物件時依照先例項化父類中的屬性,再例項化本類中的屬性,這和在一般的繼承中,例項化物件時的機制一樣的。final可以宣告一個類,但是此類是不能有子類的父類,但是抽象類必須要有子類的實現,所以抽象類一定不可以用final宣告。


介面:是抽象方法和常量的集合。
抽象類中包含抽象方法,那如果全部都是抽象方法,則可以用介面來表示。
常量定義:一定要這樣用:public static final String name;如果你沒有這麼寫,而寫成了String name;則會預設像前面那樣。舉例:
interface Person{
 public static final String furColor="orange";
 public void Sing();
 public void say();
}
class student implements Person{
  //在這裡一定要重寫介面中的方法
}
一個類可以同時實現多個介面。
一個介面可以允許繼承多個介面
但是一個類是不允許繼承多個類的

 

多型的知識點:
●介面和抽象類很重要,多型就是最好的體現。
•方法的多型性(過載):同一個方法名稱根據傳入引數的不同,完成的功能也不同
•物件的多型性:它是在繼承應用上的一種擴充套件,所以多型是建立在繼承關係之上。
  *物件導向程式開發的一個思路:【建議】永遠不要去繼承一個普通類
子類物件和父類物件之間的轉換
★向上轉型:子類物件向父類物件轉換(⊕自動轉型 父類物件=子類物件 )
★向下轉型:父類物件向子類物件轉換(☉強制轉換 子類物件=(子類)父類物件 )
注意點:如果一個方法被子類重寫了,則子類與父類發生轉換,自動去呼叫已經被重寫過的方法(子類中的方法);★★★★★
物件多型性最核心的部分:方法的覆寫與繼承的關係,只要有繼承關係,只要有覆寫過的方法,則子類向父類進行轉型時,肯定呼叫被子類覆寫過的方法(核心)
★介面與抽象類的實際應用:基礎類,封裝,繼承,覆寫,多型性。

物件多型性
開發建議:不要去繼承一個已經實現好的類
如果以後在開發中需要繼承,則大部分情況下繼承的都會是一個抽象類,當然,也有一個問題,抽象類有JAVA單繼承侷限,不能多繼承。所以用到介面。

介面的實際應用:
 介面的使用:將方法名暴露給使用者(比較難理解)
 介面物件的實力:通過物件的多型性,由子類為介面物件例項化

抽象類與介面在使用上非常的相似。
在開發過程上講:優先使用介面,介面允許多繼承的特點。
抽象類與介面的比較:
相同點:物件不能直接例項化,通過多型性,可有其子類例項化
不同點:
抽象類:包括一般方法,抽象方法,變數,常量; 可以有構造方法;抽象類可以實現多個介面;繼承時,單繼承會有侷限。
介面:包括常量,抽象方法;不能有構造方法;介面不能繼承一個抽象類;解決單繼承的侷限。
注意這樣一個特點:介面中都是抽象方法,則子類必須全部覆寫介面中的全部抽象方法,那麼如果現在子類不希望全部都覆寫呢?又怎樣操作?用介面卡Adapter:介面卡的設計模式
介面---抽象類---子類

介面可以進一步擴充套件---------工廠設計模式
介面與抽象類的應用:(需要長時間的訓練才能讀透,我也不是很熟練哦,呵呵,大家一起進步哦)

 

附錄:一個是多型性在抽象類的應用,一個是用抽象類實現繼承,一個是用介面實現繼承
abstract class Person
{
 private String name ;
 private int age ;
 public Person(String name,int age)
 {
  this.setName(name) ;
  this.setAge(age) ;
 }
 public void setName(String name)
 {
  this.name = name ;
 }
 public void setAge(int age)
 {
  this.age = age ;
 }
 public String getName()
 {
  return this.name ;
 }
 public int getAge()
 {
  return this.age ;
 }
 // 將說話的內容作為一個抽象方法,通過子類去實現
 public void say()
 {
  System.out.println(this.getContent()) ;
 }
 public abstract String getContent() ;
};
// 假設人分為兩種 :一種是工人,一種是學生
// 工人有工資,學生有成績
// 不管是學生還是工人,肯定都可以說話
// 說話的內容不一樣
class Worker extends Person
{
 private float salary ;
 public Worker(String name,int age,float salary)
 {
  super(name,age) ;
  this.setSalary(salary) ;
 }
 public void setSalary(float salary)
 {
  this.salary = salary ;
 }
 public float getSalary()
 {
  return this.salary ;
 }
 public String getContent()
 {
  return "工人說 --&gt 姓名:"+super.getName()+",年齡:"+super.getAge()+",工資:"+this.getSalary() ;
 }
};
class Student extends Person
{
 private float score ;
 public Student(String name,int age,float score)
 {
  super(name,age) ;
  this.setScore(score) ;
 }
 public void setScore(float score)
 {
  this.score = score ;
 }
 public float getScore()
 {
  return this.score ;
 }
 public String getContent()
 {
  return "學生說 --&gt 姓名:"+super.getName()+",年齡:"+super.getAge()+",成績:"+this.getScore() ;
 }
};
public class OODemo03
{
 public static void main(String args[])
 {
  Person p = null ;
  // p = new Student("張三",30,90) ;
  p = new Worker("張三",30,3000) ;
  p.say() ;
 }
};

 

 

 

interface USB
{
 // 開始工作
 public void start() ;
 // 停止工作
 public void stop() ;
}
// 對於PC機上認的是一個USB介面
class PC
{
 public static void plugin(USB u)
 {
  u.start() ;
  u.stop() ;
 }
};
class Mp3 implements USB
{
 public void start()
 {
  System.out.println("Mp3開始工作了。。。") ;
 }
 public void stop()
 {
  System.out.println("Mp3停止工作了。。。") ;
 }
};

class UDisk implements USB
{
 public void start()
 {
  System.out.println("U盤開始工作了。。。") ;
 }
 public void stop()
 {
  System.out.println("U盤停止工作了。。。") ;
 }
};

public class OODemo05
{
 public static void main(String args[])
 {
  PC.plugin(new UDisk()) ;
 }
};

 

 

 

interface A
{
 public void fun1() ;
 public void fun2() ;
 public void fun3() ;
}
abstract class B implements A
{
 public void fun1()
 {}
 public void fun2()
 {}
 public void fun3()
 {}
};
class C extends B
{
 public void fun1()
 {
  System.out.println("HELLO 垃圾廣告 ...") ;
 }
};
public class OODemo06
{
 public static void main(String args[])
 {
  A a = new C() ;
  a.fun2() ;
 }
};

 

 


interface USB
{
 // 開始工作
 public void start() ;
 // 停止工作
 public void stop() ;
}
class Mp3 implements USB
{
 public void start()
 {
  System.out.println("Mp3開始工作了。。。") ;
 }
 public void stop()
 {
  System.out.println("Mp3停止工作了。。。") ;
 }
};

class UDisk implements USB
{
 public void start()
 {
  System.out.println("U盤開始工作了。。。") ;
 }
 public void stop()
 {
  System.out.println("U盤停止工作了。。。") ;
 }
};
// 假設現在要修改子類,則要修改mian方法,是一個程式的客戶端
class Factory
{
 public static USB getUSBInstance()
 {
  return new UDisk() ;
 }
};
public class OODemo07
{
 public static void main(String args[])
 {
  USB u = Factory.getUSBInstance() ;
  u.start() ;
  u.stop() ;
 }
};


 

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/21359667/viewspace-588691/,如需轉載,請註明出處,否則將追究法律責任。

相關文章