Java方法及構造方法
*************************構造函數(構造方法、構造器)Constructor************
一.why 為什麽用
Student s1 = new Student();
s1.sno = 1;//破壞程序的封裝性
s1.name = "aaa";
s1.age = 20;
//推薦
s1.setSno(1);
s1.setName("aaa");
s1.setAge(20);
假設對象有10個屬性,為了創建這個對象並且為該對象的10個屬性賦值,需要調用10次
setters()方法,顯然是比較麻煩!有沒有一種方式,可以一句話就能創建對象 同時為
該對象的所有屬性賦值?
有的.使用構造函數
二.what
構造函數 是一個特殊的函數...
作用: 是用來給對象的屬性進行初始化的...
構造函數也叫做構造方法、構造器... 英文叫做Constructor...
三.how
public class Student{
public Student(){
}
}
特點:
1. 與類同名
2. 沒有返回值(連void也不要寫)
演示代碼:
package com.chapter6.演示構造函數;
public class Student {
private int sno;
private String name;
private int age;
public Student(int sno,String name){
System.out.println("使用兩個參數的構造函數創建對象int sno,String name");
this.sno = sno;
this.name = name;
}
//構造函數
//特點:
//1.與類同名
//2.沒有返回值(連void也不需要寫)
public Student(int sno,String name,int age){
System.out.println("使用三個參數的構造函數來創建對象 int sno,String name,int age");
this.sno = sno;
this.name = name;
this.age = age;
}
public void study(){
System.out.println("我在學習");
}
public static void main(String[] args) {
//Student s1 = new Student(1,"aaa",20);
Student s1 = new Student(1,"bbb");
}
}
*************************構造函數不寫返回值的實質**********************
其實構造函數是有返回值的,返回值是剛剛創建出來的對象的引用...
public Student Student(int sno,String name){
System.out.println("使用兩個參數的構造函數創建對象int sno,String name");
this.sno = sno;
this.name = name;
return new Student(1,"aaa",20);
}
或者
public void Student(int sno,String name){
System.out.println("使用兩個參數的構造函數創建對象int sno,String name");
this.sno = sno;
this.name = name;
}
以上兩種都不是構造函數,它是一個普通的方法,只不過碰巧和構造函數同名罷了...
構造函數不寫返回值,是java設計人員的一個規定, 編譯器也是根據這個規定來找到哪個方法是構造函數的.....
而不是說構造函數真的沒有返回值
*************************默認的構造函數**********************
Student s1 = new Student(1,"aaa",20);//底層調用了構造函數 來創建對象
Student s1 = new Student();//之前我們沒有學構造函數的時候 也可以創建對象
為什麽呢? 原因是雖然我們沒有寫構造函數,編譯器會自動幫我們提供一個不帶參數的
構造函數,這個不帶參數的構造函數,叫做默認的構造函數,也叫做缺省的構造函數
一.what 什麽是默認的構造函數
不帶參數的構造函數, 也叫做缺省的構造函數、無參的構造函數...
public class Student{
//默認的構造函數
public Student(){
//super();
}
}
註意: 一旦程序員寫上一個帶參數的構造函數,編譯器就不會幫你提供那個默認的構造函數了
程序員要養成習慣,一旦寫了帶參數的構造函數,自己要主動把不帶參數的默認的構造函數也加上.
*************************對象的初始化塊************************************
一.why
問題:既然初始化塊和構造函數功能是完全一樣的,這樣既然有了構造函數,為什麽還需要初始化塊??
初始化塊是多余的嗎???
不是!
當多個構造函數中,如果出現相同的代碼,可以把這些相同的代碼提取出來,抽取到對象初始化塊中...
由於對象初始化塊 是優先於構造函數執行的,這樣就解決了代碼冗余問題....
二.what
作用: 和構造函數一樣, 是用來給對象的屬性進行初始化...
public class Student{
//1.屬性
//4.對象初始化塊
{
}
//3.構造函數
//2.方法
}
演示代碼:
package com.chapter6.對象的初始化塊;
public class Student {
private int sno;
private String name;
private int age;
private int grade;//年級
//對象初始化塊
{
System.out.println("對象初始化塊執行");
this.grade = 1;
}
public Student(){
System.out.println("默認的構造函數執行");
}
public Student(int sno,String name){
System.out.println("兩個參數的構造函數執行int sno,String name");
this.sno = sno;
this.name = name;
}
public Student(int sno,String name,int age){
System.out.println("三個參數的構造函數執行int sno,String name,int age");
this.age = age;
this.sno = sno;
this.name = name;
}
public static void main(String[] args) {
Student s1 = new Student(1,"aaa",20);
}
}
*******************************對象初始化過程(或 使用new創建對象 底層到底做了什麽)******************
Student s1 = new Student(1,"aaa",20);//對象初始化
一.給對象的實例變量分配空間、默認初始化
二.聲明時初始化、對象初始化塊初始化(按照寫代碼的順序 從上到下執行)
三.構造函數初始化
執行完以上三步以後,對象被創建完畢,返回剛剛創建的對象的地址
實例變量是隸屬於對象的,每個對象有自己的一份實例變量
*******************************this指針********************************
this 指向的是自己 翻譯成中文 "我"
一.構造函數中
指向的是 正在初始化的對象
二.用在方法中
指向的是 正在調用該方法的對象
s1.study();//在study()中的this 指向的是s1
三.使用this可以來調用其他的構造函數
public Student(int sno,String name,int age){
this(sno,name);//調用其他的構造函數 int String 這句話必須要寫到當前構造函數的第一句 否則編譯報錯
System.out.println("使用三個參數的構造函數int sno,String name,int age");
this.age = age;
}
*******************************重載(Overload)********************************
一.what 什麽是重載
方法的名稱相同,參數列表不同的方法之間叫做重載....
參數列表不同體現在三個方面:
1. 個數不同
2. 類型不同
3. 順序不同
編譯器決定到底調用哪個方法,首先是通過方法名判斷,如果introduce有多個重載的方法,編譯器通過參數的類型、個數、順序
來判斷到底調用哪一個,如果碰到兩個相同類型的方法(例如參數都是int類型,編譯器就糊塗了,有句話叫 不要讓計算機糊塗 讓計算機糊塗就是你錯了)
面試題: 方法的名稱相同,參數列表也完全相同,只有返回值不同的方法之間 叫不叫重載???
不叫重載. 編譯報錯 . 重復的方法 Duplicate Method 編譯器認為它是一個重復的方法..所以不叫重載...
重載: 也叫做靜態聯編、靜態綁定、前期綁定..
聯編(binding綁定): 給定一個方法名, 通過該方法名 決定 到底執行 哪一塊代碼的過程,叫做聯編...
靜態聯編: 在 編譯的 時候 決定到底執行哪一塊代碼...
演示代碼:
package com.chapter6.演示重載;
/**
* 作者: zhangzy 公司: 藍橋軟件學院 時間: 2017年7月3日 上午11:15:30 功能: 演示重載
* 方法的名稱相同,參數列表不同的方法之間叫做重載.... 參數列表不同體現在三個方面:1. 個數不同 2. 類型不同 3. 順序不同.
*/
public class Student {
private int sno;
private String name;
private int age;
/*public int introduce(int sno) {
System.out.println("我是學生,我的學號是:" + sno);
return 1;
}
public long introduce(int age){
System.out.println("我是學生,我的年齡是:" + age);
return 1;
}*/
public void introduce(String name) {
System.out.println("我是學生,我的名字是:" + name);
}
public void introduce(int sno, String name) {
System.out.println("我是學生,我的學號是:" + sno + ",姓名是:" + name);
}
public void introduce(String name, int sno) {
System.out.println("我是學生,我的姓名是:" + name + ",學號是:" + sno);
}
public static void main(String[] args) {
Student s1 = new Student();
s1.introduce(1);
}
}
********************************構造函數也是可以重載的*****************************
**************************static 靜態的************************************
一.修飾方法
1. 靜態方法
類名.方法名();
二.修飾成員變量
1. 靜態變量(類變量)
如何訪問靜態變量 :
類名.屬性名
隸屬於類的,類的所有對象 共享一份 靜態變量....
需求: 統計使用Student類總共創建了多少個對象
演示代碼:
package com.chapter6.演示static;
/**
* 作者: zhangzy
* 公司: 藍橋軟件學院
* 時間: 2017年7月3日 下午2:11:12
* 功能: 演示static
* 需求: 統計使用Student類創建了多少個對象
*/
public class Student {
private int sno;
private String name;
private int age;
private static int sum;
//靜態初始化塊
//作用: 給類的靜態屬性初始化的
static{
System.out.println("靜態初始化塊執行");
sum = 10;
}
public Student(){
sum++;
}
public Student(int sno,String name,int age){
sum++;
this.sno = sno;
this.name = name;
this.age = age;
}
public static void study(){
System.out.println("我在學習");
}
public static void main(String[] args) {
Student s1 = new Student(1,"aaa",20);//1.類初始化 2.對象初始化
Student s2 = new Student(2,"bbb",25);//只執行對象初始化
s1.sum = 50;
System.out.println(s1.sum);//50
System.out.println(s2.sum);//50
System.out.println(Student.sum);//推薦
//System.out.println("一共創建了" + Student.sum + "個對象");
}
}
*****************************類的初始化過程****************************
對象初始化時機: new 對象的時候
類的初始化時機: 第一次使用類的時候
1.使用該類來創建對象的時候
Student s1 = new Student();
2.調用類的靜態方法
Student.study();
3.訪問類的靜態屬性
Student.sum
類初始化過程
1. 類加載
把類的二進制文件(.class)讀到方法區
2.給類靜態變量分配空間、默認初始化
3.聲明時初始化、靜態初始化塊初始化(從上到下的順序)
靜態初始化塊
作用: 給類的屬性(靜態變量)賦值
static {
}
**************************實例變量和靜態變量的區別*****************************
一.實例變量
隸屬於對象的,每個對象都有自己的一份實例變量,實例變量是分配在堆裏的
二.靜態變量
隸屬於類的,類的所有對象 共享一份 靜態變量,靜態變量是在靜態區的...
三.局部變量
在棧裏
***************************************************************
類初始化 優先於 對象初始化
Java方法及構造方法