面向對象編程(Object Oriented Programming,OOP)是一種計算機模擬人類的天然思惟方式的編程架構技術,解決了傳統結構化開發方法中客觀世界描述工具與軟件結構的不一致性問題。Java是一種純面向對象的語言,與C語言不同他是面向過程的語言。通俗說Java程序主要是由類組成的,而C是由函數組成的。java
面向對象很是重要,恰當的使用面向對象會使咱們開發的系統擁有「可複用」、「可擴展」、「可維護」的特色。面向對象的概念和應用已超越了程序設計和軟件開發,擴展到如數據庫系統、交互式界面、應用結構、應用平臺、分佈式系統、網絡管理結構、CAD技術、人工智能等領域。面向對象是一種對現實世界理解和抽象的方法,是計算機編程技術發展到必定階段後的產物,做爲開發者面向對象您必須理解後掌握。面試
面向對象中對象與類是最重要的,先來理解對象、類及他們間的關係。數據庫
世界萬物都是對象(object),在面向對象中一切都是對象編程
對象:系統中用來描述客觀事物的實體,構成系統的基本單位
對象封裝了屬性(特徵)和方法(操做)數組
屬性——對象具備的各類特徵
每一個對象的每一個屬性都擁有特定值
例如:布蘭尼和朱麗葉的體重不同網絡
方法——對象執行的操做多線程
對象就是封裝了屬性與方法的實體架構
1.二、類編程語言
猜猜下面描述的是什麼:
屬性:有排量、有速度、有油耗、有2-5個座位、有4個輪子
方法:載客、加速、轉向、行駛、鳴笛
類:是擁有共同屬性和方法的對象的抽象
類是模子,肯定對象將會擁有的特徵(屬性)和行爲(方法)
類是對象的類型
對象是類的實例
面向對象編程(Object Oriented Programming,OOP)是一種計算機模擬人類的天然思惟方式的編程架構技術,解決了傳統結構化開發方法中客觀世界描述工具與軟件結構的不一致性問題
面向對象編程是相對面向過程的,如C語言
Java是純面向對象編程語言
面向對象中最重要的是對象與類
全部Java程序都以類class爲組織單元
關鍵字class定義自定義的數據類型
類將現實世界中的概念模擬到計算機程序中
定義類的基本結構:
public class 類名 { //定義屬性部分 屬性1的類型 屬性1; 屬性2的類型 屬性2; … 屬性n的類型 屬性n; //定義方法部分 方法1; 方法2; … 方法m; }
定義一個類的步驟
一、定義類名
二、編寫類的屬性
三、編寫類的方法
定義一個類用來抽象圓形
//1包 package com.gdnf.java.d1; //註釋 /** *圓 */ //2類 public class Circle { /**圓周率*/ //7常量,不能被修改,靜態成員能夠直接訪問 public static final double PI=3.1415926; /**半徑*/ //3屬性(成員變量,方法內的變量叫局部變量不能被訪問修飾符) //命名:數字,字母,下劃線,$組成;camel 駱駝命名法,首字母小寫,從第2個單詞開始大寫 //成員變量有默認值,數字通常爲0,字符爲null public int radiusLength; /**得到面積*/ //4方法,完成特定功能的代碼塊 public double getArea() { //5局部變量 double result=PI*radiusLength*radiusLength; //將結果返回 return result; } }
類是抽象的,並不能直接使用,將類型實例化後使能夠動態應用了。
建立對象的步驟:
a).使用new建立類的一個對象
類型名 對象名=new 類型名();
b).使用對象:使用「.」進行如下操做
給類的屬性賦值:對象名.屬性
調用類的方法:對象名.方法名()
c).兩種實例化對象的方法
1.類名 對象名=new 類名();
2.類名 對象名=new 類名(配置參數);
package com.gdnf.java.d1; /**遊戲類*/ public class Game { /**主方法,程序的入口*/ public static void main(String[] args) { //6對象,實例化對象 Circle c1=new Circle(); c1.radiusLength=10; Circle c2=new Circle(); c2.radiusLength=5; //方法調用 System.out.println(c1.getArea()); System.out.println(c2.getArea()); //靜態的成員屬於類,非靜態成員屬於對象 //靜態的是公用的,在內存中只有一份 System.out.println("PI="+Circle.PI+","+c1.PI); } }
運行結果:
類文件中有:包(package)、類(class)、成員變量/屬性(attribute)、方法(method)、常量(const,final)、對象(object)、局部變量(variable)
圓:
//1包 package com.gdnf.java.d1; //註釋 /** *圓 */ //2類 public class Circle { /**圓周率*/ //7常量,不能被修改,靜態成員能夠直接訪問 public static final double PI=3.1415926; /**半徑*/ //3屬性(成員變量,方法內的變量叫局部變量不能被訪問修飾符) //命名:數字,字母,下劃線,$組成;camel 駱駝命名法,首字母小寫,從第2個單詞開始大寫 //成員變量有默認值,數字通常爲0,字符爲null public int radiusLength; /**得到面積*/ //4方法,完成特定功能的代碼塊 public double getArea() { //5局部變量 double result=PI*radiusLength*radiusLength; //將結果返回 return result; } }
客戶端調用:
package com.gdnf.java.d1; /**遊戲類*/ public class Game { /**主方法,程序的入口*/ public static void main(String[] args) { //6對象,實例化對象 Circle c1=new Circle(); c1.radiusLength=10; Circle c2=new Circle(); c2.radiusLength=5; //方法調用 System.out.println(c1.getArea()); System.out.println(c2.getArea()); //靜態的成員屬於類,非靜態成員屬於對象 //靜態的是公用的,在內存中只有一份 System.out.println("PI="+Circle.PI); } }
運行結果:
//建立對象,c1是對類的對象
Circle c1=new Circle();
//經過對象名訪問對象的屬性「半徑」
c1.radiusLength=10;
方法:根據參數完成特定功能的代碼塊
如方法public int Add(int n1,int n2),int是返回值的類型,n1,n2參數,完成的功能相加。
語法:訪問修飾符 返回值類型 方法名([參數類型 參數名]...){
方法體
[return 返回值]
}
若是返回值爲void則表示沒有返回值,其它狀況必須有返回值
package com.gdnf.java.d1; /**計算器*/ public class Calc { /**加法方法*/ public int add(int n1,int n2){ //返回結果 return n1+n2; } }
調用:
package com.gdnf.java.d1; /***/ public class Computer { public static void main(String[] args) { //建立對象 Calc calc=new Calc(); System.out.println("1+1="+calc.add(1, 1)); } }
package com.gdnf.java.d1; /**計算器*/ public class Calc { /**顯示信息*/ public void show(String msg){ System.out.println("神算子計算器告訴你結果:"+msg); } }
調用:
package com.gdnf.java.d1; /***/ public class Computer { public static void main(String[] args) { //建立對象 Calc calc=new Calc(); calc.show("1+1="+calc.add(1, 1)); calc.show(985+""); } }
結果:
當方法的返回值聲明爲「void」時方法沒有返回值。
同名的方法不一樣參數,與返回值沒有關係。
package com.gdnf.java.d1; /**計算器*/ public class Calc { /**顯示信息*/ public void show(String msg){ System.out.println("神算子計算器告訴你結果:"+msg); } /**顯示信息*/ public void show(Object msg){ System.out.println("超算子計算器告訴你結果:"+msg); } /**加法方法*/ public int add(int n1,int n2){ //返回結果 return n1+n2; } }
運行結果:
package com.gdnf.java.d1; /***/ public class Computer { public static void main(String[] args) { //建立對象 Calc calc=new Calc(); calc.show("1+1="+calc.add(1, 1)); calc.show(985+""); calc.show(19.8); calc.show(true); calc.show("1+5=6"); } }
運行結果:
a)、方法內能夠直接調用成員變量
b)、方法中的局部變量間不容許相互訪問
c)、內部能夠無限訪問外部,外部不容許訪問內部,注意靜態
d)、成員變量定義就有默認值,局部變量沒有默認值
package com.gdnf.java.d3; public class Point { public int x; public int y; //方法內能夠直接調用成員變量 public void set(int n1,int n2) { int i=100; this.x=n1; this.y=n2; System.out.println("x:"+this.x+",y:"+this.y); //this表示當前對象 } public void add(int n3,int n4){ //i++; //訪問set方法的i是錯誤的 int j=0; if(n3>100){ j++; int k=0; if(n4>200) { k++; } } } }
靜態成員屬於類,用類調用,是全部對象共享的。
直接用類名能夠得到靜態成員,固然對象名也能夠但不推薦。
package com.gdnf.java.d1; /**計數器*/ public class Counter { public int n1; public static int n2; public void show(){ System.out.println("n1="+n1+",n2="+n2); } }
調用
package com.gdnf.java.d1; public class CounterClient { public static void main(String[] args) { Counter c1=new Counter(); c1.n1++; Counter c2=new Counter(); c2.n1++; c1.show(); c2.show(); } }
結果:
package com.gdnf.java.d1; /**計數器*/ public class Counter { //每一個實例獨享 public int n1; //全部實例與類共享,只有一份 public static int n2; public void show(){ System.out.println("n1="+n1+",n2="+n2); } }
調用:
package com.gdnf.java.d1; public class CounterClient { public static void main(String[] args) { Counter c1=new Counter(); c1.n2++; c1.n1++; Counter c2=new Counter(); c2.n2++; c2.n1++; //靜態成員屬於類,直接用類名調用 Counter.n2++; //Counter.n1++; 不容許直接用類名調用非靜態成員 c1.show(); c2.show(); } }
結果:
a)、非靜態方法能夠直接調用靜態方法
package com.gdnf.java.d1; /**計數器*/ public class Counter { //每一個實例獨享 public int n1; //全部實例與類共享,只有一份 public static int n2; public void show(){ show("n1="+n1+",n2="+n2); } //靜態方法,完成顯示 public static void show(Object message){ System.out.println("輸出結果:"+message); } //靜態方法,完成減法 public static void subtract(int n2,int n1){ //靜態調用靜態 直接 show("n2-n1="+(n2-n1)); } //非靜態方法,完成乘法 public void mutil(int n1,int n2){ //非靜態調用靜態,直接 show(n1*n2); } }
b)、靜態方法不容許直接調用非靜態方法,只能經過對象調用
package com.gdnf.java.d1; /**計數器*/ public class Counter { //每一個實例獨享 public int n1; //全部實例與類共享,只有一份 public static int n2; public void show(){ show("n1="+n1+",n2="+n2); } //靜態方法,完成顯示 public static void show(Object message){ System.out.println("輸出結果:"+message); } //靜態方法,完成減法 public static void subtract(int n2,int n1){ //靜態調用靜態 直接 show("n2-n1="+(n2-n1)); //靜態不能直接調用非靜態 //mutil(100,200); 報錯 //靜態方法能夠經過對象名調用非靜態 Counter counter=new Counter(); counter.mutil(100,200); } //非靜態方法,完成乘法 public void mutil(int n1,int n2){ //非靜態調用靜態,直接 show(n1*n2); } }
靜態調用非靜態必須經過對象名調用,需實例化對象
package com.gdnf.java.d1; public class Student { int i=100; public static void main(String[] args) { Student tom=new Student(); System.out.println(tom.i); } }
a). static能夠修飾:類,變量,方法
b). static修飾的變量只有一個副本
c). static修飾的方法裏面不能引用非靜態變量
d). static修飾的方法裏面不能引用this關鍵字
e). static方法不能被非靜態方法重寫
爲了更好地組織類,Java 提供了包機制,用於區別類名的命名空間。
包的做用
一、把功能類似或相關的類或接口組織在同一個包中,方便類的查找和使用。分文別類
二、如同文件夾同樣,包也採用了樹形目錄的存儲方式。
三、包也限定了訪問權限,擁有包訪問權限的類才能訪問某個包中的類。
Java 使用包(package)這種機制是爲了防止命名衝突,訪問控制,提供搜索和定位類(class)、接口、枚舉(enumerations)和註解(annotation)等。
使用package聲明包、通常使和倒置的域名,如com.zhangguo.項目名.具體分類
src上右鍵
輸入包名,不能重複,所有小寫
包與文件夾一一對應:
爲了可以使用某一個包的成員,咱們須要在 Java 程序中明確導入該包。使用 "import" 語句可完成此功能。
當使用一個類時,若是類不在當前包中則應該先導入包或用全名稱引用。
第一個Player類:
package com.zhangguo.game; //包 //玩家類 public class Player { //屬性,默認訪問修飾符 String name; //展現 public void show() { System.out.println("當前玩家是:"+this.name); } //public //能夠被任何類訪問 //protected //能夠被同一包中的全部類訪問 //能夠被全部子類訪問 //子類沒有在同一包中也能夠訪問 //private //只可以被當前類的方法訪問 //缺省(無訪問修飾符) //default 不寫 //能夠被同一包中的全部類訪問 //若是子類沒有在同一個包中,也不能訪問 }
第二個Player類:
package com.zhangguo.project; public class Player { public void msg(){ System.out.println("我是一個運行員"); } }
使用:
package com.zhangguo.test; //導入包,若是是*號則表示包下的全部類 //import com.zhangguo.game.*; //導入單個類Player import com.zhangguo.game.Player; public class PlayerTest { public static void main(String[] args) { //實例化對象 Player player=new Player(); //訪問屬性 player.name="西門吹雪"; //調用方法 player.show(); //全名稱引用 com.zhangguo.project.Player hero=new com.zhangguo.project.Player(); hero.msg(); } }
a)、類中默認引入java.lang.*包,language(語言包)
package com.gdnf.java.d3; //導入系統已定義好的類 import java.util.Date; public class Person { public static void main(String[] args) { System.out.println("Hello java.lang"); Date date=new Date(); System.out.println("當前時間:"+date.toLocaleString()); } }
訪問修飾符 修飾符 class 類名稱 extends 父類名稱 implement 接口名稱
(訪問修飾符與修飾符的位置能夠互換)
訪問修飾符 |
||
名稱 |
說明 |
備註 |
public |
能夠被全部類訪問(使用) |
public類必須定義在和類名相同的同名文件中 |
package |
能夠被同一個包中的類訪問(使用) |
默認的訪問權限,能夠省略此關鍵字,能夠定義在和public類的同一個文件中 |
修飾符 |
||
名稱 |
說明 |
備註 |
final |
使用此修飾符的類不可以被繼承 |
|
abstract |
若是要使用abstract類,以前必須首先建一個繼承abstract類的新類,新類中實現abstract類中的抽象方法。 |
類只要有一個abstract方法,類就必須定義爲abstract,但abstract類不必定非要保護abstract方法不可 |
l Java中沒有全局變量,只有方法變量、實例變量(類中的非靜態變量)、類變量(類中的靜態變量)。
l 方法中的變量不可以有訪問修飾符。因此下面訪問修飾符表僅針對於在類中定義的變量。
l 聲明實例變量時,若是沒有賦初值,將被初始化爲null(引用類型)或者0、false(原始類型)。
l 能夠經過實例變量初始化器來初始化較複雜的實例變量,實例變量初始化器是一個用{}包含的語句塊,在類的構造器被調用時運行,運行於父類構造器以後,構造器以前。
l 類變量(靜態變量)也能夠經過類變量初始化器來進行初始化,類變量初始化器是一個用static{}包含的語句塊,只可能被初始化一次。
訪問修飾符 |
||
名稱 |
說明 |
備註 |
public |
能夠被任何類訪問 |
|
protected |
能夠被同一包中的全部類訪問 能夠被全部子類訪問 |
子類沒有在同一包中也能夠訪問 |
private |
只可以被當前類的方法訪問 |
|
缺省(無訪問修飾符) |
能夠被同一包中的全部類訪問 |
若是子類沒有在同一個包中,也不能訪問 |
修飾符 |
||
名稱 |
說明 |
備註 |
static |
靜態變量(又稱爲類變量,其它的稱爲實例變量) |
能夠被類的全部實例共享。 並不須要建立類的實例就能夠訪問靜態變量 |
final |
常量,值只可以分配一次,不能更改 |
注意不要使用const,雖然它和C、C++中的const關鍵字含義同樣,能夠同static一塊兒使用,避免對類的每一個實例維護一個拷貝 |
transient |
告訴編譯器,在類對象序列化時,此變量不須要持久保存 |
主要是由於改變量能夠經過其它變量來獲得,使用它是爲了性能的問題 |
volatile |
指出可能有多個線程修改此變量,要求編譯器優化以保證對此變量的修改可以被正確的處理 |
|
訪問修飾符 修飾符 返回類型 方法名稱(參數列表)throws 違例列表
l 類的構造器方法不可以有修飾符、返回類型和throws子句
l 類的構造器方法被調用時,它首先調用父類的構造器方法,而後運行實例變量和靜態變量的初始化器,而後才運行構造器自己。
l 若是構造器方法沒有顯示的調用一個父類的構造器,那麼編譯器會自動爲它加上一個默認的super(),而若是父類又沒有默認的無參數構造器,編譯器就會報錯。super必須是構造器方法的第一個子句。
l 注意理解private構造器方法的使用技巧。
訪問修飾符 |
||
名稱 |
說明 |
備註 |
public |
能夠從全部類訪問 |
|
protected |
能夠被同一包中的全部類訪問 能夠被全部子類訪問 |
子類沒有在同一包中也能夠訪問 |
private |
只可以被當前類的方法訪問 |
|
缺省 無訪問修飾符 |
能夠被同一包中的全部類訪問 |
若是子類沒有在同一個包中,也不能訪問 |
修飾符 |
||
名稱 |
說明 |
備註 |
static |
靜態方法(又稱爲類方法,其它的稱爲實例方法) |
提供不依賴於類實例的服務 並不須要建立類的實例就能夠訪問靜態方法 |
final |
防止任何子類重載該方法 |
注意不要使用const,雖然它和C、C++中的const關鍵字含義同樣 能夠同static一塊兒使用,避免對類的每一個實例維護一個拷貝 |
abstract |
抽象方法,類中已聲明而沒有實現的方法 |
不能將static方法、final方法或者類的構造器方法聲明爲abstract |
native |
用該修飾符定義的方法在類中沒有實現,而大多數狀況下該方法的實現是用C、C++編寫的。 |
參見Sun的Java Native接口(JNI),JNI提供了運行時加載一個native方法的實現,並將其於一個Java類關聯的功能 |
synchronized |
多線程的支持 |
當一個此方法被調用時,沒有其它線程可以調用該方法,其它的synchronized方法也不能調用該方法,直到該方法返回 |
訪問修飾符 interface 接口名稱 extends 接口列表
l接口不可以定義其聲明的方法的任何實現
l 接口中的變量老是須要定義爲「public static final 接口名稱」,但能夠不包含這些修飾符,編譯器默認就是這樣,顯示的包含修飾符主要是爲了程序清晰
訪問修飾符 |
|
名稱 |
說明 |
public |
全部 |
無訪問修飾符(默認) |
同一個包內 |
上課視頻B站高清:http://search.bilibili.com/all?keyword=%E5%BC%A0%E6%9E%9C
上課示例下載:http://files.cnblogs.com/files/best/Chapter3.3.7z
10.一、在java中咱們定義一個類會產生一個後綴爲java的文件,請問類中能夠包含哪些元素(如類成員)?
類文件中有:包(package)、類(class)、成員變量/屬性(attribute)、方法(method)、常量(const,final)、對象(object)、局部變量(variable)
10.二、請定義一個汽車(Car)類,在類中添加一個屬性int類型的屬性(speed)。
public class Car{ public int speed; }
10.三、請使用Car類建立兩個對象,實例化兩輛車,一輛名爲bmw,一輛名爲benz。
package com.gdnf.java.d3; /**停車場*/ public class Park { public static void main(String[] args) { Car bmw=new Car(); Car benz=new Car(); } }
10.四、設置bmw與benz的車速分別爲198與205
package com.gdnf.java.d3; /**停車場*/ public class Park { public static void main(String[] args) { Car bmw=new Car(); Car benz=new Car(); bmw.speed=198; benz.speed=205; } }
10.五、在Car類中添加一個方法inc實現加速功能,方法中有一個int類型的參數n,當執行方法時把當前車速屬性增加n並輸出到當前車速。
package com.gdnf.java.d3; //車類 public class Car{ //速度 public int speed; //加速方法 public void inc(int n){ speed=speed+n; System.out.println("當前車速:"+speed); } }
調用:
package com.gdnf.java.d3; /**停車場*/ public class Park { public static void main(String[] args) { Car bmw=new Car(); Car benz=new Car(); //訪問屬性 bmw.speed=198; benz.speed=205; //調用方法 bmw.inc(10); benz.inc(-5); } }
結果:
10.六、什麼是重載?
同名的方法不一樣參數(類型或個數不一樣),與返回值沒有關係,是多態的一種體現。
package com.gdnf.java.d3; //車類 public class Car { // 速度 public int speed; // 加速方法 public void inc(int n) { speed = speed + n; System.out.println("當前車速:" + speed); } // 默認加速 public void inc() { inc(10); } // 默認加速 public void inc(int n1, int n2, int n3) { inc(n1); inc(n2); inc(n3); System.out.println("屢次加速"); } }
10.七、靜態方法有什麼特色?
a)、使用關鍵字static
b)、靜態的成員屬於類,通常用類名直接調用,無需實例化
c)、非靜態能夠直接調用靜態,靜態需經過對象名調用非靜態
d)、靜態是共享的,非靜態是獨享的
package com.gdnf.java.d3; //車類 public class Car { // 速度 public int speed; // 加速方法 public void inc(int n) { speed = speed + n; System.out.println("當前車速:" + speed); //非靜態可直接調靜態 run(); } // 默認加速 public void inc() { inc(10); } // 默認加速 public void inc(int n1, int n2, int n3) { inc(n1); inc(n2); inc(n3); System.out.println("屢次加速"); } //靜態方法 public static void run(){ System.out.println("車正在前行...嘟嘟..."); } //靜態方法 public static void start() { //靜態調用非靜態實例調用 Car byd=new Car(); byd.inc(10); //靜態直接調靜態 run(); } }
測試:
package com.gdnf.java.d3; /**停車場*/ public class Park { public static void main(String[] args) { Car bmw=new Car(); Car benz=new Car(); //訪問屬性 bmw.speed=198; benz.speed=205; //調用方法 bmw.inc(10); benz.inc(-5); benz.inc(); benz.inc(); //靜態方法直接調 Car.run(); Car qq=new Car(); qq.speed=100; qq.start(); } }
結果: