- 編程語言的發展
- 面向過程的設計思想
- 面向對象的設計思想
- 對象和類的概念
- 類之間的關係
- 對象和引用
- Java類的定義
- 構造函數
- 對象的創建和使用
- this關鍵字
- static關鍵字
- package和import語句
- 訪問控制
- 類的繼承
- 方法的重寫
- final關鍵字
- object類
- 對象轉型
- 多態
- 抽象類
- 接口
編程語言的發展
- 機器語言
- 彙編語言
- 高級語言–面向過程的語言
- 面向對象的語言
面向過程的思想和麪向對象的設計思想
面向對象思維:
- 合適的方法出現在合適類中
在問題域中,不再考慮一步一步的過程,而是將問題域中的對象抽象出來,弄清楚對象和對象之間的關係。
重點:面向對象實現的三個步驟:
- 問題中有哪些類哪些對象。
- 這些類這些對象有哪些屬性和方法。
- 類和類之間具備哪些關係:關聯(弱),繼承(強),聚合(強),實現(父類和子類之間),多態。
對象和類的概念
- 類:一類事物的一個抽象,包括靜態屬性(成員變量)和動態屬性(方法)。“瓶子”
對象:一類事務的具體的實例。“某個瓶子”
類(對象)之間的關係 之
關聯關係
關聯關係:某個類的方法關聯到某個類的對象。
繼承關係(一般和特殊)
容易形成繼承樹
XX是一種XX:球類運動員是一種運動員。
一類可以從不同的多個類繼承。【多重繼承:C++】
聚合關係(整體和部分)
聚集:鬆耦合
組合:必不可少
實現關係
父類的方法,子類來實現。
多態
練習:
類:旅行社,旅客,機票,賬目
機票
屬性:班次
方法:送票,作廢,顯示航班時間
Java與面向對象
必須先定義類纔能有對象
- 對象是Java程序的核心,在Java程序中“萬事萬物皆對象”。
- 對象可以看成是靜態屬性(成員變量)和動態屬性(方法)的封裝體。
- 類是用來創建同一類對象的“模板”,在一類中定義了該類對象所應具有的成員變量及方法。
- J2SDK本身提供了很多類供編程人員使用,編程人員也可定義自己的類。
爲什麼用對象?
Java類的定義
約定俗成的命名規則:
- 類名的首字母大寫
- 變量名和方法名的首字母小寫
- 運用駝峯標識
//用class關鍵字定義一個類,例如:
class Person{
//成員變量定義
private int id;
private int age = 20;
//方法定義
public int getAge(){
return age;
}
public void setAge(int i){
age = i;
}
public int getId(){
return id;
}
}
成員變量
成員變量可以使Java語言中任何一種數據類型(包括基本類型和引用類型)。
在定義成員變量時,可以對它初始化,也可以不對它初始化,不初始化時,Java會給出默認初始化值。
成員變量的作用範圍爲整個類體。
引用
Java中除了基本類型之外的變量類型都稱爲引用類型。
Java中的對象是通過引用對其操作。
- 基本類型:佔一塊內存。
- 引用類型:佔兩塊內存(一小塊內存指向一大塊內存)。(引用(棧) + 真正的對象(存放在堆內存中))
類和對象的關係
構造方法(構造函數)
- 使用new+構造方法 創建一個新對象。
- 構造函數是定義在Java類中的一個用來初始化對象的函數。
構造函數與類同名且沒有返回值。
public class Person{ int id; int age; Person(int n,int i){ id = n; age = i; } }
創建對象時,使用構造函數初始化對象的成員變量。
public class Test{ public static void main(String args[]){ Person tom = new Person(1,25); Person john = new Person(2,27); } }
當沒有指定構造函數時,編譯器爲類自動添加形如:類名( ){ } 的構造函數。
class Point{ public int x; public int y; } ... Point p = new Point();
方法重載
方法的重載是指一個類中可以定義有相同的名字,但參數不同的多個方法。調用時,會根據不同參數表選擇對應的方法。
void info() { System.out.println("my id is :" + id); } void info(String t) { System.out.println(t + " my id is" + id); }
構造方法也可以重載。
Person() { id = 100; age = 20; } Person(int _id) { id = _id; age = 30; } Person(int _id, int _age) { id = _id; age = _age; }
對象創建與使用
- 必須使用 new 關鍵字創建對象
- 使用對象【引用.成員變量】來引用對象的成員變量
- 使用對象【引用.方法(參數列表)】來調用對象的方法
- 同一類的每一對象有不同的成員變量存儲空間
- 同一類的每個對象共享該類的方法
- 非靜態方法是針對每個對象進行調用
this 關鍵字
- 在類的方法定義中使用的this關鍵字代表使用該方法的對象的應用
- 在必須指出當前使用方法的對象是誰時要使用this
- 有時使用this可以處理方法中成員變量和參數重名的情況
this可以看作是一個變量,它的值時當前對象的引用
public class Leaf{ int i = 0; Leaf(int i ){ this i = i; } Leaf increament() { i++; return this; } void print(){ System.out.println("i = "+i); } public static void main(String[] args){ Leaf leaf = new Leaf(100); leaf.increament().increament().print(); } }
static 關鍵字
- 在類中,用static聲明的成員變量爲靜態成員變量,它爲該類的公用變量,在第一次使用時被初始化,對於該類的所有對象來說,static成員變量只有一份。
- 用static聲明的方法爲靜態方法,在調用該方法時,不會將對象的引用傳遞給它,所以在static方法中不可訪問非static的成員。
- 靜態方法不再是針對某個對象調用,所以不能訪問非靜態成員。
- 可以通過對象引用或類名(不需要實例化)訪問靜態成員。
package 和 import 語句
爲了便於管理大型軟件系統中數目衆多的類,解決類的命名衝突問題,Java引入包(package)機制,提供類的多重類命名空間。
- 如果想把一個類放入包中,在這個類源文件第一句話寫package
- 必須保證該類的class文件位於正確目錄下
- 該類的源碼可能會產生影響
- 刪除或轉移到另外的目錄
- 另外的類想訪問的話
- 寫全名
- 引入
- *
- 具體類名
- 訪問位於同一個包中的類不需要引入
- 必須class文件的最上層包的父目錄位於classpath下
- 執行一個類需要寫全包名
J2SDK 中主要的包介紹
- java.lang 包含一些Java語言的核心類,如String、Math、Integer、System和Thread,提供常用功能。
- java.awt 包含了構成抽象窗口工具類(abstract window toolkits)的多個類,這些類被用來構建和管理應用程序的圖形用戶界面(GUI)。
- java.applet 包含applet運用所需的一些類。
- java.net 包含執行與網絡相關的操作的類。
- java.io 包含能夠提供多種輸入/輸出功能的類。
- java.util 包含一些實用工具類,如定義系統特性、實用與日期日曆相關的函數。
- java.lang包中的類,不需要引入,可以直接使用。
- 把自己的類打成jar包:jar -cvf xxx.jar * . *
類的繼承
Java中使用extends關鍵字實現類的繼承機制,其語法規則爲:
<modifier> class <name> [extends <superclass>] { ... ... }
通過繼承,子類自動擁有了基類(superclass)的所有成員(成員變量和方法)。
Java只支持單繼承,不允許多繼承:
- 一個子類只能有一個基類,一個基類可以派生出多個子類
//繼承中的權限控制 class Parent{ private int n_private = 1; int n_friendly = 2; // 包權限:同一個包內可以訪問 protected int n_protected = 3; public int n_public = 4; } class Child extends Parent { public void f () { // n_private = 10; 錯誤,繼承中私有變量不能訪問 n_friently = 20; n_protected = 30; n_public = 40; } }
訪問控制
Java權限修飾符public protected private 置於類的成員定義前,用來限定其他對象對該類對象成員的訪問權限。
對於class的權限修飾只可以用 public 和 default
- public 類可以在任意地方被訪問
- default 類只可以被同一個包內部的類訪問
方法重寫
在子類中可以根據需要對從基類中繼承來的方法進行重寫
重寫方法必須和被重寫方法具有相同方法名稱,參數列表和返回類型
重寫方法不能使用比被重寫方法更嚴格地訪問權限
super 關鍵字
在Java類中使用 super 來引用基類的成分,例如:
class FatherClass { public int value; public void f () { value = 100; System.out.println("FatherClass.value = "+value); } } class ChildClass extends FatherClass { public int value; public void f () { super.f(); //super指向當前對象的父對象 value = 200; System.out.println("ChildClass.value ="+value); System.out.println(value); System.out.println(super.value); } }
繼承中的構造方法
- 子類的構造的過程中必須調用其基類的構造方法。
- 子類可以在自己的構造方法中使用super(argument_list)調用基類的構造方法。
- 使用this(argument_list)調用本類的另外的構造方法
- 如果調用super,必須寫在子類構造方法的第一行
- 如果子類的構造方法中沒有顯示地調用基類構造方法,則系統默認調用基類無參數的構造方法
- 如果子類構造方法中既沒顯示調用基類構造方法,而基類中又沒有無參的構造方法,則編譯出錯。
參數拷貝來拷貝去,最終剩下堆裏的對象和棧裏的引用以及數據區的靜態變量。
Object類
- Object 類是所有Java類的根基類
如果在類的聲明中未使用extends關鍵字指明其基類,則默認基類爲Object類
public class Person { ... ... }
等價於:
public class Person extends Object{ ... ... }
toString 方法
- Object 類中定義有public String toString() 方法,其返回值是String類型,描述當前對象的有關信息
- 在進行String與其它類型數據的連接操作時(如:System.out.println(“info”+person)),將自動調用該對象類的toString() 方法
- 可以根據需要在用戶自定義類型中重寫toString()方法
hashcode 解釋
每一個對象都有一個獨一無二的哈希編碼,可以通過這個哈希編碼在內存中找到這個對象並確定這個對象的位置。
equals 方法
- public boolean equals(Object obj)方法
- 定義對象是否“相等”的邏輯
- Object 的 equals方法定義爲:x.equals(y)當x和y是同一個對象的引用時,返回true否則返回false
- J2SDK提供的一些類,如String,Date等,重寫了Object的equals方法,調用這些類的equals方法,x.equals(y),當x和y所引用的對象是同一類對象且屬性內容相等時(並不一定是相同對象),返回true否則返回false
可以根據需要在用戶自定義類型中重寫equals方法
public class TestEquals { public static void main(String[] args) { Cat c1 = new Cat(1,2,3); Cat c2 = new Cat(1,2,3); //類Cat重寫從Object類默認集成的方法equals() System.out.println(c1 == c2); //false System.out.println(c1.equals(c2)); //true //String類已經中重寫了方法equals() String s1 = new String("hello"); String s2 = new String("hello"); System.out.println(s1 == s2); //false System.out.println(s1.equals(s2)); //true } } class Cat { int color; int height, weight; public Cat(int color, int height, int weight) { this.color = color; this.height = height; this.weight = weight; } public boolean equals(Object obj) { if(obj == null) return false; else { if(obj instanceof Cat) { Cat c = (Cat)obj; if(this.color == c.color && this.height == c.height && this.weight == c.weight) { return true; } } } return false; } }
對象轉型(casting)
- 一個基類的引用類型變量可以“指向”其子類的對象
- 一個基類的引用不可以訪問其子類對象新增加的成員(屬性和方法)
- 可以使用引用變量 instanceof 類名來判斷該引用型變量所“指向”的對象是否屬於該類或該類的子類。
子類的對象可以當做基類的對象來使用稱爲向上轉型(upcasting),反之稱爲向下轉型(downcasting)。
class Animal { public String name; Animal (String name) { this.name = name; } } class Cat extends Animal { public String eyesColor; Cat (String n, String c) { super(n); eyesColor = c; } } class Dog extends Animal { public String furColor; Dog (String n, String c) { super(n); furColor = c; } }
public class Test { public static void main(String args[]) { Animal a = new Animal("name"); Cat c = new Cat("catname","blue"); Dog d = new Dog("dogname","black"); System.out.println(a instanceof Animal); //true System.out.println(c instanceof Animal); //true System.out.println(d instanceof Animal); //true System.out.println(a instanceof Cat); //false a = new Dog("bigyellow","yellow"); System.out.println(a.name); //bigyellow //System.out.println(a.furname); //!error System.out.println(a instanceof Animal); //true System.out.println(a instanceof Dog); //true Dog d1 = (Dog)a; //要加強制轉換符 System.out.println(d1.furColor); //yellow } }
public class Test { public static void main(String args[]) { Test test = new Test(); Animal a = new Animal("name"); Cat c = new Cat("catname","blue"); Dog d = new Dog("dogname", "black"); test.f(a); test.f(c); test.f(d); } public void f(Animal a) { System.out.println("name: "+a.name); if(a instanceof Cat) { Cat cat = (Cat)a; System.out.println(" "+cat.eyesColor+" eyes"); } if(a instanceof Dog) { Dog dog = (Dog)a; System.out.println(" "+dog.furcolor+ "fur"); } } }
動態綁定和多態
- 動態綁定:是指在執行期間(而非編譯期間)判斷所引用對象的實際類型,根據其實際的類型調用其相應的方法
下面的例子中,根據Lady對象的成員變量pet所引用的不同的實際類型而調用相應的enjoy方法
class Animal { private String name; Animal (String name) { this.name = name;} private void enjoy() { System.out.println("叫聲。。。。。"); } } class Cat extends Animal { private String eyesColor; Cat(String n, String c) { super(n); eyesColor = c;} public void enjoy() { System.out.println("貓叫聲。。。。。"); } } class Dog extends Animal { private String furColor; Cat(String n, String c) { super(n); furColor = c;} public void enjoy() { System.out.println("狗叫聲。。。。。"); } } class Lady { private String name; private Animal pet; Lady(String name, Animal pet) { this.name = name; this.pet = pet; } public void myPetEnjoy() { pet.enjoy(); } } public class Test { public static void main(String args[]) { Cat c = new Cat("catname","blue"); Dog d = new Dog("dogname","black"); Lady l1 = new Lady("l1",c); Lady l2 = new Lady("l2",d); l1.myPetEnjoy(); l2.myPetEnjoy(); } }
- 多態的存在有三個必要條件:
- 要有繼承;
- 要用重寫;
- 父類引用指向子類對象;
抽象類
- 用abstract關鍵字來修飾一個類時,這個類叫做抽象類;用abstract來修飾一個方法時,該方法叫做抽象方法。
- 含有抽象方法的類必須被聲明爲抽象類,抽象類必須被繼承,抽象方法必須被重寫。
- 抽象類不能被實例化。
抽象方法只需聲明,而不需實現。
abstract class Animal { private String name; Animal (String name) { this.name = name; } public abstract void enjoy(); } class Cat extends Animal { private String eyesColor; Cat(String n, String c) { super(n); eyesColor = c; } public void enjoy() { System.out.println("貓叫聲。。。。"); } }
Final關鍵字
- final 的變量的值不能夠被改變
- final 的成員變量
- final 的局部變量(形參)
- final 的方法不能夠被重寫
final 的類不能被繼承
接口
- 接口(interface)是抽象方法和常量值的定義的集合。
從本質上講,接口是一種特殊的抽象類,這種抽象類中只包含常量和方法的定義,而沒有變量和方法的實現。
//接口中沒有abstract,但是所有的都是abstract public interface Runner { //public static final int id = 1; int id = 1; //默認是public static final 關鍵字寫不寫都行 public void start(); public void run(); public void stop(); }
接口特性
- 接口可以多重實現 (意思:可以實現多繼承)
- 接口中聲明的屬性默認爲 public static final 的,也只能是public static final
- 接口中只能定義抽象方法,而且這些方法默認爲pubic的,也只能是public的
- 接口可以繼承其他的接口,並添加新的屬性和抽象類
- 多個無關的類可以實現同一個接口
- 一個類可以實現多個無關的接口
- 與繼承關係類似,接口與實現類之間存在多態性
定義Java類的語法格式:
<modifier> class <name> [extends <superclass>] [implements <interface> [, <interface>]* ] { <declarations>*}
interface Singer { public void sing(); public void sleep(); } class Student implement Singer { private String name; Student(String name) { this.name = name; } public void study() { System.out.println("studying"); } public String getName() { return name; } public void sing() { System.println("Student is singing"); } public void sleep() { System.out.println("Student is sleeping"); } }
interface Singer { public void sing(); public void sleep(); } interface Painter { public void paint(); public void eat(); } class Student implement Singer { private String name; Student(String name) { this.name = name; } public void study() { System.out.println("studying"); } public String getName() { return name; } public void sing() { System.println("Student is singing"); } public void sleep() { System.out.println("Student is sleeping"); } } class Teacher implements Singer,Painter { private String name; public String getString() { return name; } Teacher(String name) { this.name = name; } pulic void teach() { System.out.println("teaching"); } pulic void sing() { System.out.println("teaching is singing"); } pulic void sleep() { System.out.println("teaching is sleeping"); } pulic void paint() { System.out.println("teaching is painting"); } pulic void eat() { System.out.println("teaching is eating"); } } public class TestImplement { public static void main (String[] args) { Singer s1 = new Student("le"); s1.sing(); s1.sleep(); Singer s2 = new Teacher("steven"); s2.sing(); s2.sleep(); Painter p1 = (Painter)s2; p1.paint(); p1.eat(); } }
總結
- 對象和類的概念
- 類(對象)之間的關係
- 面向對象思想
- class
- new
- 引用的概念
- 構造方法的概念
- 方法重載
- 構造方法重載
- this
- static
- package & import
- private default protected public
- extends
- overwrite
- final
- Object
- toString
- equals
- upcasting downcasting
- polymophysm / dynamic binging / late binging
- abstract class
- interface
- implements