【45】WEB安全學習----JAVA基礎二
一、類與物件
1、構造方法
作用:可以通過構造方法實現例項化物件中的屬性初始化處理。若類中沒有自己定義構造方法,JAVA會預設提供一個無參、什麼都不做的構造方法。
定義:方法名稱必須和類名稱保持一致、不允許設定任何的返回值型別、是在使用關鍵字new例項化物件時自動呼叫。
構造方法過載:構造方法既然是屬於一個方法,那麼肯定具備方法的過載性。
class Person{ //定義一個類,類名稱首字母大寫 private String name; //定義類的屬性 private int age; public Person(String n,int a) { //自定義有參構造方法 name = n; age = a; } public Person() { //定義無參無返回值構造方法(預設) } public Person(String n) { //自定義有參構造方法 name = n; } public void Person_print() { System.out.println(name+"----"+age); } } public class Test{ public static void main(String ages[]) { Person p1 = new Person("小明",22); //構造方法過載 p1.Person_print(); Person p2 = new Person("小花"); //構造方法過載 p2.Person_print(); Person p3 = new Person(); //構造方法過載 p3.Person_print(); } }
why?為什麼構造方法沒有返回值,而不用void值代替呢?
答:編譯器為了區分構造方法與普通方法,所以構造方法定義時不寫返回值型別。
2、setter和getter
面向物件三大特性:封裝、繼承、多型。那麼通過使用setter和getter來對類中的私有屬性進行讀取和修改(private修飾體現封裝性)。
class Person{ //定義一個類,類名稱首字母大寫 private String name; //定義類的屬性 private int age; public String getName() { //為類中的私有屬性分別設定setter和getter方法 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 Person_print() { System.out.println(name+"----"+age); } } public class Test{ public static void main(String ages[]) { Person p1 = new Person(); p1.setName("小明"); p1.setAge(20); p1.Person_print(); } }
why?構造方法和setter都可以對類中的屬性值進行設定,那麼它們的區別是什麼?
答:構造方法是在物件例項化時為屬性設定初始化內容,而setter除了擁有設定屬性初始化功能外,還可以修改資料的功能。
3、匿名物件
在例項化時沒有對物件進行地址引用(設定物件名),那麼此時例項化出來的物件因為沒有引用,故會垃圾回收。
new Person();//匿名物件
二、this關鍵字
this可以描述:當前類中的屬性(this.屬性),當前類中的方法(this()、this.方法()),描述當前物件;
class Person{ private String name; private int age; public Person() { this.name = "預設值"; this.age = 20; }; public Person(String name) { this(); //this()描述無參構造方法 } public Person(String name,int age) { this.name = name; //this描述當前類屬性 this.age = age; this.Person_print(); //this描述當前類方法,構造方法可以呼叫普通方法,但普通方法不能呼叫構造方法 } public void Person_print() { System.out.println(name+"----"+age + "----" + this);//this描述當前物件 } } public class Test{ public static void main(String ages[]) { Person p1 = new Person(); p1.Person_print(); } }
定義簡單JAVA類原則:
類名具有意義、類中每個屬性用private封裝、每個屬性提供setter和getter方法、至少有一個無參構造方法(預設構造方法)、類中不能有任何輸出語句、提供一個返回類資訊的方法(可選,如getinfo())
class Person{ //類名要有意義
private String name; //屬性用private封裝
private int age;
public Person() { //至少定義一個無參構造方法
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public void setname(String name) { //為每個屬性配置getter和setter方法,不管用得著不
this.name = name;
}
public String getname() {
return this.name;
}
public void setage(int age) {
this.age = age;
}
public int getage() {
return this.age;
}
public String getinfo() { //配置一個返回類資訊的方法,可選。類中不能有任何輸出語句
return "name:" + this.name + ",age:" + this.age;
}
}
public class Test{
public static void main(String args[]) {
Person p1 = new Person("小明",20);
System.out.println(p1.getinfo());
}
}
三、static關鍵字
注意:static並不受例項化物件的控制,可以直接呼叫類使用。這也是在主類中定義類和方法需要加static的原因。
static定義類屬性:
在類屬性中用static修飾,則此屬性就變成公共屬性,所有通過此類例項化的物件都受這個static公共屬性控制,也就是靜態變數作用:
class Person{
public static String name; //name屬性設定static修飾
private int age;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getinfo() { //
return "name:" + this.name + ",age:" + this.age;
}
}
public class Test{
public static void main(String args[]) {
Person p1 = new Person("小明",22);
Person p2 = new Person("小花",20);
System.out.println(p1.getinfo()); //name:小花,age:22
System.out.println(p2.getinfo()); //name:小花,age:20
//可以看到,static修飾類屬性後編變成一個公共屬性,只要其中一個物件修改了,那麼其它物件中屬性也被修改了
Person.name = "張三"; //可以不例項化物件直接呼叫類和修改類屬性,前提是public公開
System.out.println(Person.name);
}
}
static定義類方法:
用static定義的方法和普通方法最大的區別就是可以不例項化直接呼叫,所以就有了限制:
1、static方法只允許呼叫類中的static方法和static屬性
2、非static方法可以呼叫類中的static方法和static屬性
原因:因為static定義的屬性和方法可以在沒有例項化物件前呼叫,所以static定義的方法不能呼叫普通方法和屬性。
public class Test{
public static void main(String args[]) {
getinfo(); //這也解釋了為啥在主類中定義方法需要加static關鍵字,因為不需要例項化就能呼叫static方法
}
public static String getinfo() {
return "hello world";
}
}
四、程式碼塊
靜態程式碼塊:
目的:為類中的靜態屬性初始化,靜態程式碼塊會優先於構造塊執行,並不管有多少例項化物件,只執行一次。
class Person{
private String name;
private int age;
private static String addr;
public Person() {}
public Person(String name,int age) {
this.name = name;
this.age = age;
}
static { //靜態程式碼塊
Person.addr = "北京";
System.out.println("靜態程式碼塊會優先構造塊執行");
}
}
public class Test{
public static void main(String args[]) {
Person p1 = new Person("小明",20);
Person p2 = new Person("小花",18);
}
}
普通程式碼塊::
目的:可以在一個方法中進行一些結構的拆分,以防止相同變數名稱所帶來的影響:
public class Test{
public static void main(String args[]) {
{ //定義普通程式碼塊
int x = 10; //通過普通程式碼塊進行結構拆分 區域性變數
}
int x = 2; //全域性變數
}
}
構造程式碼塊:
目的:在類中定義,會優先於構造方法執行,且每次例項化物件都會呼叫構造程式碼塊(和靜態程式碼塊的區別):
class Person{
public Person() {
System.out.println("構造方法執行了");
}
{ //定義構造程式碼塊,和普通程式碼塊類似,不管不是定義在方法裡,而是在類中
System.out.println("構造程式碼塊執行了");
}
}
public class Test{
public static void main(String args[]) {
new Person();
new Person();
/*
構造程式碼塊執行了
構造方法執行了
構造程式碼塊執行了
構造方法執行了
*/
}
}
五、陣列
陣列的動態初始化:資料型別 陣列名稱 [] = new 資料型別 [長度];
陣列的靜態初始化:資料型別 陣列名稱 [] = new 資料型別 {資料1,資料2......};
public class Test{
public static void main(String args[]) {
String array1 [] = new String [2]; //陣列的動態初始化
array1[0] = "你好";
array1[1] = "世界";
String array2 [] = new String [] {"你好","世界"}; //陣列的靜態初始化
for(int i = 0;i < array1.length;i++) {
System.out.println(array1[i]);
}
}
}
foreach迴圈:
為了避免使用for迴圈運算元組下標越界問題,JDK參考.NET增強了for迴圈:foreach也可以寫成for
public class Test{
public static void main(String args[]) {
String array1 [] = new String [2]; //陣列的動態初始化
array1[0] = "你好";
array1[1] = "世界";
for(String s1 : array1) {
System.out.println(s1);
}
}
}
多維陣列:一個[]表示一行,兩個[]表示行和列(表),三個[]表示三維:xyz座標
public class Test{
public static void main(String args[]) {
String array1 [][] = new String [2][2]; //建立二行二列的多維陣列
array1[0][0] = "aa";
array1[0][1] = "11";
array1[1][0] = "bb";
array1[1][1] = "22";
for(String s1[] : array1) {
for(String s2 : s1) {
System.out.println(s2);
}
}
}
}
陣列的引用:陣列也是引用型別,所以也可以進行引用傳遞
public class Test{
public static void main(String args[]) {
int int1 [] = new int [] {1,2,3,4,5,6}; //靜態初始化定義一個數組
int int2 [] = new int[10];
int2 = array(int1);
for(int i : int2) {
System.out.println(i);
}
}
public static int [] array(int array_int1 []) { //陣列可以當作引數傳遞,也可以返回陣列
for(int i = 0; i < array_int1.length; i++) {
array_int1[i] = array_int1[i] * 2;
}
return array_int1;
}
}
可變引數:當傳遞的引數個數不確定時可採用可變引數
public class Test{
public static void main(String args[]) {
array(1,2,3,4,5,6); //可變引數可接受普通引數列表及陣列引用引數
array(new int [] {1,2,3,4,5});
}
public static void array(int ... int1) { //通過加三個.就是可變引數傳遞
for(int i : int1) {
System.out.println(i);
}
}
}
物件陣列:陣列可以儲存基本資料型別,當然也可以儲存引用型別:類
class Person{
private String name;
private int age;
public Person() {}
public Person(String name,int age) {
this.name = name;
this.age = age;
}
public String getinfo() {
return "姓名:" + this.name + "年齡:" + this.age;
}
}
public class Test{
public static void main(String args[]) {
Person array_person [] = new Person [3];
array_person [0] = new Person("張三",17);
array_person [1] = new Person("李四",20);
array_person [2] = new Person("王五",23);
for(int i = 0; i < array_person.length; i++) {
System.out.println(array_person[i].getinfo());
}
}
}
六、引用傳遞
類之間可以互相關聯,也可以由多個類組合成一個大的類:程式碼鏈
class 電腦{
private 主機 主機 []; //一臺電腦可以有多個主機 物件陣列
private 顯示器 顯示器; //一個顯示器
}
class 主機{
private CPU CPU;
private 硬碟 硬碟;
private 記憶體 記憶體;
}
class 顯示器{
private 滑鼠 滑鼠;
private 鍵盤 鍵盤;
}
class 滑鼠{}
class 鍵盤{}
class CPU{}
class 硬碟{}
class 記憶體{}
public class Test{
public static void main(String args[]) {
}
}