面向對象三大特點:封裝、繼承、多態
封裝概念
① 將東西包裝在一起,然後以新的完整形式呈現出來:
將方法和字段一起包裝到一個單元中,單元以類的形式實現;
② 信息隱藏,隱藏對象的實現細節,不讓外部直接訪問到;
③ 將數據和方法包裝進類中,加上具體實現的隱藏,共同被稱作封裝,其結果是一個同時帶有特征和行為的數據類型;
④ 定義類,定義其屬性、方法的過程稱為封裝類;
信息隱藏式OOP最重要的功能之一,也是使用訪問修飾符的原因;
信息隱藏的原因包括:
① 對模塊的任何實現細節所作的更改不會影響使用該模塊的代碼;
② 防止用戶意外修改數據;
③ 是模塊易於使用和維護;
訪問修飾符
① public:該類或非該類都均可訪問;
② private:只有該類可以訪問;
③ protected:該類及其子類的成員可以訪問,同一個包中的類也可以訪問;
④ 默認:同一包中的類可以訪問;
屬性封裝的實現
① 修改屬性的可見性來限制對屬性的訪問;
② 為每個屬性創建一對賦值(setter)方法和取值(getter)方法,用於公開對這些屬性的訪問接口;
③ 在setter和getter方法中,根據需要加入對屬性操作的限制;
要點:除非必須公開底層實現細節,否則應該將所有屬性指定為private加以封裝;使用屬性封裝,通過增加數據訪問限制,增強了類的可維護性;
封裝方法的目的
① 隱藏方法實現細節(方法體),向外部提供公開接口(方法頭),以供安全;
② 簡化調用,方便修改維護;
③ 根據需要,可以私有化方法以供類內部使用----幫助方法help;
1 public class TeacherDemo 2 { 3 public static void main(String []agrs){ 4 Teacher t=new Teacher(); 5 //t.name="張三";//不能直接賦值 6 t.setName("張三"); 7 System.out.println(t.getName()); 8 t.setAge(10); 9 System.out.println(t.getAge()); 10 } 11 } 12 13 class Teacher 14 { 15 private String name; 16 private int age; 17 public void setName(String tname){ 18 name=tname; 19 } 20 public String getName(){ 21 return name; 22 } 23 public void setAge(int tage){ 24 if(tage<25) 25 { 26 System.out.println("年齡太小了"); 27 age=25; 28 } 29 else 30 { 31 age=tage; 32 } 33 } 34 public int getAge(){ 35 return age; 36 } 37 } View Code
類的構造方法的概念和作用
① 構造方法負責對象初始化工作,為對象的屬性賦合適的初始值;
② 創建對象時,其類的構造方法確保在用戶操作對象之前,系統保證初始化的進行;
構造方法的語法規則
① 構造方法名與類名相同
② 沒有返回類型
③ 方法實現主要為字段賦初值
構造方法的調用和特別:new操作符(返回新建實例的引用)
無參構造方法
1 public class ConstructorDemo 2 { 3 public static void main(String []agrs){ 4 Person p=new Person();//實例化的時候是有初始值的int默認0,String默認null 5 p.setName("張三"); 6 p.setAge(10); 7 System.out.println(p.toString()); 8 } 9 } 10 11 //當一個類沒有顯示聲明一個構造方法時,系統會有一個默認的無參構造方法 12 class Person 13 { 14 private String name; 15 private int age; 16 private String city; 17 18 //默認的構造方法,實例化時候會調用,此處不寫也可以,系統已默認寫好 19 public Person(){ 20 System.out.println("Person"); 21 } 22 23 24 public void setCity(String pcity){ 25 city =pcity; 26 } 27 public String getCity(){ 28 return city; 29 } 30 31 public void setName(String pname){ 32 name=pname; 33 } 34 public String getName(){ 35 return name; 36 } 37 38 public void setAge(int page){ 39 age=page; 40 } 41 public int getAge(){ 42 return age; 43 } 44 45 public String toString() 46 { 47 return "名字:"+name+",今年"+age+"歲,家住"+city; 48 } 49 } View Code帶參構造方法
1 public class ConstructorDemo 2 { 3 public static void main(String []agrs){ 4 //帶參調用,若不寫參數會報錯,因為Person中只有一個帶參的構造方法 5 Person p=new Person("張三",10,"杭州"); 6 //1、在堆中開辟空間,給屬性分配默認的初始值 7 //2、假設屬性一開始就賦值了,就進行賦值工作 8 //3、調用構造方法對屬性進行初始化 9 System.out.println(p.toString()); 10 } 11 } 12 13 class Person 14 { 15 private String name="李四"; 16 private int age; 17 private String city; 18 19 //帶參數的構造方法 20 public Person(String pname,int page,String pcity ){ 21 name=pname; 22 age=page; 23 city=pcity; 24 } 25 26 public void setCity(String pcity){ 27 city =pcity; 28 } 29 public String getCity(){ 30 return city; 31 } 32 33 public void setName(String pname){ 34 name=pname; 35 } 36 public String getName(){ 37 return name; 38 } 39 40 public void setAge(int page){ 41 age=page; 42 } 43 public int getAge(){ 44 return age; 45 } 46 47 public String toString() 48 { 49 return "名字:"+name+",今年"+age+"歲,家住"+city; 50 } 51 } View Code
this關鍵字
特點:
①在類的方法中使用的this關鍵字代表的是調用此方法的對象的引用;
②this可以看作是一個變量,它的值是當前對象的引用;
③使用this可以處理方法中的成員變量和形參同名的問題;
④當方法內需要用到調用該方法的對象時,就可以用this;
⑤在類的構造方法中可以調用this([參數列表])來調用該類的指定構造方法。
1 public class ConstructorDemo 2 { 3 public static void main(String []agrs){ 4 Person p=new Person("張三",10,"杭州"); 5 System.out.println(p.toString()); 6 } 7 } 8 9 10 class Person 11 { 12 private String name="李四"; 13 private int age; 14 private String city; 15 16 //構造方法 17 public Person(){ 18 System.out.println("無參構造方法"); 19 } 20 21 //帶參數的構造方法 22 public Person(String name,int age,String city ){ 23 24 this();//表示調用當前對象的無參構造方法,必須寫在第一句 25 26 //此處將形參名稱寫成age與屬性名相同 27 //age=age;//此處不會對屬性重新賦值age=0 28 this.age=age;//此處對屬性重新賦值age=10,this代表p 29 this.name=name; 30 this.city=city; 31 32 } 33 34 public void setCity(String city){ 35 this.city=city; 36 } 37 public String getCity(){ 38 return city; 39 } 40 41 public void setName(String name){ 42 this.name=name; 43 } 44 public String getName(){ 45 return name; 46 } 47 48 public void setAge(int age){ 49 this.age=age; 50 } 51 public int getAge(){ 52 return age; 53 } 54 55 public String toString() 56 { 57 //默認前面都是有this的,可寫可不寫 58 System.out.println(this.getAge()); 59 return "名字:"+this.name+",今年"+age+"歲,家住"+city; 60 } 61 } View Code
static關鍵字
特點:
①用來修飾類的成員----修飾成員變量的稱之為類變量(靜態變量),修飾成員方法的稱之為類方法(靜態方法);
②當類被加載時就會被加載,優先於對象的存在;
③用來修飾語句塊----稱之為靜態代碼塊。先於構造方法之前執行,只會執行一次,用來對靜態成員做初始化;
④靜態修飾的成員被所有的對象共享;
⑤調用的時候可以直接通過類名.成員來進行訪問
static關鍵字注意事項
① 靜態方法中只能訪問外部的靜態成員;
② 靜態方法中不能出現this;
非靜態
1 public class StaticDemo 2 { 3 public static void main(String []agrs){ 4 Account acc1=new Account(); 5 acc1.number1++; 6 acc1.showNumber1(); 7 acc1.showNumber2(); 8 9 Account acc2=new Account(); 10 acc2.showNumber1(); 11 acc2.showNumber2(); 12 } 13 } 14 15 class Account 16 { 17 public int number1=1; 18 public int number2=2; 19 public void showNumber1() 20 { 21 System.out.println(number1); 22 } 23 public void showNumber2() 24 { 25 System.out.println(number2); 26 } 27 } View Code靜態1
1 public class StaticDemo 2 { 3 public static void main(String []agrs){ 4 Account acc1=new Account(); 5 acc1.number1++; 6 acc1.showNumber1(); 7 //acc1.showNumber2(); 8 9 10 Account acc2=new Account(); 11 acc2.showNumber1(); 12 //acc2.showNumber2(); 13 } 14 } 15 16 class Account 17 { 18 public static int number1=1;//靜態變量(類變量),它不屬於任何一個對象,被多個對象共享 19 public int number2=2; 20 public void showNumber1() 21 { 22 System.out.println(number1); 23 } 24 public void showNumber2() 25 { 26 System.out.println(number2); 27 } 28 } View Code靜態2
1 public class StaticDemo 2 { 3 public static void main(String []agrs){ 4 Account.number1++; 5 System.out.println(Account.number1); 6 Account.showNumber1(); 7 8 Account acc1=new Account(); 9 acc1.showNumber2(); 10 11 Account acc2=new Account(); 12 acc2.showNumber2(); 13 } 14 } 15 16 class Account 17 { 18 public static int number1=1;//靜態變量(類變量),它不屬於任何一個對象,被多個對象共享 19 public int number2=2; 20 //靜態方法中不能使用非靜態的變量 21 //靜態方法中不能使用this 22 public static void showNumber1() 23 { 24 //showNumber2();//報錯 25 System.out.println(number1); 26 //System.out.println(this.number2);//報錯 27 } 28 29 //非靜態的方法可以訪問靜態的內容和非靜態的屬性和方法 30 public void showNumber2() 31 { 32 showNumber1(); 33 System.out.println(number2); 34 System.out.println("非靜態方法訪問靜態變量:"+number1); 35 } 36 37 //構造方法 38 public Account(){ 39 System.out.println("constructor"); 40 } 41 42 //static語句塊 43 //在類被加載時就會執行,只會執行一次,用來對靜態的變量賦值 44 //優先於構造方法執行 45 static{ 46 System.out.println("static"); 47 number1=100; 48 } 49 } View Code
方法重載
多數程序設計語言要求為每個方法(函數)提供一個獨一無二的方法名,不存在方法重載的概念
在Java中,規定方法簽名是解析方法的規則而不是方法名,為方法重載開創了條件
方法重載使得在一個類中,方法名相同而參數列表不同的方法可同時存在,代表相似的行為和功能
重載overload概念:同一類中,同名不同參的方法稱為重載方法
注意:僅有返回類型不同的方法不能稱為重載,即方法重載必須方法簽名不同
1 public class OverloadDemo{ 2 public static void main(String []agrs){ 3 Printer p=new Printer(2000); 4 p.print("hello"); 5 p.print(10); 6 p.print("hello",10); 7 } 8 } 9 10 class Printer{ 11 private String brand="聯想"; 12 private double price; 13 14 public Printer(double price){ 15 this.price=price; 16 } 17 18 public Printer(String brand,double price){ 19 this.brand=brand; 20 this.price=price; 21 } 22 23 public void print(String content){ 24 System.out.println("字符串"+content); 25 } 26 27 public void print(int content){ 28 System.out.println("整型"+content); 29 } 30 31 public void print(String str,int content){ 32 System.out.println(str+"--"+content); 33 } 34 35 public int print(int content,double d){ 36 return content; 37 } 38 } View Code