1. 程式人生 > 實用技巧 >85,java基礎2

85,java基礎2

15.方法過載

---------------------------------------------方法過載---------------------------------------
package com.atguigu.exer;
/*
 * 方法的過載(overload)  loading...
 * 
 * 1.定義:在同一個類中,允許存在一個以上的同名方法,只要它們的引數個數或者引數型別不同即可。
 * 	
 *  "兩同一不同":同一個類、相同方法名
 *            引數列表不同:引數個數不同,引數型別不同
 * 
 * 2. 舉例:
 *    Arrays類中過載的sort() / binarySearch()
 * 
 * 3.判斷是否是過載:
 *    跟方法的許可權修飾符、返回值型別、形參變數名、方法體都沒有關係!
 *    
 * 4. 在通過物件呼叫方法時,如何確定某一個指定的方法:
 *      方法名 ---> 引數列表
 
 * 5.編寫程式,定義三個過載方法並呼叫。方法名為mOL。
	三個方法分別接收一個int引數、兩個int引數、一個字串引數。
	分別執行平方運算並輸出結果,相乘並輸出結果,輸出字串資訊。
	在主類的main ()方法中分別用引數區別呼叫三個方法。
	
	2.定義三個過載方法max(),
	第一個方法求兩個int值中的最大值,
	第二個方法求兩個double值中的最大值,
	第三個方法求三個double值中的最大值,
	並分別呼叫三個方法。
 * 
 * 
 */
public class OverloadExer {
	
	//1. 如下的三個方法構成過載
	public void mOL(int i){
		System.out.println(i * i);
		
	}
	public void mOL(int i,int j){
		System.out.println(i * j);
	}
	
	public void mOL(String s){
		System.out.println(s);
	}
	
	//2.如下的三個方法構成過載
	public int max(int i,int j){
		return (i > j)? i : j;
	}
	public double max(double d1,double d2){
		return (d1 > d2)? d1 : d2;
	}
	public double max(double d1,double d2,double d3){
		double max = (d1 > d2)? d1 : d2;
		return (max > d3)? max : d3;
	}
    //如下的3個方法不能與上述4個方法構成過載
//	public int getSum(int i,int j){
//		return 0;
//	}	
//	public void getSum(int m,int n){
//		
//	}
//	private void getSum(int i,int j){
//		
//	} 
}

練習:
package com.atguigu.exer;
/*
 * 1.編寫程式,定義三個過載方法並呼叫。方法名為mOL。
	三個方法分別接收一個int引數、兩個int引數、一個字串引數。
	分別執行平方運算並輸出結果,相乘並輸出結果,輸出字串資訊。
	在主類的main ()方法中分別用引數區別呼叫三個方法。
	2.定義三個過載方法max(),
	第一個方法求兩個int值中的最大值,
	第二個方法求兩個double值中的最大值,
	第三個方法求三個double值中的最大值,
	並分別呼叫三個方法。
 * 
 * 
 */
public class OverloadExer {
	//1. 如下的三個方法構成過載
	public void mOL(int i){
		System.out.println(i * i);
	}
	public void mOL(int i,int j){
		System.out.println(i * j);
	}
	public void mOL(String s){
		System.out.println(s);
	}
	//2.如下的三個方法構成過載
	public int max(int i,int j){
		return (i > j)? i : j;
	}
	public double max(double d1,double d2){
		return (d1 > d2)? d1 : d2;
	}
	public double max(double d1,double d2,double d3){
		double max = (d1 > d2)? d1 : d2;
		return (max > d3)? max : d3;
	}
}

16.可變形參

package com.atguigu.java1;
/*
 * 可變個數形參的方法
 * 1.jdk 5.0新增的內容
 * 2.具體使用:
 *   2.1 可變個數形參的格式:資料型別 ... 變數名
 *   2.2 當呼叫可變個數形參的方法時,傳入的引數個數可以是:0個,1個,2個,。。。
 *   2.3 可變個數形參的方法與本類中方法名相同,形參不同的方法之間構成過載
 *   2.4 可變個數形參的方法與本類中方法名相同,形參型別也相同的陣列之間不構成過載。換句話說,二者不能共存。
 *   2.5 可變個數形參在方法的形參中,必須宣告在末尾
 * 	 2.6  可變個數形參在方法的形參中,最多隻能宣告一個可變形參。
 */
public class MethodArgsTest {	
	public static void main(String[] args) {		
		MethodArgsTest test = new MethodArgsTest();
		test.show(12);
//		test.show("hello");
//		test.show("hello","world");
//		test.show();		
		test.show(new String[]{"AA","BB","CC"});		
	}	
	public void show(int i){		
	}	
	public void show(String s){
		System.out.println("show(String)");
	}	
	public void show(String ... strs){
		System.out.println("show(String ... strs)");
		
		for(int i = 0;i < strs.length;i++){
			System.out.println(strs[i]);
		}
	}
	//不能與上一個方法同時存在
//	public void show(String[] strs){
//		
//	}
	//The variable argument type String of the method 
	//show must be the last parameter
//	public void show(String ...strs,int i){
//		
//	}
}

17.值傳遞規律

package com.atguigu.java1;
/*
 * 
 * 關於變數的賦值:  值傳遞
 * 
 *  如果變數是基本資料型別,此時賦值的是變數所儲存的資料值。
 *  如果變數是引用資料型別,此時賦值的是變數所儲存的資料的地址值。
 * 
 */
public class ValueTransferTest {
	
	public static void main(String[] args) {		
		System.out.println("***********基本資料型別:****************");
		int m = 10;
		int n = m;		
		System.out.println("m = " + m + ", n = " + n);		
		n = 20;	
		System.out.println("m = " + m + ", n = " + n);		
		System.out.println("***********引用資料型別:****************");		
		Order o1 = new Order();
		o1.orderId = 1001;		
		Order o2 = o1;//賦值以後,o1和o2的地址值相同,都指向了堆空間中同一個物件實體。		
		System.out.println("o1.orderId = " + o1.orderId + ",o2.orderId = " +o2.orderId);		
		o2.orderId = 1002;		
		System.out.println("o1.orderId = " + o1.orderId + ",o2.orderId = " +o2.orderId);		
	}	
}
class Order{	
	int orderId;	
}
-------------------------------------------------------------------------------
package com.atguigu.java1;
/*
 * 方法的形參的傳遞機制:值傳遞
 * 
 * 1.形參:方法定義時,宣告的小括號內的引數
 *   實參:方法呼叫時,實際傳遞給形參的資料
 * 
 * 2.值傳遞機制:
 * 如果引數是基本資料型別,此時實參賦給形參的是實參真實儲存的資料值。
 * 如果引數是引用資料型別,此時實參賦給形參的是實參儲存資料的地址值。
 * 
 */
public class ValueTransferTest1 {
	public static void main(String[] args) {		
		int m = 10;
		int n = 20;		
		System.out.println("m = " + m + ", n = " + n);
		//交換兩個變數的值的操作
//		int temp = m ;
//		m = n;
//		n = temp;		
		ValueTransferTest1 test = new ValueTransferTest1();
		test.swap(m, n);	"""調換引數失敗"""	
		System.out.println("m = " + m + ", n = " + n);		
	}	
	public void swap(int m,int n){
		int temp = m ;
		m = n;
		n = temp;
	}
}

18.物件作為引數傳遞

package com.atguigu.exer1;
/*
 * 考查引數的值傳遞
 * 
 * 定義一個類PassObject,在類中定義一個方法printAreas(),
 * 該方法的定義如下:public void printAreas(Circle c, int time)
 * 在printAreas方法中列印輸出1到time之間的每個整數半徑值,以及對應的面積。
 * 例如,time為5,則輸出半徑1,2,3,4,5,以及對應的圓面積。
 * 在main方法中呼叫printAreas()方法,呼叫完畢後輸出當前半徑值。程式執行結果如圖所示。
 */
public class PassObject {	
	public static void main(String[] args) {
		PassObject test = new PassObject();		
		Circle c = new Circle();		
		test.printAreas(c, 5);		
		System.out.println("now radius is " + c.radius);
	}
	public void printAreas(Circle c, int time){		
		System.out.println("Radius\t\tArea");
		int i = 1;
		for(;i <= time;i++){
			//設定圓的半徑
			c.radius = i;
			double area = c.findArea();
			System.out.println(c.radius + "\t\t" + area);
		}		
		//
//		c.radius = time + 1;
		c.radius = i;		
	}
}

package com.atguigu.exer1;
/*
 * 定義一個Circle類,包含一個double型的radius屬性代表圓的半徑,
 * 一個findArea()方法返回圓的面積。
 * 
 */
public class Circle {
	double radius;//半徑
	
	//求圓的面積
	public double findArea(){
		return Math.PI * radius * radius;
	}
}

19.遞迴方法

package com.atguigu.java2;

/*
 * 遞迴方法的使用(瞭解)
 * 1.遞迴方法:一個方法體內呼叫它自身。
 * 2. 方法遞迴包含了一種隱式的迴圈,它會重複執行某段程式碼,但這種重複執行無須迴圈控制。
 * 遞迴一定要向已知方向遞迴,否則這種遞迴就變成了無窮遞迴,類似於死迴圈。
 */
public class RecursionTest {
	public static void main(String[] args) {
		// 例1:計算1-100之間所有自然數的和
		// 方式一:
		int sum = 0;
		for (int i = 1; i <= 100; i++) {
			sum += i;
		}
		System.out.println(sum);
		// 方式二:
		RecursionTest test = new RecursionTest();
		int sum1 = test.getSum(100);
		System.out.println(sum1);		
		System.out.println("*****************");
		int value = test.f(10);
		System.out.println(value);
	}
	// 例1:計算1-n之間所有自然數的和
	public int getSum(int n) {// 3
		if (n == 1) {
			return 1;
		} else {
			return n + getSum(n - 1);
		}
	}
	// 例2:計算1-n之間所有自然數的乘積:n!
	public int getSum1(int n) {
		if (n == 1) {
			return 1;
		} else {
			return n * getSum1(n - 1);
		}
	}	
	//例3:已知有一個數列:f(0) = 1,f(1) = 4,f(n+2)=2*f(n+1) + f(n),
	//其中n是大於0的整數,求f(10)的值。
	public int f(int n){
		if(n == 0){
			return 1;
		}else if(n == 1){
			return 4;
		}else{
//			return f(n + 2) - 2 * f(n + 1);
			return 2*f(n - 1) + f(n - 2);
		}
	}
	//例4:斐波那契數列	
	//例5:漢諾塔問題	
	//例6:快排
}

20.面向物件的特徵:封裝

package com.atguigu.java;
/*
 * 面向物件的特徵一:封裝與隱藏     3W:what? why? how?
 * 一、問題的引入:
 *  當我們建立一個類的物件以後,我們可以通過"物件.屬性"的方式,對物件的屬性進行賦值。這裡,賦值操作要受到
 *  屬性的資料型別和儲存範圍的制約。除此之外,沒有其他制約條件。但是,在實際問題中,我們往往需要給屬性賦值
 *  加入額外的限制條件。這個條件就不能在屬性宣告時體現,我們只能通過方法進行限制條件的新增。(比如:setLegs())
 *  同時,我們需要避免使用者再使用"物件.屬性"的方式對屬性進行賦值。則需要將屬性宣告為私有的(private).
 *  -->此時,針對於屬性就體現了封裝性。
 * 
 * 二、封裝性的體現:
 * 我們將類的屬性xxx私有化(private),同時,提供公共的(public)方法來獲取(getXxx)和設定(setXxx)此屬性的值
 * 
 *  拓展:封裝性的體現:① 屬性私有化  ② 不對外暴露的私有的方法  ③ 單例模式   ...
 *  
 * 
 * 三、封裝性的體現,需要許可權修飾符來配合。
 * 1.Java規定的4種許可權(從小到大排列):private、預設、protected 、public 
 * 2.4種許可權可以用來修飾類及類的內部結構:屬性、方法、構造器、內部類
 * 3.具體的,4種許可權都可以用來修飾類的內部結構:屬性、方法、構造器、內部類
 *        修飾類的話,只能使用:預設、public
 * 
 * 總結封裝性:Java提供了4種許可權修飾符來修飾類及類的內部結構,體現類及類的內部結構在被呼叫時的可見性的大小。
 * 
 */
public class AnimalTest {
	public static void main(String[] args) {		
		Animal a = new Animal();
		a.name = "大黃";
//		a.age = 1;
//		a.legs = 4;//The field Animal.legs is not visible		
		a.show();		
//		a.legs = -4;
//		a.setLegs(6);
		a.setLegs(-6);		
//		a.legs = -4;//The field Animal.legs is not visible
		a.show();		
		System.out.println(a.name);		
	}
}
class Animal{	
	String name;
	private int age;
	private int legs;//腿的個數	
	//對屬性的設定
	public void setLegs(int l){
		if(l >= 0 && l % 2 == 0){
			legs = l;
		}else{
			legs = 0;
//			丟擲一個異常(暫時沒有講)
		}
	}	
	//對屬性的獲取
	public int getLegs(){
		return legs;
	}	
	public void eat(){
		System.out.println("動物進食");
	}	
	public void show(){
		System.out.println("name = " + name + ",age = " + age + ",legs = " + legs);
	}	
	//提供關於屬性age的get和set方法
	public int getAge(){
		return age;
	}
	public void setAge(int a){
		age = a;
	}	
}
//private class Dog{
//	
//}
1.什麼事方法的過載?
	方法名相同引數型別與各屬不同的方法叫做過載
2.說明java方法中的引數傳遞機制的具體體現?
	基本資料型別: 傳遞的是本身的值
    引用資料型別: 傳遞的是引用地址值
3.成員變數和區域性變數在宣告的位置上,是否有預設初始化值上,是否能有許可權修飾符修飾上,記憶體分配的位置有何不同?
	
4.return 關鍵字
	結束方法, 返回資料

21.java許可權修飾符 : 封裝性

package com.atguigu.java;

public class Order {
	
	private int orderPrivate;
	int orderDefault;
	public int orderPublic;
	private void methodPrivate(){
		orderPrivate = 1;  //除了當前類,都不能呼叫
		orderDefault = 2;  //同一個包中
		orderPublic = 3;   //哪裡都可以
	}
	void methodDefault(){
		orderPrivate = 1;
		orderDefault = 2;
		orderPublic = 3;
	}
	public void methodPublic(){
		orderPrivate = 1;
		orderDefault = 2;
		orderPublic = 3;
	}
}
-----------------------------------------------------------------------------
package com.atguigu.java;

public class OrderTest {
	public static void main(String[] args) {
		
		Order order = new Order();
		order.orderDefault = 1;
		order.orderPublic = 2;
		//出了Order類之後,私有的結構就不可以呼叫了
//		order.orderPrivate = 3;//The field Order.orderPrivate is not visible
        
		order.methodDefault();
		order.methodPublic();
		//出了Order類之後,私有的結構就不可以呼叫了
//		order.methodPrivate();//The method methodPrivate() from the type Order is not visible
	}
}

22.java中getX&setX

package com.atguigu.exer;
/*
 * 1.建立程式,在其中定義兩個類:Person和PersonTest類。定義如下:
 * 用setAge()設定人的合法年齡(0~130),用getAge()返回人的年齡。
 * 
 * 2.練習2:
 * 2.1. 在前面定義的Person類中新增構造器,利用構造器設定所有人的age屬性初始值都為18。
 * 2.2. 修改上題中類和構造器,增加name屬性,使得每次建立Person物件的同時初始化物件的age屬性值和name屬性值。
 */
public class Person {
	
	private int age;
	private String name;	
	public Person(){
		age = 18;
	}	
	public Person(String n,int a){
		name = n;
		age = a;
	}	
	public void setAge(int a){
		if(a < 0 || a > 130){
//			throw new RuntimeException("傳入的資料非法!");
			System.out.println("傳入的資料非法!");
			return;
		}
		age = a;	
	}	
	public int getAge(){
		return age;
	}	
	//絕對不要這樣寫!! 不可以講設定值和獲取值寫在同一個函式內
//	public int doAge(int a){
//		age = a;
//		return age;
//	}	
	public void setName(String n){
		name = n;
	}
	public String getName(){
		return name;
	}	
}
-------------------------------------------------------------------------------------
package com.atguigu.exer;
/*
 * 在PersonTest類中例項化Person類的物件b,
 * 呼叫setAge()和getAge()方法,體會Java的封裝性。
 */
public class PersonTest {
	public static void main(String[] args) {		
		Person p1 = new Person();
//		p1.age = 1;編譯不通過		
		p1.setAge(12);		
		System.out.println("年齡為:" + p1.getAge());		
//		p1.doAge(122);
		Person p2 = new Person("Tom", 21);
		System.out.println("name = " + p2.getName() + ",age = " + p2.getAge());	
	}
}

23.java構造器

package com.atguigu.java1;
/*
 * 類的結構之三:構造器(或構造方法、constructor)的使用
 * construct:建設、建造。  construction:CCB    constructor:建設者
 * 
 * 一、構造器的作用:
 * 1.建立物件
 * 2.初始化物件的資訊
 * 
 * 二、說明:
 * 1.如果沒有顯式的定義類的構造器的話,則系統預設提供一個空參的構造器
 * 2.定義構造器的格式:許可權修飾符  類名(形參列表){}
 * 3.一個類中定義的多個構造器,彼此構成過載
 * 4.一旦我們顯式的定義了類的構造器之後,系統就不再提供預設的空參構造器
 * 5.一個類中,至少會有一個構造器。
 */
public class PersonTest {
	public static void main(String[] args) {
		//建立類的物件:new + 構造器
		Person p = new Person();	
		p.eat();		
		Person p1 = new Person("Tom");		
		System.out.println(p1.name);				
	}
}

class Person{
	//屬性
	String name;
	int age;	
	//構造器
	public Person(){
		System.out.println("Person().....");
	}	
	public Person(String n){
		name = n;		
	}
	public Person(String n,int a){
		name = n;  //進行初始化引數
		age = a;
         eat();  //初始化方法,進行一系列的賦值
	}	
	//方法
	public void eat(){
		System.out.println("人吃飯");
	}	
	public void study(){
		System.out.println("人可以學習");
	}	
}
    

24.java屬性賦值的先後

package com.atguigu.java1;
/*
 * 總結:屬性賦值的先後順序
 * ① 預設初始化
 * ② 顯式初始化
 * ③ 構造器中初始化
 * ④ 通過"物件.方法" 或 "物件.屬性"的方式,賦值
 * 
 * 以上操作的先後順序:① - ② - ③ - ④  
 */
public class UserTest {
	public static void main(String[] args) {
		User u = new User();		
		System.out.println(u.age);		
		User u1 = new User(2);		
		u1.setAge(3);
		u1.setAge(5);		
		System.out.println(u1.age);
	}
}
class User{
	String name; //預設初始化
	int age = 1; //顯式初始化
	public User(){
	}	
	public User(int a){  //構造器中初始化	
		age = a;
	}	
	public void setAge(int a){ //通過"物件.方法" 或 "物件.屬性"的方式,賦值
		age = a;
	}	
}

25.javaBean

package com.atguigu.java1;
/*
 * JavaBean是一種Java語言寫成的可重用元件。

	所謂JavaBean,是指符合如下標準的Java類:
		>類是公共的
		>有一個無參的公共的構造器
		>有屬性,且有對應的get、set方法
 */

	private int id;
	private String name;	
	public Customer(){	
	}	
	public void setId(int i){
		id = i;
	}
	public int getId(){
		return id;
	}
	public void setName(String n){
		name = n;
	}
	public String getName(){
		return name;
	}	
}

26.this關鍵字

public class Customer {
	package com.atguigu.java2;
/*
 * this關鍵字的使用:
 * 1.this可以用來修飾、呼叫:屬性、方法、構造器
 * 
 * 2.this修飾屬性和方法:
 *   this理解為:當前物件  或 當前正在建立的物件
 * 
 *  2.1  在類的方法中,我們可以使用"this.屬性"或"this.方法"的方式,呼叫當前物件屬性或方法。但是,
 *   通常情況下,我們都選擇省略"this."。特殊情況下,如果方法的形參和類的屬性同名時,我們必須顯式
 *   的使用"this.變數"的方式,表明此變數是屬性,而非形參。
 * 
 *  2.2 在類的構造器中,我們可以使用"this.屬性"或"this.方法"的方式,呼叫當前正在建立的物件屬性或方法。
 *  但是,通常情況下,我們都選擇省略"this."。特殊情況下,如果構造器的形參和類的屬性同名時,我們必須顯式
 *   的使用"this.變數"的方式,表明此變數是屬性,而非形參。
 * 
 * 3. this呼叫構造器
 * 	  ① 我們在類的構造器中,可以顯式的使用"this(形參列表)"方式,呼叫本類中指定的其他構造器
 *    ② 構造器中不能通過"this(形參列表)"方式呼叫自己
 *    ③ 如果一個類中有n個構造器,則最多有 n - 1構造器中使用了"this(形參列表)"
 *    ④ 規定:"this(形參列表)"必須宣告在當前構造器的首行
 *    ⑤ 構造器內部,最多隻能宣告一個"this(形參列表)",用來呼叫其他的構造器
 */
public class PersonTest {
	public static void main(String[] args) {		
		Person p1 = new Person();		
		p1.setAge(1);
		System.out.println(p1.getAge());		
		p1.eat();	
		System.out.println();		
		Person p2 = new Person("Jerry",20);
		System.out.println(p2.getAge());		
	}
}
class Person{	
	private String name;
	private int age;
	public Person(){		
//		this.eat();
		String info = "Person初始化時,需要考慮如下的1,2,3,4...(共40行程式碼)";
		System.out.println(info);
	}	
	public Person(String name){
		this();   //this呼叫構造器,同時必須在這個方法中的第一行
		this.name = name;	
	}	
	public Person(int age){
		this();
		this.age = age;		
	}	
	public Person(String name,int age){
		this(age); //這裡呼叫的就是Person(int age)
		this.name = name;
		//this.age = age;
		//Person初始化時,需要考慮如下的1,2,3,4...(共40行程式碼)
	}	
	public void setName(String name){
		this.name = name;
	}
	public String getName(){
		return this.name;
	}
	public void setAge(int age){
		this.age = age;
	}
	public int getAge(){
		return this.age;
	}	
	public void eat(){
		System.out.println("人吃飯");
		this.study();
	}
	public void study(){
		System.out.println("人學習");
	}
}

27.pageckage&import關鍵字

package com.atguigu.java2;
import java.lang.reflect.Field;
import java.util.*;
import com.atguigu.exer4.Account;
import com.atguigu.exer4.Bank;
import com.atguigu.java2.java3.Dog;
import static java.lang.System.*;
import static java.lang.Math.*;
/*
 * 一、package關鍵字的使用
 * 1.為了更好的實現專案中類的管理,提供包的概念
 * 2.使用package宣告類或介面所屬的包,宣告在原始檔的首行
 * 3.包,屬於識別符號,遵循識別符號的命名規則、規範(xxxyyyzzz)、“見名知意”
 * 4.每"."一次,就代表一層檔案目錄。
 * 
 * 補充:同一個包下,不能命名同名的介面、類。
 *     不同的包下,可以命名同名的介面、類。
 * 二、import關鍵字的使用
 * import:匯入
 * 1. 在原始檔中顯式的使用import結構匯入指定包下的類、介面
 * 2. 宣告在包的宣告和類的宣告之間
 * 3. 如果需要匯入多個結構,則並列寫出即可
 * 4. 可以使用"xxx.*"的方式,表示可以匯入xxx包下的所有結構
 * 5. 如果使用的類或介面是java.lang包下定義的,則可以省略import結構
 * 6. 如果使用的類或介面是本包下定義的,則可以省略import結構
 * 7. 如果在原始檔中,使用了不同包下的同名的類,則必須至少有一個類需要以全類名的方式顯示。
 * 8. 使用"xxx.*"方式表明可以呼叫xxx包下的所有結構。但是如果使用的是xxx子包下的結構,則仍需要顯式匯入
 * 
 * 9. import static:匯入指定類或介面中的靜態結構:屬性或方法。 
 */
public class PackageImportTest {
	public static void main(String[] args) {		
		String info = Arrays.toString(new int[]{1,2,3});		
		Bank bank = new Bank();		
		ArrayList list = new ArrayList();
		HashMap map = new HashMap();		
		Scanner s = null;	
		System.out.println("hello!");		
		Person p = new Person();		
		Account acct = new Account(1000);
		//全類名的方式顯示
		com.atguigu.exer3.Account acct1 = new com.atguigu.exer3.Account(1000,2000,0.0123);		
		Date date = new Date();
		java.sql.Date date1 = new java.sql.Date(5243523532535L);	
		Dog dog = new Dog();		
		Field field = null;		
		out.println("hello");		
		long num = round(123.434);
	}
}

28.總結

//面向物件的特徵一:封裝與隱藏
1.為什麼要引入封裝性?
我們程式設計追求“高內聚,低耦合”。
高內聚 :類的內部資料操作細節自己完成,不允許外部干涉;
低耦合 :僅對外暴露少量的方法用於使用。

隱藏物件內部的複雜性,只對外公開簡單的介面。便於外界呼叫,從而提高系統的可擴充套件性、可維護性。通俗的說,把該隱藏的隱藏起來,該暴露的暴露出來。這就是封裝性的設計思想。

2.問題引入: 
當我們建立一個類的物件以後,我們可以通過"物件.屬性"的方式,對物件的屬性進行賦值。這裡,賦值操作要受到屬性的資料型別和儲存範圍的制約。除此之外,沒其他制約條件。但是,在實際問題中,我們往往需要給屬性賦值加入額外的限制條件。這個條件就不能在屬性宣告時體現,我們只能通過方法進行限制條件的新增。(比如:setLegs()同時,我們需要避免使用者再使用"物件.屬性"的方式對屬性進行賦值。則需要將屬性宣告為私有的(private).
  -->此時,針對於屬性就體現了封裝性。
3.封裝性思想具體的程式碼體現:
體現一:將類的屬性xxx私化(private),同時,提供公共的(public)方法來獲取(getXxx)和設定(setXxx)此屬性的值
private double radius;
public void setRadius(double radius){
	this.radius = radius;
}
public double getRadius(){
	return radius;
}
體現二:不對外暴露的私有的方法
體現三:單例模式(將構造器私有化)
體現四:如果不希望類在包外被呼叫,可以將類設定為預設的。

4.Java規定的四種許可權修飾符
4.1 許可權從小到大順序為:private <  預設 < protected < public
4.2 具體的修飾範圍:

4.3 許可權修飾符可用來修飾的結構說明:
4種許可權都可以用來修飾類的內部結構:屬性、方法、構造器、內部類
修飾類的話,只能使用:預設、public

//構造器:
1.構造器(或構造方法):Constructor
構造器的作用:
 * 1.建立物件
 * 2.初始化物件的資訊
2.使用說明:
 * 1.如果沒顯式的定義類的構造器的話,則系統預設提供一個空參的構造器
 * 2.定義構造器的格式:許可權修飾符  類名(形參列表){}
 * 3.一個類中定義的多個構造器,彼此構成過載
 * 4.一旦我們顯式的定義了類的構造器之後,系統就不再提供預設的空參構造器
 * 5.一個類中,至少會有一個構造器。

3.舉例:
//構造器
	public Person(){
		System.out.println("Person().....");
	}	
	public Person(String n){
		name = n;		
	}	
	public Person(String n,int a){
		name = n;
		age = a;
	}

//屬性賦值:
 * 總結:屬性賦值的先後順序
 * 
 * 
 * ① 預設初始化
 * ② 顯式初始化
 * ③ 構造器中初始化
 * **********************
 * ④ 通過"物件.方法" 或 "物件.屬性"的方式,賦值
 * 
 * 以上操作的先後順序:① - ② - ③ - ④  
     
//JavaBean:
	所謂JavaBean,是指符合如下標準的Java類:
		>類是公共的
		>一個無參的公共的構造器
		>屬性,且對應的get、set方法

// this關鍵字:
1.可以呼叫的結構:屬性、方法;構造器
2.this呼叫屬性、方法:
this理解為:當前物件  或 當前正在建立的物件

2.1  在類的方法中,我們可以使用"this.屬性"或"this.方法"的方式,呼叫當前物件屬性或方法。但是,
 *   通常情況下,我們都擇省略"this."。特殊情況下,如果方法的形參和類的屬性同名時,我們必須顯式
 *   的使用"this.變數"的方式,表明此變數是屬性,而非形參。
 * 
 *  2.2 在類的構造器中,我們可以使用"this.屬性"或"this.方法"的方式,呼叫當前正在建立的物件屬性或方法。但是,通常情況下,我們都擇省略"this."。特殊情況下,如果構造器的形參和類的屬性同名時,我們必須顯式的使用"this.變數"的方式,表明此變數是屬性,而非形參。

3.this呼叫構造器:
① 我們在類的構造器中,可以顯式的使用"this(形參列表)"方式,呼叫本類中指定的其他構造器
② 構造器中不能通過"this(形參列表)"方式呼叫自己
③ 如果一個類中有n個構造器,則最多有 n - 1構造器中使用了"this(形參列表)"
④ 規定:"this(形參列表)"必須宣告在當前構造器的首行
⑤ 構造器內部,最多隻能宣告一個"this(形參列表)",用來呼叫其他的構造器

//關鍵字package/import
1. package的使用
1.1 使用說明:
 * 1.為了更好的實現專案中類的管理,提供包的概念
 * 2.使用package宣告類或介面所屬的包,宣告在原始檔的首行
 * 3.包,屬於識別符號,遵循識別符號的命名規則、規範(xxxyyyzzz)、“見名知意”
 * 4.每"."一次,就代表一層檔案目錄。

2. import的使用:
import:匯入
 * 1. 在原始檔中顯式的使用import結構匯入指定包下的類、介面
 * 2. 宣告在包的宣告和類的宣告之間
 * 3. 如果需要匯入多個結構,則並列寫出即可
 * 4. 可以使用"xxx.*"的方式,表示可以匯入xxx包下的所結構
 * 5. 如果使用的類或介面是java.lang包下定義的,則可以省略import結構
 * 6. 如果使用的類或介面是本包下定義的,則可以省略import結構
 * 7. 如果在原始檔中,使用了不同包下的同名的類,則必須至少一個類需要以全類名的方式顯示。
 * 8. 使用"xxx.*"方式表明可以呼叫xxx包下的所結構。但是如果使用的是xxx子包下的結構,則仍需要顯式匯入
 * 
 * 9. import static:匯入指定類或介面中的靜態結構:屬性或方法。 

29.java繼承

package com.atguigu.java;
/*
 * 面向物件的特徵之二:繼承性    why?
 * 
 * 一、繼承性的好處:
 * ① 減少了程式碼的冗餘,提高了程式碼的複用性
 * ② 便於功能的擴充套件
 * ③ 為之後多型性的使用,提供了前提
 * 
 * 
 * 二、繼承性的格式: 
 *    class A extends B{}
 *    A:子類、派生類、subclass
 *    B:父類、超類、基類、superclass
 *    
 *    2.1體現:一旦子類A繼承父類B以後,子類A中就獲取了父類B中宣告的所有的屬性和方法。
 *    	特別的,父類中宣告為private的屬性或方法,子類繼承父類以後,仍然認為獲取了父類中私有的結構。
 *    只有因為封裝性的影響,使得子類不能直接呼叫父類的結構而已。
 *    2.2 子類繼承父類以後,還可以宣告自己特有的屬性或方法:實現功能的拓展。
 *    子類和父類的關係,不同於子集和集合的關係。
 *    extends:延展、擴充套件
 * 
 * 三、Java中關於繼承性的規定:
 * 	  1.一個類可以被多個子類繼承。
 *    2.Java中類的單繼承性:一個類只能有一個父類
 *    3.子父類是相對的概念。
 *    4.子類直接繼承的父類,稱為:直接父類。間接繼承的父類稱為:間接父類
 *    5.子類繼承父類以後,就獲取了直接父類以及所有間接父類中宣告的屬性和方法
 *    
 *  
 * 四、 1. 如果我們沒有顯式的宣告一個類的父類的話,則此類繼承於java.lang.Object類
 *    2. 所有的java類(除java.lang.Object類之外)都直接或間接的繼承於java.lang.Object類
 *    3. 意味著,所有的java類具有java.lang.Object類宣告的功能。
 */
public class ExtendsTest {
	public static void main(String[] args) {
		
		Person p1 = new Person();
//		p1.age = 1;
		p1.eat();
		System.out.println("*****************");		
		Student s1 = new Student();
		s1.eat();
//		s1.sleep();
		s1.name = "Tom";
		s1.setAge(10);
		System.out.println(s1.getAge());		
		s1.breath();				
		Creature c = new Creature();
		System.out.println(c.toString());
	}
}

----------------------------------------------------------------
package com.atguigu.java;
public class Person extends Creature{	
	String name;
	private int age;	
	public Person(){
		
	}	
	public Person(String name,int age){
		this.name = name;
		this.age = age;
	}	
	public void eat(){
		System.out.println("吃飯");
		sleep();
	}	
	private void sleep(){
		System.out.println("睡覺");
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}		
}
--------------------------------------------------------------------    
package com.atguigu.java;
public class Student extends Person{
	
//	String name;
//	int age;
	String major;
	
	public Student(){	
	}
	public Student(String name,int age,String major){
		this.name = name;
//		this.age = age;
		setAge(age);
		this.major = major;
	}
//	public void eat(){
//		System.out.println("吃飯");
//	}
//	
//	public void sleep(){
//		System.out.println("睡覺");
//	}
	public void study(){
		System.out.println("學習");
	}
	public void show(){
		System.out.println("name:" + name + ",age:" + getAge());
	}
}

30.重寫

package com.atguigu.java1;
/*
 * 方法的重寫(override / overwrite)
 * 1.重寫:子類繼承父類以後,可以對父類中同名同參數的方法,進行覆蓋操作
 * 2.應用:重寫以後,當建立子類物件以後,通過子類物件呼叫子父類中的同名同參數的方法時,實際執行的是子類重寫父類的方法。
 * 3. 重寫的規定:
 * 			方法的宣告: 許可權修飾符  返回值型別  方法名(形參列表) throws 異常的型別{
 * 						//方法體
 * 					}
 * 			約定俗稱:子類中的叫重寫的方法,父類中的叫被重寫的方法
 * 		① 子類重寫的方法的方法名和形參列表與父類被重寫的方法的方法名和形參列表相同
 *      ② 子類重寫的方法的許可權修飾符不小於父類被重寫的方法的許可權修飾符
 *      	>特殊情況:子類不能重寫父類中宣告為private許可權的方法
 *      ③ 返回值型別:
 *      	>父類被重寫的方法的返回值型別是void,則子類重寫的方法的返回值型別只能是void
 *      	>父類被重寫的方法的返回值型別是A型別,則子類重寫的方法的返回值型別可以是A類或A類的子類
 *      	>父類被重寫的方法的返回值型別是基本資料型別(比如:double),則子類重寫的方法的返回值型別必須是相同的基本資料型別(必須也是double)
 *		④ 子類重寫的方法丟擲的異常型別不大於父類被重寫的方法丟擲的異常型別(具體放到異常處理時候講)
 *	**********************************************************************
 *		子類和父類中的同名同參數的方法要麼都宣告為非static的(考慮重寫),要麼都宣告為static的(靜態方法不能被重寫)。
 *
 * 面試題:區分方法的過載與重寫
 */
public class PersonTest {
	public static void main(String[] args) {
		
		Student s = new Student("電腦科學與技術");
		s.eat();
		s.walk(10);
		System.out.println("**************");
		s.study();
		Person p1 = new Person();
		p1.eat();
	}
}
------------------------------------------------------------------------
package com.atguigu.java1;
public class Person {
	String name;
	int age;
	public Person(){		
	}
	public Person(String name,int age){
		this.name = name;
		this.age = age;
	}	
	 void eat(){
		System.out.println("吃飯");
	}
	public void walk(int distance){
		System.out.println("走路,走的距離是:" + distance + "公里");
		show();
		eat();
	}	
	private void show(){
		System.out.println("我是一個人");
	}	
	public Object info(){
		return null;
	}	
	public double info1(){
		return 1.0;
	}
}
-------------------------------------------------------------------------------
package com.atguigu.java1;
public class Student extends Person{
	String major;	
	public Student(){		
	}
	public Student(String major){
		this.major = major;
	}	
    //同時添加了自己的新功能
	public void study(){
		System.out.println("學習。專業是:" + major);
	}	
	//對父類中的eat()進行了重寫,父類的同名同參
	public void eat(){
		System.out.println("學生應該多吃有營養的食物");   
	}	
	public void show(){
		System.out.println("我是一個學生");
	}	
	public String info(){
		return null;
	}	
	public void walk(int distance) {
		System.out.println("重寫的方法");
	}

}

31.super關鍵字

package com.atguigu.java3;
/*
 * super關鍵字的使用
 * 1.super理解為:父類的
 * 2.super可以用來呼叫:屬性、方法、構造器
 * 
 * 3.super的使用:呼叫屬性和方法
 * 
 *   3.1 我們可以在子類的方法或構造器中。通過使用"super.屬性"或"super.方法"的方式,顯式的呼叫
 *   父類中宣告的屬性或方法。但是,通常情況下,我們習慣省略"super."
 *   3.2 特殊情況:當子類和父類中定義了同名的屬性時,我們要想在子類中呼叫父類中宣告的屬性,則必須顯式的
 *   使用"super.屬性"的方式,表明呼叫的是父類中宣告的屬性。
 *   3.3 特殊情況:當子類重寫了父類中的方法以後,我們想在子類的方法中呼叫父類中被重寫的方法時,則必須顯式的
 *   使用"super.方法"的方式,表明呼叫的是父類中被重寫的方法。
 * 
 * 4.super呼叫構造器
 * 	 4.1  我們可以在子類的構造器中顯式的使用"super(形參列表)"的方式,呼叫父類中宣告的指定的構造器
 *   4.2 "super(形參列表)"的使用,必須宣告在子類構造器的首行!
 *   4.3 我們在類的構造器中,針對於"this(形參列表)"或"super(形參列表)"只能二選一,不能同時出現
 *   4.4 在構造器的首行,沒有顯式的宣告"this(形參列表)"或"super(形參列表)",則預設呼叫的是父類中空參的構造器:super()
 *   4.5 在類的多個構造器中,至少有一個類的構造器中使用了"super(形參列表)",呼叫父類中的構造器
 */
public class SuperTest {
	public static void main(String[] args) {	
		Student s = new Student();
		s.show();	
		System.out.println();	
		s.study();	
		Student s1 = new Student("Tom", 21, "IT");
		s1.show();		
		System.out.println("************");
		Student s2 = new Student();		
	}
}
---------------------------------------------------------------------------
package com.atguigu.java3;
public class Person {
	String name;
	int age;
	int id = 1001;//身份證號
	public Person(){
		System.out.println("我無處不在!");
	}
	public Person(String name){
		this.name = name;
	}
	public Person(String name,int age){
		this(name);
		this.age = age;
	}
	public void eat(){
		System.out.println("人:吃飯");
	}
	public void walk(){
		System.out.println("人:走路");
	}
}

-----------------------------------------------------------------------------
package com.atguigu.java3;
public class Student extends Person{	
	String major;
	int id = 1002;//學號
	
	public Student(){
		super();
	}
	public Student(String major){
		super();
		this.major = major;
	}	
	public Student(String name,int age,String major){
//		this.name = name;
//		this.age = age;
		super(name,age);
		this.major = major;
	}	
	@Override
	public void eat() {
		System.out.println("學生:多吃有營養的食物");
	}	
	public void study(){
		System.out.println("學生:學習知識");
		this.eat();
		super.eat();  //次數呼叫的父類的eat方法
		walk();
	}	
	public void show(){
		System.out.println("name = " + name + ", age = " + age);
		System.out.println("id = " + this.id);
		System.out.println("id = " + super.id);
	}
}

32.子類例項化過程

package com.atguigu.java3;
/*
 * 子類物件例項化的全過程
 * 1. 從結果上來看:(繼承性)
 * 		子類繼承父類以後,就獲取了父類中宣告的屬性或方法。
 *      建立子類的物件,在堆空間中,就會載入所有父類中宣告的屬性。
 * 2. 從過程上來看:
 * 		當我們通過子類的構造器建立子類物件時,我們一定會直接或間接的呼叫其父類的構造器,進而呼叫父類的父類的構造器,...
 *    直到呼叫了java.lang.Object類中空參的構造器為止。正因為載入過所有的父類的結構,所以才可以看到記憶體中有
 *    父類中的結構,子類物件才可以考慮進行呼叫。
 * 明確:雖然建立子類物件時,呼叫了父類的構造器,但是自始至終就建立過一個物件,即為new的子類物件。
 */
public class InstanceTest {
}

33.eclipse快捷鍵

package com.atguigu.java;

import java.sql.Date;
import java.util.ArrayList;
import java.util.HashMap;

/*
 * Eclipse中的快捷鍵: 
 * 1.補全程式碼的宣告:alt + /
 * 2.快速修復: ctrl + 1  
 * 3.批量導包:ctrl + shift + o
 * 4.使用單行註釋:ctrl + /
 * 5.使用多行註釋: ctrl + shift + /   
 * 6.取消多行註釋:ctrl + shift + \
 * 7.複製指定行的程式碼:ctrl + alt + down 或 ctrl + alt + up
 * 8.刪除指定行的程式碼:ctrl + d
 * 9.上下移動程式碼:alt + up  或 alt + down
 * 10.切換到下一行程式碼空位:shift + enter
 * 11.切換到上一行程式碼空位:ctrl + shift + enter
 * 12.如何檢視原始碼:ctrl + 選中指定的結構   或  ctrl + shift + t
 * 13.退回到前一個編輯的頁面:alt + left 
 * 14.進入到下一個編輯的頁面(針對於上面那條來說的):alt + right
 * 15.游標選中指定的類,檢視繼承樹結構:ctrl + t
 * 16.複製程式碼: ctrl + c
 * 17.撤銷: ctrl + z
 * 18.反撤銷: ctrl + y
 * 19.剪下:ctrl + x 
 * 20.貼上:ctrl + v
 * 21.儲存: ctrl + s
 * 22.全選:ctrl + a
 * 23.格式化程式碼: ctrl + shift + f
 * 24.選中數行,整體往後移動:tab
 * 25.選中數行,整體往前移動:shift + tab
 * 26.在當前類中,顯示類結構,並支援搜尋指定的方法、屬性等:ctrl + o
 * 27.批量修改指定的變數名、方法名、類名等:alt + shift + r
 * 28.選中的結構的大小寫的切換:變成大寫: ctrl + shift + x
 * 29.選中的結構的大小寫的切換:變成小寫:ctrl + shift + y
 * 30.調出生成getter/setter/構造器等結構: alt + shift + s
 * 31.顯示當前選擇資源(工程 or 檔案)的屬性:alt + enter
 * 32.快速查詢:參照選中的Word快速定位到下一個 :ctrl + k
 * 
 * 33.關閉當前視窗:ctrl + w
 * 34.關閉所有的視窗:ctrl + shift + w
 * 35.檢視指定的結構使用過的地方:ctrl + alt + g
 * 36.查詢與替換:ctrl + f
 * 37.最大化當前的View:ctrl + m
 * 38.直接定位到當前行的首位:home
 * 39.直接定位到當前行的末位:end
 */

public class EclipseKeys {
	final double PROJECT_ACCOUNT_ID = 3.14;
	public static void main(String[] args) {
		String s = new String();
		String str = new String();
		char c = str.charAt(0);
		int num =1;
		
		ArrayList list123 = new ArrayList();
		list123.add(123);
		list123.add(123);
		
		HashMap map = null;
		map = new HashMap();
		Date date = new Date(34241324L);
		HashMap map1 = null;	
	}
}

class user{
	private int id;
	private String name;
	public user(int id, String name) {
		this.id = id;
		this.name = name;
	}
	public user(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}	
}

34.java多型性

package com.atguigu.java4;

/*
 * 面向物件特徵之三:多型性
 * 1.理解多型性:可以理解為一個事物的多種形態。
 * 2.何為多型性:
 *   物件的多型性:父類的引用指向子類的物件(或子類的物件賦給父類的引用)
 * 3. 多型的使用:虛擬方法呼叫
 *   有了物件的多型性以後,我們在編譯期,只能呼叫父類中宣告的方法,但在執行期,我們實際執行的是子類重寫父類的方法。
 *   總結:編譯,呼叫父類的方法(如果呼叫父類沒有的方法就編譯不通過);執行,呼叫子類的方法。  
 * 4.多型性的使用前提:  ① 類的繼承關係  ② 方法的重寫
 * 5.物件的多型性,只適用於方法,不適用於屬性(編譯和執行都看左邊)
 */
public class PersonTest {	
	public static void main(String[] args) {	
		Person p1 = new Person();
		p1.eat();	
		Man man = new Man();
		man.eat();
		man.age = 25;
		man.earnMoney();		
		//*************************************************
		System.out.println("*******************");
		//物件的多型性:父類的引用指向子類的物件
		Person p2 = new Man();
//		Person p3 = new Woman();
		//多型的使用:當呼叫子父類同名同參數的方法時,實際執行的是子類重寫父類的方法 ---虛擬方法呼叫
		p2.eat();
		p2.walk();		
//		p2.earnMoney(); //Person中沒有earnMoney這個方法所以不能呼叫		
		System.out.println(p2.id);//1001		
	}
}
--------------------------------------------------------------------------------------
package com.atguigu.java4;
public class Person {
	String name;
	int age;	
	int id = 1001;	
	public void eat(){
		System.out.println("人:吃飯");
	}	
	public void walk(){
		System.out.println("人:走路");
	}	
}
--------------------------------------------------------------------------------------
package com.atguigu.java4;
public class Man extends Person{	
	boolean isSmoking;	
	int id = 1002;	
	public void earnMoney(){
		System.out.println("男人負責掙錢養家");
	}	
	public void eat(){
		System.out.println("男人多吃肉,長肌肉");
	}	
	public void walk(){
		System.out.println("男人霸氣的走路");
	}
}
----------------------------------------------------------------------------------
package com.atguigu.java4;
public class Woman extends Person{	
	boolean isBeauty;	
	public void goShopping(){
		System.out.println("女人喜歡購物");
	}	
	public void eat(){
		System.out.println("女人少吃,為了減肥");
	}	
	public void walk(){
		System.out.println("女人窈窕的走路");
	}
}
----------------------------------------------另一個方式體現---------------------------------------
package com.atguigu.java4;

import java.sql.Connection;


//多型性的使用舉例一:
public class AnimalTest {	
	public static void main(String[] args) {		
		AnimalTest test = new AnimalTest();
		test.func(new Dog()); //需要的Animal物件,傳入的是子類Dog,解決了方法的重複定義		
		test.func(new Cat());
	}	
	public void func(Animal animal){//Animal animal = new Dog();
		animal.eat();
		animal.shout();
		
		if(animal instanceof Dog){  //檢驗引用型別
			Dog d = (Dog)animal; //重新賦值
			d.watchDoor();
		}
	}	
//	public void func(Dog dog){
//		dog.eat();
//		dog.shout();
//	}
//	public void func(Cat cat){
//		cat.eat();
//		cat.shout();
//	}
}
class Animal{	
	public void eat(){
		System.out.println("動物:進食");
	}	
	public void shout(){
		System.out.println("動物:叫");
	}		
}
class Dog extends Animal{
	public void eat(){
		System.out.println("狗吃骨頭");
	}	
	public void shout(){
		System.out.println("汪!汪!汪!");
	}	
	public void watchDoor(){
		System.out.println("看門");
	}
}
class Cat extends Animal{
	public void eat(){
		System.out.println("貓吃魚");
	}	
	public void shout(){
		System.out.println("喵!喵!喵!");
	}
}
//舉例二:
class Order{
	public void method(Object obj){		
	}
}
//舉例三:
class Driver{
	public void doData(Connection conn){//conn = new MySQlConnection(); / conn = new OracleConnection();
		//規範的步驟去操作資料
//		conn.method1();
//		conn.method2();
//		conn.method3();		
	}
}
    

35.java多型2:

面試題:
package com.atguigu.java5;
import java.util.Random;
//面試題:多型是編譯時行為還是執行時行為?
//證明如下:
class Animal  {
	protected void eat() {
		System.out.println("animal eat food");
	}
}
class Cat  extends Animal  {
	protected void eat() {
		System.out.println("cat eat fish");
	}
}
class Dog  extends Animal  {
	public void eat() {
		System.out.println("Dog eat bone");
	}
}
class Sheep  extends Animal  {
	public void eat() {
		System.out.println("Sheep eat grass");
	}
}
public class InterviewTest {

	public static Animal  getInstance(int key) {
		switch (key) {
		case 0:
			return new Cat ();
		case 1:
			return new Dog ();
		default:
			return new Sheep ();
		}
	}
	public static void main(String[] args) {
		int key = new Random().nextInt(3);
		System.out.println(key);
		Animal  animal = getInstance(key);
		animal.eat();
	}
}