1:成員變量和局部變量的差別(了解)
(1)在類中的位置不同
成員變量:類中方法外
局部變量:方法定義中或者方法聲明上
(2)在記憶體中的位置不同
成員變量:在堆中
局部變量:在棧中
(3)生命周期不同(成員的建立與銷毀時間)
成員變量:随着對象的建立而存在,随着對象的消失而消失
局部變量:随着方法的調用而存在,随着方法的調用完畢而消失
(4)初始化值不同
成員變量:有預設值
局部變量:沒有預設值,必須定義,指派,然後才能使用
(5)使用範圍
成員變量:在整個類中都可以通路
局部變量:隻能在目前方法通路
(6)變量的使用原則:就近原則
如果在方法中找到,使用局部變量
如果在類中方法外找到,使用成員變量
如果在類中沒有找到,報錯
/*
成員變量和局部變量的差別?
a:在類中的位置不同
成員變量:在類中方法外
局部變量:在方法定義中或者方法聲明上
b:在記憶體中的位置不同
成員變量:在堆記憶體
局部變量:在棧記憶體
c:生命周期不同
d:初始化值不同
成員變量:有預設初始化值
局部變量:沒有預設初始化值,必須定義,指派,然後才能使用。
注意事項:
局部變量名稱可以和成員變量名稱一樣,在方法中使用的時候,采用的是就近原則。
*/
class varialbe {
//成員變量
//int num = 10;
int num; //0
public void show() {
//int num2 = 20; //局部變量
//可能尚未初始化變量num2
//int num2; //沒有預設值
int num2 = 20;
system.out.println(num2);
//int num = 100;
system.out.println(num);
}
class variabledemo {
public static void main(string[] args) {
varialbe v = new varialbe();
system.out.println(v.num); //通路成員變量
v.show();
2:類作為形式參數的問題(了解)
(1)如果你看到一個方法需要的參數是一個類名,就應該知道這裡實際需要的是一個具體的對象。
形式參數的問題:
基本類型:形式參數的改變不影響實際參數
引用類型:形式參數的改變直接影響實際參數
//形式參數是基本類型
class demo {
public int sum(int a,int b) {
return a + b;
//形式參數是引用類型
class student {
system.out.println("我愛學習");
class studentdemo {
//如果你看到了一個方法的形式參數是一個類類型(引用類型),這裡其實需要的是該類的對象。
public void method(student s) { //調用的時候,把main方法中的s的位址傳遞到了這裡 student s = new student();
s.show();
class argstest {
//形式參數是基本類型的調用
demo d = new demo();
int result = d.sum(10,20);
system.out.println("result:"+result);
system.out.println("--------------");
//形式參數是引用類型的調用
//需求:我要調用studentdemo類中的method()方法
studentdemo sd = new studentdemo();
//建立學生對象
student s = new student();
sd.method(s); //把s的位址給到了這裡
3:匿名對象(了解)
(1)沒有名字的對象
(2)應用場景
a:調用方法,僅僅隻調用一次的時候。
b:作為調用方法的實際參數使用
匿名對象:就是沒有名字的對象。
匿名對象的應用場景:
注意:調用多次的時候,不适合。
那麼,這種匿名調用有什麼好處嗎?
有,匿名對象調用完畢就是垃圾。可以被垃圾回收器回收。
b:匿名對象可以作為實際參數傳遞
public void method(student s) {
class nonamedemo {
//帶名字的調用
//匿名對象
//new student();
//匿名對象調用方法
new student().show();
new student().show(); //這裡其實是重新建立了一個新的對象
//匿名對象作為實際參數傳遞
//student ss = new student();
//sd.method(ss); //這裡的s是一個實際參數
sd.method(new student());
//在來一個
new studentdemo().method(new student());
}
4:封裝(了解)
(1)隐藏實作細節,提供公共的通路方式
(2)好處:
a:隐藏實作細節,提供公共的通路方式
b:提高代碼的複用性
c:提高代碼的安全性
(3)設計原則
把不想讓外界知道的實作細節給隐藏起來,提供公共的通路方式
(4)private是封裝的一種展現。
封裝:類,方法,private修飾成員變量
定義一個學生類:
成員變量:name,age
成員方法:show()方法
我們在使用這個案例的過程中,發現了一個問題:
通過對象去給成員變量指派,可以指派一些非法的資料。
這是不合理的。
應該是這個樣子的:在指派之前,先對資料進行判斷。
判斷到底在哪裡做比較合适呢?
studentdemo類是一個測試類,測試類一般隻建立對象,調用方法。
是以,這個判斷應該定義在student類中。
而我們在成員變量的位置可不可以進行資料判斷呢?
是不可以的,因為做資料校驗,必須要依靠一些邏輯語句。
邏輯語句是應該定義在方法中的,是以,我們最終決定在student類中提供一個方法
來對資料進行校驗。
按照我們前面的分析,我們給出了一個方法進行校驗。
但是呢,它偏偏不調用方法來指派,還是直接指派了,
這樣我們的方法就沒有起到作用。
我就應該要求你必須使用我的方法,而不能直接調用成員變量指派。
怎麼去強制要求不能直接使用成員變量呢?
針對這種情況,java就提供了一個關鍵字 private
private:私有的。可以修飾成員變量和成員方法。
注意:被private修飾的成員隻能在本類中通路。
其實我講到現在講解的是一個封裝的思想。
封裝:是指隐藏對象的屬性和實作細節,僅對外提供公共通路方式。
//姓名
string name;
//年齡
private int age;
//寫一個方法對資料進行校驗
傳回值類型:void
參數清單:int a
public void setage(int a) {
if(a < 0 || age > 120) {
system.out.println("你給的年齡有問題");
}else {
age = a;
//show()方法,顯示所有成員變量值
system.out.println("姓名:"+name);
system.out.println("年齡:"+age);
//給成員變量指派
s.name = "林青霞";
//s.age = 27;
s.setage(27);
//給age指派
//s.age = -27; //這個資料是不合理的
//通過方法給值
s.setage(-27);
5:private關鍵字(掌握)
(1)私有的意義,可以修飾成員變量和成員方法
(2)特點:
被private修飾的後的成員隻能在本類中被通路
(3)private的應用:
以後再寫一個類的時候:
把所有的成員變量給private了
提供對應的getxxx()/setxxx()方法
private:
是一個權限修飾符
可以修飾成員變量和成員方法
被其修飾的成員隻能在本類中被通路
//用private修飾
private int num = 10;
private void method() {
system.out.println("method");
public void function() {
method();
class privatedemo {
//不能方法私有的成員變量
//system.out.println(d.num);
d.show();
//不能通路私有的成員方法
//d.method();
d.function();
/* 應用:
封裝和private的應用:
a:把成員變量用private修飾
b:提高對應的getxxx()和setxxx()方法
//定義學生類
private string name;
//姓名擷取值
public string getname() {
return name;
//姓名設定值
public void setname(string n) {
name = n;
//年齡擷取值
public int getage() {
return age;
//年齡指派
//測試類
class studenttest {
//使用成員變量
//錯誤:被私有修飾了,外界不能直接通路了
//system.out.println(s.name+"---"+s.age);
system.out.println(s.getname()+"---"+s.getage());
//s.name = "林青霞";
//通過方法給指派
s.setname("林青霞");
6:this關鍵字(掌握)
(1)代表目前類的引用對象
記住:哪個對象調用方法,該方法内部的this就代表那個對象
(2)this的應用場景:
a:解決了局部變量隐藏成員變量的問題
b:其實this還有其他的應用,明天講解。
作業:請把手機類寫成一個标準類,然後建立對象測試功能。
手機類:
成員變量:
品牌:string brand;
價格:int price;
顔色:string color;
成員方法:
針對每一個成員變量給出對應的getxxx()/setxxx()方法。
最後定義測試:
建立一個對象,先通過getxxx()方法輸出成員變量的值。這一次的結果是:null---0---null
然後通過setxxx()方法給成員變量指派。再次輸出結果。這一次的結果是:三星---2999---土豪金
class phone {
//品牌
private string brand;
//價格
private int price;
//顔色
private string color;
//getxxx()和setxxx()方法
public string getbrand() {
return brand;
public void setbrand(string brand) {
this.brand = brand;
public int getprice() {
return price;
public void setprice(int price) {
this.price = price;
public string getcolor() {
return color;
public void setcolor(string color) {
this.color = color;
class phonetest {
//建立手機對象
phone p = new phone();
//直接輸出預設值
system.out.println(p.getbrand()+"---"+p.getprice()+"---"+p.getcolor());
p.setbrand("三星");
p.setprice(2999);
p.setcolor("土豪金");
//再次輸出
我們曾經曰:起名字要做到見名知意。
this:是目前類的對象引用。簡單的記,它就代表目前類的一個對象。
注意:誰調用這個方法,在該方法内部的this就代表誰。
this的場景:
解決局部變量隐藏成員變量
public void setname(string name) { //name = "林青霞";
//name = name; //變量的使用規則:就近原則
//這裡是類名,目前還沒有說過類似的用法,是以這個是有問題的
//這裡的調用隻能通過對象名
//這個對象如果存在,它應該代表的是student的一個對象。
//那麼,誰能夠代表目前類的對象呢? java就提供了一個關鍵字 this
//student.name = name;
this.name = name;
public void setage(int age) {
this.age = age;
//擷取資料
标準的代碼改進版
this:哪個對象調用那個方法,this就代表那個對象
return name; //這裡其實是隐含了this
public void setname(string name) {
class studenttest2 {
//建立一個對象
student s1 = new student();
s1.setname("林青霞");
s1.setage(27);
system.out.println(s1.getname()+"---"+s1.getage());
//建立第二個對象
student s2 = new student();
s2.setname("劉意");
s2.setage(30);
system.out.println(s2.getname()+"---"+s2.getage());
7:構造方法(掌握)
(1)作用:用于對對象的資料進行初始化
(2)格式:
a:方法名和類名相同
b:沒有傳回值類型,連void都不能有
c:沒有傳回值
思考題:構造方法中可不可以有return語句呢?
可以。而是我們寫成這個樣子就ok了:return;
其實,在任何的void類型的方法的最後你都可以寫上:return;
(3)構造方法的注意事項
a:如果我們沒寫構造方法,系統将提供一個預設的無參構造方法
b:如果我們給出了構造方法,系統将不再提供預設構造方法
如果這個時候,我們要使用無參構造方法,就必須自己給出。
推薦:永遠手動自己給出無參構造方法。
(4)給成員變量指派的方式
a:setxxx()
b:帶參構造方法
(5)标準案例
public student(){}
public student(string name,int age) {
測試:
//方式1
//方式2
student s2 = new student("劉意",30);
我們一直在使用構造方法,但是,我們确沒有定義構造方法,用的是哪裡來的呢?
構造方法的注意事項:
a:如果我們沒有給出構造方法,系統将自動提供一個無參構造方法。
b:如果我們給出了構造方法,系統将不再提供預設的無參構造方法。
注意:這個時候,如果我們還想使用無參構造方法,就必須自己給出。建議永遠自己給出無參構造方法
給成員變量指派有兩種方式:
b:構造方法
public student() {
//system.out.println("我給了,你還給不");
system.out.println("這是無參構造方法");
//構造方法的重載格式
public student(string name) {
system.out.println("這是帶一個string類型的構造方法");
public student(int age) {
system.out.println("這是帶一個int類型的構造方法");
system.out.println("這是一個帶多個參數的構造方法");
system.out.println(name+"---"+age);
class constructdemo2 {
//建立對象
system.out.println("-------------");
//建立對象2
student s2 = new student("林青霞");
s2.show();
//建立對象3
student s3 = new student(27);
s3.show();
//建立對象4
student s4 = new student("林青霞",27);
s4.show();
類的組成:成員變量,成員方法
今天我們又加入了一個新的成員:構造方法。
以後再提類的組成:
成員變量
構造方法
成員方法
根據傳回值:
void類型
非void類型
形式參數:
空參方法
非空參方法
public string getstring() {
return "helloworld";
system.out.println("show");
public void method(string name) {
system.out.println(name);
public string function(string s1,string s2) {
return s1+s2;
//調用無參無傳回值方法
//調用無參有傳回值方法
string result = s.getstring();
system.out.println(result);
//調用帶參無傳回值的方法
s.method("林青霞");
//調用帶參帶傳回值的方法
string result2 = s.function("hello","world");
system.out.println(result2);
一個标準代碼的最終版。
學生類:
name,age
構造方法:
無參,帶兩個參
getxxx()/setxxx()
show():輸出該類的所有成員變量值
給成員變量指派:
a:setxxx()方法
輸出成員變量值的方式:
a:通過getxxx()分别擷取然後拼接
b:通過調用show()方法搞定
//構造方法
//輸出所有的成員變量值
//方式1給成員變量指派
//無參構造+setxxx()
//輸出值
s1.show();
system.out.println("----------------------------");
//方式2給成員變量指派
8:代碼:student s = new student();做了哪些事情?(了解)
(1)把student.class檔案加載到記憶體
(2)在棧記憶體為s開辟空間
(3)在堆記憶體為學生對象申請空間
(4)給學生的成員變量進行預設初始化。null,0
(5)給學生的成員變量進行顯示初始化。林青霞,27
(6)通過構造方法給成員變量進行初始化。劉意,30
(7)對象構造完畢,把位址指派給s變量
9:面向對象的練習題(掌握)
(1)标準的手機類的定義和測試
(2)demo類有求和方法,test類進行測試。
什麼時候定義成員變量?
當該變量是用來描述一個類的時候。
(3)長方形案例
(4)員工案例
(5)mymath案例(自己提供加減乘除并測試)
/* 練習題(1)
标準的手機類練習
成員變量:brand,price,color
構造方法:無參構造
成員方法:getxxx()/setxxx()
//定義手機類
//無參構造方法
public phone() {}
}
//手機測試類
p.setbrand("諾基亞");
p.setprice(199);
//擷取值
/* 練習題(2)
定義一個類demo,其中定義一個求兩個資料和的方法,
定義一個測試了test,進行測試。
變量什麼時候定義為成員變量:
如果這個變量是用來描述這個類的資訊的,那麼,該變量就應該定義為成員變量。
變量到底定義在哪裡好呢?
變量的範圍是越小越好。因為能及時的被回收。
public int sum() {
int a = 10;
int b = 20;
int c = a + b;
return c;
//方式1滿足了我們的要求,但是不好。
//因為參與操作的資料現在是固定的。
//方式2可以滿足我們的要求,但是呢我們學習過來面向對象的思想。
//我就再想,a,b可不可以定義為成員變量呢?
//如果可以,我們再改進一版
int a;
int b;
//雖然這種方式可以,并且好像是符合了面向對象的思想。
//但是不好。
//因為我們曾經說過:類是一組相關的屬性和行為的集合。
//并且類是通過事物轉換過來的
//而類中的成員變量就是事物的屬性
//屬性是用來描述事物的
//同理:成員變量其實是用來描述類的。
class test {
//方式1測試
system.out.println(d.sum());
//方式2測試
system.out.println(d.sum(a,b));
//方式3測試
d.a = 10;
d.b = 20;
/* 練習題(3)
定義一個長方形類,定義 求周長和面積的方法,
然後定義一個測試了test2,進行測試。
長方形的類:
長,寬
求周長:(長+寬)*2;
求面積:長*寬
注意:
import必須出現在所有的class前面。
import java.util.scanner;
class changfangxing {
//長方形的長
private int length;
//長方形的寬
private int width;
public changfangxing(){}
//僅僅提供setxxx()即可
public void setlength(int length) {
this.length = length;
public void setwidth(int width) {
this.width = width;
//求周長
public int getzhouchang() {
return (length + width) * 2;
//求面積
public int getarea() {
return length * width;
class test2 {
//建立鍵盤錄入對象
scanner sc = new scanner(system.in);
system.out.println("請輸入長方形的長:");
int length = sc.nextint();
system.out.println("請輸入長方形的寬:");
int width = sc.nextint();
changfangxing cfx = new changfangxing();
//先給成員變量指派
cfx.setlength(length);
cfx.setwidth(width);
system.out.println("周長是:"+cfx.getzhouchang());
system.out.println("面積是:"+cfx.getarea());
/* 練習題(4)
需求:
定義一個員工類,自己分析出幾個成員,
然後給出成員變量,構造方法,getxxx()/setxxx()方法,
以及一個顯示所有成員資訊的方法。并測試。
分析:
員工
員工編号,姓名,年齡
無參構造方法
show();
class employee {
//員工編号
private string employeeid;
public employee() {}
//getxxx()/setxxx()
public string getemployeeid() {
return employeeid;
public void setemployeeid(string employeeid) {
this.employeeid = employeeid;
//顯示所有成員資訊的方法
system.out.println("員工編号是:"+employeeid+"的這個人是:"+name+"的年齡是:"+age);
class employeetest {
employee e = new employee();
e.setemployeeid("czbk9527");
e.setname("唐伯虎");
e.setage(18);
//system.out.println(e.getemployeeid()+"---"+e.getname()+"---"+e.getage());
//我們在employee類中定義了一個show方法。是以,我們改進一下,使用show方法
e.show();
/* 練習題(5)
定義一個類mymath,提供基本的加減乘除功能,然後進行測試。
class mymath {
//加法功能
public int add(int a,int b) {
//減法功能
public int sub(int a,int b) {
return a - b;
//乘法功能
public int mul(int a,int b){
return a * b;
//除法功能
public int div(int a,int b) {
return a / b;
class mymathtest {
system.out.println("請輸入第一個操作數:");
int firstnumber = sc.nextint();
system.out.println("請輸入第二個操作數:");
int secondnumber = sc.nextint();
//建立mymath對象,并使用
mymath mm = new mymath();
system.out.println("加法結果:"+mm.add(firstnumber,secondnumber));
system.out.println("減法結果:"+mm.sub(firstnumber,secondnumber));
system.out.println("乘法結果:"+mm.mul(firstnumber,secondnumber));
system.out.println("除法結果:"+mm.div(firstnumber,secondnumber));
10:static關鍵字(了解)
(1)靜态的意思。可以修飾成員變量和成員方法。
(2)靜态的特點:
a:随着類的加載而加載
b:優先與對象存在
c:被類的所有對象共享
這其實也是我們判斷該不該使用靜态的依據。
舉例:飲水機和水杯的問題思考
d:可以通過類名調用
既可以通過對象名調用,也可以通過類名調用,建議通過類名調用。
(3)靜态的記憶體圖
靜态的内容在方法區的靜态區
(4)靜态的注意事項;
a:在靜态方法中沒有this對象
b:靜态隻能通路靜态(代碼測試過)
(5)靜态變量和成員變量的差別
a:所屬不同
靜态變量:屬于類,類變量
成員變量:屬于對象,對象變量,執行個體變量
b:記憶體位置不同
靜态變量:方法區的靜态區
成員變量:堆記憶體
靜态變量:靜态變量是随着類的加載而加載,随着類的消失而消失
成員變量:成員變量是随着對象的建立而存在,随着對象的消失而消失
d:調用不同
靜态變量:可以通過對象名調用,也可以通過類名調用
成員變量:隻能通過對象名調用
(6)main方法是靜态的
public:權限最大
static:不用建立對象調用
void:傳回值給jvm沒有意義
main:就是一個常見的名稱。
string[] args:可以接收資料,提供程式的靈活性
格式:java maindemo hello world java
java maindemo 10 20 30
static的特點:(它可以修飾成員變量,還可以修飾成員方法)
回想main方法。
b:優先于對象存在
舉例:咱們班級的學生應該共用同一個班級編号。
其實這個特點也是在告訴我們什麼時候使用靜态?
如果某個成員變量是被所有對象共享的,那麼它就應該定義為靜态的。
舉例:
飲水機(用靜态修飾)
水杯(不能用靜态修飾)
其實它本身也可以通過對象名調用。
推薦使用類名調用。
靜态修飾的内容一般我們稱其為:與類相關的,類成員
//非靜态變量
int num = 10;
//靜态變量
static int num2 = 20;
system.out.println(s.num);
system.out.println(student.num2);
system.out.println(s.num2);
static關鍵字注意事項
a:在靜态方法中是沒有this關鍵字的
如何了解呢?
靜态是随着類的加載而加載,this是随着對象的建立而存在。
靜态比對象先存在。
b:靜态方法隻能通路靜态的成員變量和靜态的成員方法
靜态方法:
成員變量:隻能通路靜态變量
成員方法:隻能通路靜态成員方法
非靜态方法:
成員變量:可以是靜态的,也可以是非靜态的
成員方法:可是是靜态的成員方法,也可以是非靜态的成員方法。
簡單記:
靜态隻能通路靜态。
class teacher {
public int num = 10;
public static int num2 = 20;
system.out.println(num); //隐含的告訴你通路的是成員變量
system.out.println(this.num); //明确的告訴你通路的是成員變量
//function();
//function2();
public static void method() {
//無法從靜态上下文中引用非靜态 變量 num
//system.out.println(num);
//無法從靜态上下文中引用非靜态 方法 function()
function2();
public static void function2() {
class teacherdemo {
teacher t = new teacher();
t.show();
system.out.println("------------");
t.method();
main方法的格式講解:
public static void main(string[] args) {...}
public:公共的,通路權限是最大的。由于main方法是被jvm調用,是以權限要夠大。
static:靜态的,不需要建立對象,通過類名就可以。友善jvm的調用。
void:因為我們曾經說過,方法的傳回值是傳回給調用者,而main方法是被jvm調用。你傳回内容給jvm沒有意義。
main:是一個常見的方法入口。我見過的語言都是以main作為入口。
string[] args:這是一個字元串數組。值去哪裡了?
這個東西到底有什麼用啊?怎麼給值啊?
這個東西早期是為了接收鍵盤錄入的資料的。
格式是:
java maindemo hello world java
class maindemo {
//system.out.println(args); //[ljava.lang.string;@175078b
//system.out.println(args.length); //0
//system.out.println(args[0]); //arrayindexoutofboundsexception
//接收資料後
system.out.println(args);
system.out.println(args.length);
//system.out.println(args[0]);
for(int x=0; x<args.length; x++) {
system.out.println(args[x]);
定義一個人類
姓名和年齡都是變化的,這個我能接收,因為每個人的姓名和年齡是不同的。
但是,我們現在選取的幾個人都是中國人,他們的國籍是一樣的。
一樣的國籍,我每次建立對象,在堆記憶體都要開辟這樣的空間,
我就覺得有點浪費了。怎麼辦呢?
針對多個對象有共同的這樣的成員變量值的時候,
java就提高了一個關鍵字來修飾:static。
class person {
int age;
//國籍
//string country;
static string country;
public person(){}
public person(string name,int age) {
public person(string name,int age,string country) {
this.country = country;
system.out.println("姓名:"+name+",年齡:"+age+",國籍:"+country);
class persondemo {
//建立對象1
person p1 = new person("鄧麗君",16,"中國");
p1.show();
//person p2 = new person("楊幂",22,"中國");
//p2.show();
person p2 = new person("楊幂",22);
p2.show();
//person p3 = new person("鳳姐",20,"中國");
//p3.show();
person p3 = new person("鳳姐",20);
p3.show();
p3.country = "美國";
java幫幫微信公衆号
java幫幫今日頭條号