函數也稱爲方法,就是定義在類中的具備特定功能的一段獨立代碼。用於定義功能,提升代碼的複用性。java
函數的特色
1> 定義函數能夠將功能代碼進行封裝,便於對該功能進行復用;
2> 函數只有被調用纔會被執行;
3> 對於函數沒有具體返回值的狀況,返回值類型用關鍵字void表示,那麼該函數中的return語句若是在最後一行能夠省略不寫,系統會幫你自動加上;
4> 函數中只能調用函數,不能夠在函數內部定義函數。編程
修飾符 返回值類型 方法名(參數類型 形式參數1,參數類型 形式參數2,..) { 方法體; return 返回值; } //修飾符: 可選,告訴編譯器如何調用該方法。定義了該方法的訪問類型。 //返回值類型:函數運行後的結果的數據類型 //參數類型:形式參數的數據類型
主函數 main():
1> 保證該類的獨立運行;
2> 程序的入口,自動調用;
3> jvm調用。數組
函數的重載 (overload)安全
重載的概念:
在同一個類中,容許存在一個以上的同名函數,只要它們的參數個數或者參數類型不一樣便可。
重載的特色:
與返回值類型無關,只看參數列表。
重載的好處:
方便於閱讀,優化了程序設計。Java編譯器根據方法簽名判斷哪一個方法應該被調用。多線程
何時用重載?jvm
當定義的功能相同,但參與運算的未知內容不一樣。編程語言
那麼,這時就定義一個函數名稱以表示起功能,方便閱讀,而經過參數列表的不一樣來區分多個同名函數。ide
重載的方法必須擁有不一樣的參數列表。你不能僅僅依據修飾符或者返回類型的不一樣來重載方法。函數
重載示例:
返回兩個整數的和
int add(int x,int y){return x+y;}
返回三個整數的和
int add(int x,int y, int z){return x+y+z;}
返回兩個小數的和
double add(double x,double y){return x+y;}性能
// 重載區分, 重載和返回值類型不要緊 void show(int a,char b,double c){} a. void show(int x,char y,double z){}//沒有,由於和原函數同樣。 b. int show(int a,double c,char b){} //重載,由於參數類型不一樣。 c. void show(int a,double c,char b){}//重載,由於參數類型不一樣。
public class functc { public static void draw(int row, int col){ for (int i=0; i<row; i++){ for (int n=0; n<col; n++){ System.out.print('@'); } System.out.println(); } } public static void main(String[] args) { draw(5, 9); } }
public class funcsj { } public static void main(String[] args) { print99(); } public static void print99(){ for (int i=1; i<10; i++){ for (int n=1; n<i+1; n++){ System.out.print(n+"*"+i+"="+i*n+" "); } System.out.println(); } } } // 結果 1*1=1 1*2=2 2*2=4 1*3=3 2*3=6 3*3=9 1*4=4 2*4=8 3*4=12 4*4=16 1*5=5 2*5=10 3*5=15 4*5=20 5*5=25 1*6=6 2*6=12 3*6=18 4*6=24 5*6=30 6*6=36 1*7=7 2*7=14 3*7=21 4*7=28 5*7=35 6*7=42 7*7=49 1*8=8 2*8=16 3*8=24 4*8=32 5*8=40 6*8=48 7*8=56 8*8=64 1*9=9 2*9=18 3*9=27 4*9=36 5*9=45 6*9=54 7*9=63 8*9=72 9*9=81
public class funcol { public static void main(String[] args) { int num = add(5, 8, 9); System.out.print(num); //22 } public static int add(int x,int y){ return x+y; } public static int add(int x,int y,int z){ return add(x,y)+z; } }
當一個對象被建立時候,構造方法用來初始化該對象。構造方法和它所在類的名字相同,但構造方法沒有返回值。
一般會使用構造方法給一個類的實例變量賦初值,或者執行其它必要的步驟來建立一個完整的對象。
無論你與否自定義構造方法,全部的類都有構造方法,由於Java自動提供了一個默認構造方法,它把全部成員初始化爲0。
一旦你定義了本身的構造方法,默認構造方法就會失效。
public class myfunc { int x; myfunc(int i){ x = i; } }
// myfunc.java public class myfunc { int x; myfunc(int i){ x = i; System.out.println(x); } } // MyDemoTest.java public class MyDemoTest { public static void main(String args[]) { myfunc t1 = new myfunc(9); myfunc t2 = new myfunc(5); System.out.println(t1.x + " " + t2.x); } } // 輸出結果 9 5 9 5
JDK 1.5 開始,Java支持傳遞同類型的可變參數給一個方法。
在方法聲明中,在指定參數類型後加一個省略號(...) 。
一個方法中只能指定一個可變參數,它必須是方法的最後一個參數。任何普通的參數必須在它以前聲明。
//typeName... parameterName public static void My( double... nums){...}
public class myfunc { public static void printNum( double... numbers) { double result = numbers[0]; System.out.println("The value index eq 0: " + result); for (int i = 1; i < numbers.length; i++){ System.out.println("The value is " + numbers[i]); } } public static void main(String args[]) { // 調用可變參數的方法 printNum(1, 2, 9, 5, 8); printNum(new double[]{1, 2, 6}); } } // 輸出結果 The value index eq 0: 1.0 The value is 2.0 The value is 9.0 The value is 5.0 The value is 8.0 The value index eq 0: 1.0 The value is 2.0 The value is 6.0
Java 容許定義這樣的方法,它在對象被垃圾收集器析構(回收)以前調用,這個方法叫作 finalize( ),它用來清除回收對象。
例如,你可使用 finalize() 來確保一個對象打開的文件被關閉了。
在 finalize() 方法裏,你必須指定在對象銷燬時候要執行的操做。
finalize() 通常格式是:
protected void finalize() { // 在這裏終結代碼 }
關鍵字 protected 是一個限定符,它確保 finalize() 方法不會被該類之外的代碼調用。
固然,Java 的內存回收能夠由 JVM 來自動完成。若是你手動使用,則可使用上面的方法。
public class myfunc { public static void main(String args[]) { Cake c1 = new Cake(1); Cake c2 = new Cake(2); Cake c3 = new Cake(3); c2 = c3 = null; System.gc(); //調用Java垃圾收集器 } } class Cake extends Object { private int id; public Cake(int id) { this.id = id; System.out.println("Cake Object " + id + "is created"); } protected void finalize() throws java.lang.Throwable { super.finalize(); System.out.println("Cake Object " + id + "is disposed"); } } // 輸出結果 Cake Object 1is created Cake Object 2is created Cake Object 3is created Cake Object 3is disposed Cake Object 2is disposed
public 類:類屬變量及方法,包內及包外的任何類都可以訪問;
protected 類:類屬變量及方法,包內的任何類,及包外的那些繼承了此類的子類才能訪問;
private 類:類屬變量及方法,包內包外的任何類均不能訪問;
friendly 類:類屬變量及方法不以上這三種修飾符來修飾,那麼包內的任何類均可以訪問它,而包外的任何類都不能訪問它(包括包外繼承了此類的子類),所以,這種類、類屬變量及方法對包內的其餘類是友好的,開放的,而對包外的其餘類是關閉的。
訪問修飾符 修飾符 class 類名稱 extends 父類名稱 implement 接口名稱 (訪問修飾符與修飾符的位置能夠互換)
訪問修飾符 | ||
名稱 | 說明 | 備註 |
public | 能夠被全部類訪問(使用) | public類必須定義在和類名相同的同名文件中 |
package | 能夠被同一個包中的類訪問(使用) | 默認的訪問權限,能夠省略此關鍵字,能夠定義在和public類的同一個文件中 |
修飾符 | ||
名稱 | 說明 | 備註 |
final | 使用此修飾符的類不可以被繼承 | |
abstract | 若是要使用abstract類,以前必須首先建一個繼承abstract類的新類,新類中實現abstract類中的抽象方法。 | 類只要有一個abstract方法,類就必須定義爲abstract,但abstract類不必定非要保護abstract方法不可 |
訪問修飾符 | ||
名稱 | 說明 | 備註 |
public | 能夠被任何類訪問 | |
protected |
能夠被同一包中的全部類訪問
能夠被全部子類訪問
|
子類沒有在同一包中也能夠訪問 |
private | 只可以被當前類的方法訪問 | |
缺省
無訪問修飾符
|
能夠被同一包中的全部類訪問 | 若是子類沒有在同一個包中,也不能訪 |
修飾符 | ||
名稱 | 說明 | 備註 |
static | 靜態變量(又稱爲類變量,其它的稱爲實例變量) |
能夠被類的全部實例共享。
並不須要建立類的實例就能夠訪問靜態變量
|
final | 常量,值只可以分配一次,不能更改 |
注意不要使用const,雖然它和C、C++中的const關鍵字含義同樣
能夠同static一塊兒使用,避免對類的每一個實例維護一個拷貝
|
transient | 告訴編譯器,在類對象序列化的時候,此變量不須要持久保存 | 主要是由於改變量能夠經過其它變量來獲得,使用它是爲了性能的問題 |
volatile | 指出可能有多個線程修改此變量,要求編譯器優化以保證對此變量的修改可以被正確的處理 |
訪問修飾符 修飾符 返回類型 方法名稱(參數列表)throws 違例列表
訪問修飾符 | ||
名稱 | 說明 | 備註 |
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方法也不能調用該方法,直到該方法返回 |
訪問修飾符 | ||
名稱 | 說明 |
|
public | 全部 | |
無訪問修飾符(默認) | 同一個包內 |
繼承可使用 extends 和 implements 這兩個關鍵字來實現繼承,並且全部的類都是繼承於 java.lang.Object,當一個類沒有繼承的兩個關鍵字,則默認繼承object(這個類在 java.lang 包中,因此不須要 import)祖先類。
extends關鍵字
在Java中,類的繼承是單一繼承,也就是說,一個子類只能擁有一個父類,因此 extends 只能繼承一個類。
implements關鍵字
使用 implements 關鍵字能夠變相的使java具備多繼承的特性,使用範圍爲類繼承接口的狀況,能夠同時繼承多個接口(接口跟接口之間採用逗號分隔)。
super 與 this 關鍵字
super關鍵字:咱們能夠經過super關鍵字來實現對父類成員的訪問,用來引用當前對象的父類。
this關鍵字:指向本身的引用
final關鍵字
final 關鍵字聲明類能夠把類定義爲不能繼承的,即最終類;或者用於修飾方法,該方法不能被子類重寫:
聲明類: final class 類名 {//類體} 聲明方法: 修飾符(public,private,void,protected等) final 返回值類型 方法名(){//方法體}
實例變量也能夠被定義爲final,被定義爲final的變量不能被修改。被聲明爲final的內的方法自動地聲明爲final,可是實例變量並非final。
子類不能繼承父類的構造器(構造方法或者構造函數),可是父類的構造器帶有參數的,則必須在子類的構造器中顯式地經過super關鍵字調用父類的構造器並配以適當的當屬列表。
若是父類有無參構造器,則在子類的構造器中用super調用父類構造器不是必須的,若是沒有使用super關鍵字,系統會自動調用父類的無參構造器。
class Animal { private String name; private int id; public Animal(String myName, int myid) { name = myName; id = myid; } public void eat(){ System.out.println(name+"正在吃"); } public void sleep(){ System.out.println(name+"正在睡"); } public void introduction() { System.out.println("Hello everyone, my cardid is "+ id + ", and my name is " + name + "."); } } class Bird extends Animal { public Bird(String myName, int myid) { super(myName, myid); } } class Dog extends Animal { public Dog(String myName, int myid) { super(myName, myid); } } class SuperClass { private int n; SuperClass(){ System.out.println("SuperClass()"); } SuperClass(int n) { System.out.println("SuperClass(int n)"); this.n = n; System.out.println("SuperClass(int n):"+this.n); } } class SubClass extends SuperClass{ private int n; SubClass(){ super(300); System.out.println("SuperClass"); } public SubClass(int n){ super(500); System.out.println("SubClass(int n):"+n); this.n = n; System.out.println("n:"+n+", this.n:"+this.n); } } public class AnimalMain { public static void main(String[] args){ Animal Mouseobjone = new Dog("小虎", 9); Mouseobjone.eat(); //小虎正在吃 Mouseobjone.introduction(); //Hello everyone, my cardid is 9, and my name is 小虎. Animal Mouseobjtwo = new Dog("貝貝", 5); Mouseobjtwo.eat(); //貝貝正在吃 Mouseobjtwo.introduction(); //Hello everyone, my cardid is 5, and my name is 貝貝. SubClass sc = new SubClass(); //輸出 //SuperClass(int n) //SuperClass(int n):300 //SuperClass SubClass sc2 = new SubClass(200); //輸出 //SuperClass(int n):500 //SubClass(int n):200 //n:200, this.n:200 } }
方法的重寫(Overriding)和重載(Overloading)是java多態性的不一樣表現,重寫是父類與子類之間多態性的一種表現,重載是一類中多態性的一種表現。
class Animal{ public void move(){ System.out.println("動物能夠行走"); } } class Dog extends Animal{ public void move(){ super.move(); System.out.println("狗會跳"); } public void bark(){ System.out.println("狗會叫"); } } public class Override { public static void main(String args[]){ Animal animalobj = new Animal(); Dog dogobj = new Dog(); animalobj.move(); dogobj.move(); //dogobj.bark(); //會報錯!!!拋出一個編譯錯誤,由於dogobj的引用類型Animal沒有bark方法。 } }
是在一個類裏面,方法名字相同,而參數不一樣。返回類型能夠相同也能夠不一樣。
每一個重載的方法(或者構造函數)都必須有一個獨一無二的參數類型列表。
只能重載構造函數
重載規則:
public class Overloading { public int test(){ System.out.println("This is one."); return 1; } public void test(int a){ System.out.println("This is two."); } public String test(int a,String s) { System.out.println("This is three."); return "3"; } public static void main(String args[]) { Overloading olobj = new Overloading(); System.out.println(olobj.test()); //This is one.、1 olobj.test(1); //This is two. System.out.println(olobj.test(1, "test3")); //This is three.、3 } }
當使用多態方式調用方法時,首先檢查父類中是否有該方法,若是沒有,則編譯錯誤;若是有,再去調用子類的同名方法。
多態的好處:可使程序有良好的擴展,並能夠對全部類的對象進行通用處理
public class Polymorphism { public static void main(String[] args) { show(new Cat()); // 以 Cat 對象調用 show 方法 show(new Dogo()); // 以 Dogo 對象調用 show 方法 Animalo a = new Cat(); // 向上找方法 a.eat(); // 調用的是 Cat 的 eat Cat c = (Cat)a; // 向下找方法 c.work(); // 調用的是 Cat 的 catchMouse } public static void show(Animalo a) { a.eat(); // 類型判斷 if (a instanceof Cat) { // 貓作的事情 Cat c = (Cat)a; c.work(); } else if (a instanceof Dogo) { // 狗作的事情 Dogo c = (Dogo)a; c.work(); } } } abstract class Animalo { abstract void eat(); } class Cat extends Animalo { public void eat() { System.out.println("吃魚"); } public void work() { System.out.println("抓老鼠"); } } class Dogo extends Animalo { public void eat() { System.out.println("吃骨頭"); } public void work() { System.out.println("看家"); } }
若是你想設計這樣一個類,該類包含一個特別的成員方法,該方法的具體實現由它的子類肯定,那麼你能夠在父類中聲明該方法爲抽象方法。
Abstract關鍵字一樣能夠用來聲明抽象方法,抽象方法只包含一個方法名,而沒有方法體。
抽象方法沒有定義,方法名後面直接跟一個分號,而不是花括號。
聲明抽象方法會形成如下兩個結果:
繼承抽象方法的子類必須重寫該方法。不然,該子類也必須聲明爲抽象類。最終,必須有子類實現該抽象方法,不然,從最初的父類到最終的子類都不能用來實例化對象。
2. 抽象類中不必定包含抽象方法,可是有抽象方法的類一定是抽象類。
3. 抽象類中的抽象方法只是聲明,不包含方法體,就是不給出方法的具體實現也就是方法的具體功能。
4. 構造方法,類方法(用static修飾的方法)不能聲明爲抽象方法。
5. 抽象類的子類必須給出抽象類中的抽象方法的具體實現,除非該子類也是抽象類。
abstract class Employeem { private String name; private String address; private int number; public abstract double macPany(); } class Salary extends Employeem{ private double salary=1; public double macPany(){ System.out.println("Welcome to macPany."); return salary; } } public class Employee { public static void main(String[] args){ Salary macPanyobj = new Salary(); macPanyobj.macPany(); } }
在面向對象程式設計方法中,封裝(Encapsulation)是指,一種將抽象性函式接口的實做細節部份包裝、隱藏起來的方法。
封裝能夠被認爲是一個保護屏障,防止該類的代碼和數據被外部類定義的代碼隨機訪問。
要訪問該類的代碼和數據,必須經過嚴格的接口控制。
封裝最主要的功能在於咱們能修改本身的實現代碼,而不用修改那些調用咱們代碼的程序片斷。
適當的封裝可讓程式碼更容易理解與維護,也增強了程式碼的安全性。
1. 良好的封裝可以減小耦合。
2. 類內部的結構能夠自由修改。
3. 能夠對成員變量進行更精確的控制。
4. 隱藏信息,實現細節,通常限制爲private。
public class EncapBase { public static void main(String[] args){ EncapTmp encaptmpobj = new EncapTmp(); System.out.println(encaptmpobj.getName()); //null encaptmpobj.setName("nick"); System.out.println(encaptmpobj.getName()); //nick } } class EncapTmp{ private String name; private int age; public String getName(){ return name; } public int getAge(){ return this.age; } public void setName(String namenew){ name = namenew; } public void setAge(int age){ this.age = age; } }
接口(Interface),在JAVA編程語言中是一個抽象類型,是抽象方法的集合,接口一般以interface來聲明。一個類經過繼承接口的方式,從而來繼承接口的抽象方法。
接口並非類,編寫接口的方式和類很類似,可是它們屬於不一樣的概念。類描述對象的屬性和方法。接口則包含類要實現的方法。
除非實現接口的類是抽象類,不然該類要定義接口中的全部方法。
接口沒法被實例化,可是能夠被實現。一個實現接口的類,必須實現接口內所描述的全部方法,不然就必須聲明爲抽象類。另外,在 Java 中,接口類型可用來聲明一個變量,他們能夠成爲一個空指針,或是被綁定在一個以此接口實現的對象。
[可見度] interface 接口名稱 [extends 其餘的類名] { // 聲明變量 // 抽象方法 }
當類實現接口的時候,類要實現接口中全部的方法。不然,類必須聲明爲抽象的類。
類使用implements關鍵字實現接口。在類聲明中,Implements關鍵字放在class聲明後面。
實現一個接口的語法,可使用這個公式:
...class...implements 接口名稱[, 其餘接口, 其餘接口..., ...] ...
// Animal.java interface Animal { public void eat(); public void travel(); } // Dog.java public interface Dog extends Animal { public void FallInLove(); public void HomePolice(); } // Pig.java public interface Pig { public void BigEat(); public void Sleep(); } // Sheep.java public interface Sheep extends Animal, Pig { }
// Animal.java interface Animal { public void eat(); public void travel(); } // MammalInt.java public class MammalInt implements Animal { public void eat(){ System.out.println("Animal eat.."); } public void travel(){ System.out.println("Animal travel.."); } public static void main(String args[]){ MammalInt mobj = new MammalInt(); mobj.eat(); //Animal eat.. mobj.travel(); //Animal travel.. } }
爲了更好地組織類,Java 提供了包機制,用於區別類名的命名空間。
一、把功能類似或相關的類或接口組織在同一個包中,方便類的查找和使用。
二、如同文件夾同樣,包也採用了樹形目錄的存儲方式。同一個包中的類名字是不一樣的,不一樣的包中的類的名字是能夠相同的,當同時調用兩個不一樣包中相同類名的類時,應該加上包名加以區別。所以,包能夠避免名字衝突。
三、包也限定了訪問權限,擁有包訪問權限的類才能訪問某個包中的類。
Java 使用包(package)這種機制是爲了防止命名衝突,訪問控制,提供搜索和定位類(class)、接口、枚舉(enumerations)和註釋(annotation)等。
package pkg1[.pkg2[.pkg3…]]; 例如,一個Something.java 文件它的內容: package net.java.util public class Something{ ... } # 它的路徑應該是 net/java/util/Something.java 這樣保存的
包聲明應該在源文件的第一行,每一個源文件只能有一個包聲明,這個文件中的每一個類型都應用於它。
若是一個源文件中沒有使用包聲明,那麼其中的類,函數,枚舉,註釋等將被放在一個無名的包(unnamed package)中。
payroll 包名 Employee 類名 payroll.Employee # 全名導入 import payroll.*; import payroll.Employee;