1. 程式人生 > >java學習筆記:面向物件

java學習筆記:面向物件

成員變數與區域性變數的區別:

/*
	成員變數和區域性變數的區別:
		1:在類中的位置不同
			成員變數:在類中方法外
			區域性變數:在方法定義中,或者方法宣告上
		2:在記憶體中的位置不同
			成員變數:在堆記憶體
			區域性變數:在棧記憶體
		3:生命週期不同
			成員變數:隨著物件的建立而存在,隨著物件的消失而消失
			區域性變數:隨著方法的呼叫而存在,隨著方法的呼叫完畢而消失
		4:初始化值不同
			成員變數:有預設的初始化值
			區域性變數:沒有預設的初始化值,必須定義,賦值,然後才能使用
    注意事項:
        區域性變數名稱可以和成員變數名稱一樣,在方法中使用的時候,採用的是就近原則。
*/
class Variable{
	// 成員變數
	int num = 10;
	
	public void show(){
		// 區域性變數
		int num2 = 20;
		
		System.out.println(num2);
	}
}

class VariableDemo{
	public static void main(String[] args){
		// 建立物件
		Variable v = new Variable();
		
		// 訪問成員變數
		System.out.println(v.num);
		
		// 呼叫另一個類中的方法
		// 注意,一個類中的方法,是不能訪問另一個類中的方法的。
		v.show();
	}
}

形式引數的問題:

/*
	形式引數的問題:
		基本型別:形式引數的改變不影響實際引數
		引用型別:形式引數的改變直接影響實際引數
*/

// 形式引數是基本型別
class Demo{
	public int sum(int a, int b){
		return a + b;
	}
}

// 形式引數是引用型別
class Student{
	public void show(){
		System.out.println("我愛學習");
	}
}
class StudentDemo{
	// 如果一個方法的形式引數是一個類型別(引用型別),這裡其實需要的是該類的物件
	public void method(Student s){// 呼叫的時候,把main方法中的s的地址傳遞到了這裡,Student s = new Student();
		s.show();
	}
}

class ArgsTest{
	public static void main(String[] args){
		// 形式引數是基本型別的呼叫
		// 建立物件
		Demo d = new Demo();
		int result = d.sum(10,20);
		System.out.println("result:"+result);
		
		// 形式引數是引用型別的呼叫
		// 需求:呼叫StudentDemo類中的method方法
		StudentDemo sd = new StudentDemo();
		// 建立學生物件
		Student s = new Student();
		sd.method(s); // 把s的地址給到了這裡
	}
}

匿名物件的概述和應用:

/*
	匿名物件:就是沒有名字的物件
	
	匿名物件的應用場景:
		A:呼叫方法,僅僅只呼叫一次的時候
			注意:呼叫多次的時候,不適合使用匿名物件
			優點:匿名物件呼叫完畢之後就是垃圾,可以被垃圾回收器回收
		B:匿名物件可以作為實際引數傳遞
*/
class Student{
	public void show(){
		System.out.println("我要堅持學習,不能放棄");
	}
}

class StudentDemo{
	public void method(Student s){
		s.show();
	}
}

class NoNameDemo{
	public static void main(String[] args){
		// 帶名字的呼叫
		Student s = new Student();
		s.show();
		
		// 匿名物件的呼叫方法
		new Student().show();
		new Student().show(); // 這裡其實是重新建立了一個新的物件
		
		// 匿名物件作為實際引數傳遞
		StudentDemo sd = new StudentDemo();
		sd.method(new Student());
	}
}

封裝概述:

  • 概述:是指隱藏物件的屬性和實現細節,僅對外提供公共訪問方式
  • 好處:
    • 隱藏實現細節,提供公共訪問方式
    • 提高了程式碼的複用性
    • 提高安全性
  • 封裝原則:
    • 將不需要對外提供的內容都隱藏起來
    • 把屬性隱藏,提供公共方法對其訪問
/*
	定義一個學生類:
		成員變數:name,age
		成員方法;show()方法
	
	分析:
		當我們通過物件給成員變數賦值,可以賦值一些非法的資料。所以我們需要在賦值之前對資料進行判斷
		因此,我們決定在Student類中提供一個方法來對資料進行校驗。但是仍然可以不呼叫方法賦值,可以
		直接賦值,導致我們的方法沒有作用。所以。我們應該要求必須使用方法賦值,不能直接呼叫成員變數賦值
		
	解決辦法:java提供了一個關鍵字 private
	private:私有的,可以修飾成員變數和成員方法
*/
class Student{
	String name;
	private int age;
	
	public void setAge(int a){
		if(a < 0 || a > 120){
			System.out.println("你給的年齡有問題");
		}else{
			age = a;
		}
	}
	
	public void show(){
		System.out.println("姓名:"+name);
		System.out.println("年齡:"+age);
	}
}

class StudentDemo1{
	public static void main(String[] args){
		// 建立學生物件
		Student s = new Student();
		s.show();
		System.out.println("-----------");
		
		// 給成員變數賦值
		s.name = "喬丹";
		// s.age = 45;  當age變數private後,會報錯
		s.setAge(27);
		// 不合理資料
		s.setAge(-27); // 輸出,你的年齡有問題
		s.show();
		System.out.println("-----------");
		
		
	}
}

 private關鍵字:

  • private關鍵字:
    • 是一個許可權修飾符
    • 可以修飾成員(成員變數和成員方法)
    • 被private修飾的成員只能在本類中使用
    • 與private對應的是public關鍵字。
  • 最常見的應用:
    • 把成員變數用private修飾
    • 提供對應的getXxx()h/setXxx()方法
/*
	封裝和private的應用:
		1:把成員變數用private修飾
		2:提供對應的getxxx方法和setxxx方法
*/
class Student{
	// 定義私有的變數,name和age
	private String name;
	private int age;
	
	// 獲取值
	public String getName(){
		return name;
	}
		
	public int getAge(){
		return age;
	}
	// 賦值
	public void setName(String n){
		name = n;
	}
	
	public void setAge(int a){
		age = a;
	}
}

class StudentTest{
	public static void main(String[] args){
		Student s = new Student();
		s.setName("喬丹");
		s.setAge(25);
		String na = s.getName();
		int ag = s.getAge();
		System.out.println("姓名:"+na);
		System.out.println("年齡:"+ag);
	}
}

 this的概述與應用:

  • 作用:this代表所在類的物件引用
  • 記住:方法被哪個物件呼叫,this就代表那個物件
  • 使用this:
    • 區域性變數隱藏成員變數
    • 其他方法後面和super一起說
/*
	this的使用:
*/
class Student{
	// 定義私有的變數,name和age
	private String name;
	private int age;
	
	// 獲取值
	public String getName(){
		return name; // 這裡其實隱含了this
	}
		
	public int getAge(){
		return age;
	}
	// 賦值
	public void setName(String name){
		// this.name 代表當前類的物件呼叫name
		this.name = name;
	}
	
	public void setAge(int age){
		// this.age 代表當前類的物件呼叫age
		this.age = a;
	}
}

this的記憶體圖:

構造方法:

/*
	構造方法:
		給物件的資料進行初始化
	構造方法格式:
		1.方法名與類名相同
		2.沒有返回值型別,連void都沒有
		3.沒有具體的返回值
	構造方法的注意事項:
		1.如果我們沒有給出構造方法,系統將自動提供一個無參構造方法。
		2.如果我們給出了構造方法,系統將不再提供預設的無參構造方法。
			如果想要使用無參構造方法,就必須自己給出,建議永遠自己給出無參構造方法
*/
class Student{
	private String name;
	private int age;
	// 我們自定義的構造方法。
	public Student(){
		System.out.println("這是構造方法");
	}
	
	// 構造方法的過載
	public Student(String name){
		this.name = name;
	}
	
	public void show(){
		System.out.println(name+"---"+age);
	}
}

class ConstructDemo{
	public static void main(String[] args){
		// 建立物件
		Student s = new Student(); // 此處使用的就是構造方法
		s.show();
		
		// 建立物件2
		Student s2 = new Student("小明");
		s2.show();
	}
}

一個類的完整版

/*
	類的組成:
		成員變數
		成員方法
			根據返回值:
				void型別
				非void型別
			形式引數:
				空參方法
				非空參方法
		構造方法
	需求:寫一個標準程式碼的版本
		學生類:
			成員變數:name,age
			構造方法:無參,帶兩個參
			成員方法:getxxx()/setxxx(),show()
	給成員變數賦值:
		A:setxxx()
		B:構造方法
	輸出成員變數的方法:
		A:通過setxxx()分別獲取然後拼接
		B:通過呼叫show()方法
*/
class Student{
	// 姓名
	private String name;
	// 年齡
	private int age;
	
	// 構造方法
	public Student(){
		
	}
	
	public Student(String name, int age){
		this.name = name;
		this.age = age;
	}
	
	public String getName(){
		return name;
	}
	
	public void setName(String name){
		this.name = name;
	}
	
	public int getAge(){
		return age;
	}
	
	public void setAge(int age){
		this.age = age;
	}
	
	// 輸出所有的成員變數值
	public void show(){
		System.out.println(name+"----"+age);
	}
}

// 測試類
class StudentTest1{
	public static void main(String[] args){
		// 方式1:給成員變數賦值
		// 無參構造+setxxx()
		Student s1 = new Student();
		s1.setName("小明");
		s1.setAge(27);
		// 輸出值
		System.out.println(s1.getName()+"----"+s1.getAge());
		s1.show();
		
		// 方式2:給成員變數賦值
		// 構造方法
		Student s2 = new Student("小李",30);
		// 輸出值
		System.out.println(s2.getName()+"----"+s2.getAge());
		s2.show();
	}
}

static關鍵字:

針對多個物件有共同的成員變數的時候,Java提供了一個關鍵字static來修飾

/*
	static關鍵字:
		可以修飾成員變數和成員方法
	特點:
		1.隨著類的載入而載入
			main方法
		2.優先於物件存在
		3.被類的所有物件共享
		4.可以通過類名呼叫
	注意事項
		1.在靜態方法中,沒有this關鍵字。
		2.靜態方法只能訪問靜態的成員變數和成員方法。
			靜態方法:
				成員變數:只能訪問靜態變數
				成員方法:只能訪問靜態成員方法
			非靜態方法:
				成員變數:可以是靜態的,也可以是非靜態的。
				成員方法:可以是靜態的成員方法,也可以是非靜態的成員方法。
*/
class Student{
	// 非靜態變數
	int num = 10;
	
	// 靜態變數
	static int num2 = 20;
	
}

class StudentDmeo1{
	public static void main(String[] args){
		Student s = new Student();
		System.out.println(s.num);
		
		// 用類名呼叫,也可以用物件名呼叫,推薦使用類名呼叫。
		System.out.println(Student.num2);
		
	}
}

靜態變數和成員變數的區別:

  • 所屬不同
    • 靜態變數屬於類,所以也稱為類變數
    • 成員變數屬於物件,所以也稱為例項變數(物件變數)
  • 記憶體中位置不同
    • 靜態變數儲存於方法區的靜態區
    • 成員變數儲存於堆記憶體
  • 記憶體出現時間不同
    • 靜態變數隨著類的載入而載入,隨著類的消失而消失
    • 成員變數隨著物件的建立而存在,隨著物件的消失而消失
  • 呼叫不同
    • 靜態變數可以通過類名呼叫,也可以通過物件呼叫
    • 成員變數只能通過物件名呼叫