一、面向對象的三大特徵
1、封裝
- 對外部不可見
2、繼承
- 拓展類的功能
3、多態
- 方法的重載
- 對象的多態
二、類的定義
類定義完成之後,需要創建並實例化對象才能使用。
示例:
三、聲明並實例化對象
1、聲明並實例化單個對象:
對象保存在棧內存之中,屬性保存在堆內存之中,方法則是保存在全局代碼區,此代碼區是所有對象共享的。
Person per = new Person();
- 聲明對象: Person per ,是在棧內存中聲明的,和數組名稱一樣,必須要有其堆內存的引用纔可以使用
- 實例化對象: new Person(),是在堆內存中開闢空間,並賦默認值。
或者這樣聲明並實例化對象:
Person per = null;
per = new Person();
示例:
class Person{
String name;
int age;
public void tell(){
System.out.println("姓名:"+ name + ",年齡:" + age);
}
};
public class demo {
public static void main(String args[]) {
Person per = new Person();//聲明並實例化對象per
per.name = "龐先生";//給per對象賦值
per.age = 22;
per.tell();
}
}
如果只聲明瞭對象,而沒有實例化,即對象沒有其堆內存的空間指向(指針),會報錯:
Exception in thread “main” java.lang.NullPointerException
at demo.main(demo.java:13)
出現了一個空指向異常
2、聲明並實例化多個對象:
public class demo {
public static void main(String args[]) {
Person per1 = new Person();//聲明並實例化對象
Person per2 = new Person();//聲明並實例化對象
per1.name = "龐先生";
per2.name = "黃先生";
per1.age = 22;
per2.age = 21;
per1.tell();//調用per1對象的tell方法
per2.tell();//調用per2對象的tell方法
}
}
對象的引用傳遞:
3、棧與堆內存的關係
情況一:對象的引用傳遞
public class demo {
public static void main(String args[]) {
Person per1 = new Person();//聲明並實例化對象
Person per2 = per1;//引用per1的對象,把per1的堆內存空間使用權給per2
per1.name = "龐先生";//初始化per1對象的屬性
per1.age = 22;
per1.tell();
per2.name = "黃先生";//利用per2對象修改per1的屬性
per2.age = 21;
per1.tell();//還是調用per1對象方法,看per1的屬性是否被per2改動
}
}
per1和per2對象都指向同一個堆內存空間,並不會爲per2多分配一個內存空間。
情況二:重新指向另一對象
public class demo {
public static void main(String args[]) {
Person per1 = new Person();//聲明並實例化對象
Person per2 = new Person();
per1.name = "龐先生";//初始化per1對象的屬性
per1.age = 22;
per2.name = "黃先生";
per2.age = 21;
per1.tell();
per2.tell();
per2 = per1;//改變per2對象的堆內存空間指向,指向per1的空間。
System.out.println("修改後:");
per1.tell();//調用per2對象方法,看per2的屬性是否和per1一樣
per2.tell();
}
}
四、Java的封裝
封裝就是保護內容保護某些方法或屬性不被暴露在外面。
使用private 類聲明私有方法或私有屬性
封裝類的屬性
class Person{
private String name;
private int age;
public void tell(){
System.out.println("姓名:"+ name + ",年齡:" + age);
}
};
訪問封裝內容
被封裝屬性如果需要被訪問,可以自定義set…方法和get…方法,並且爲set、get方法設置參數過濾
class Person{
private String name;
private int age;
public void tell(){
System.out.println("姓名:"+ name + ",年齡:" + age);
}
//設置名字方法
public void setName(String str) {
if (str.length()<10) {
name = str;
}else {
System.out.println("名字過長");
}
}
//取得名字方法
public String getName() {
return name;
}
//設置年齡方法
public void setAge(int n) {
if (n>0&&n<100) {
age = n ;
}else {
System.out.println("年齡不符合要求");
}
}
//取得年齡方法
public int getAge() {
return age;
}
};
public class demo {
public static void main(String args[]) {
Person per1 = new Person();//聲明並實例化對象
per1.setName("龐先生");
per1.setAge(22);
int age = per1.getAge();
String name = per1.getName();
System.out.println("姓名:"+name+",年齡:"+age);
}
}
五、構造方法
對象實例化→調用構造方法
構造方法的目的是爲類中的屬性初始化。
當類中沒有自定義的構造方法時,將會自動創建一個默認的無參的構造方法。
1、定義構造方法
- 構造方法的名稱必須與類名稱一直
- 構造方法的聲明不能有任何返回值的定義(包括void都不行,直接就public 類名稱() )
- 不能在構造方法中使用return返回一個值
class Person{
private String name;
private int age;
public Person(String str, int a) { //聲明構造方法,傳遞參數爲類的屬性初始化
this.setName(str);
this.setAge(a);
}
public void setName(String str) {
if (str.length()<10) {
name = str;
}else {
System.out.println("名字過長");
}
}
public String getName() {
return name;
}
public void setAge(int n) {
if (n>0&&n<100) {
age = n ;
}else {
System.out.println("年齡不符合要求");
}
}
public int getAge() {
return age;
}
};
public class demo {
public static void main(String args[]) {
Person per1 = new Person("龐先生",22); //實例化對象並且賦初始值
//per1.setName("龐先生"); //原來的使用封裝方法賦值
//per1.setAge(22);
String name = per1.getName();
int age = per1.getAge();
System.out.println("姓名:"+name+",年齡:"+age);
}
}
2、構造方法的重載:
public Person() {}; //聲明一個無參的構造方法
public Person(String str) { //聲明一個只有一個參數的構造方法
this.setName(str);
};
public Person(String str, int a) { //聲明構造方法,傳遞參數爲類的屬性初始化
this.setName(str);
this.setAge(a);
}
3、匿名對象:
如果一個對象只使用一次,則可以使用匿名對象。
也就是說可以聲明一個沒有名字的對象指向堆內存,即不開闢棧內存空間存放對象名,僅開闢一個堆內存空間存放對象的屬性。
public static void main(String args[]) {
new Person("龐先生",22).tell();
//Person per1 = new Person("龐先生",22); //實例化對象並且賦初始值
//per1.setName("龐先生"); //原來的使用封裝方法賦值
//per1.setAge(22);
//String name = per1.getName();
//int age = per1.getAge();
//System.out.println("姓名:"+name+",年齡:"+age);
}
六、類分析設計
對於任何一個程序,對類分析思路的步驟:
- 根據要求寫出類所包含的屬性
- 所有的屬性都必須進行封裝(private)
- 封裝之後的屬性通過setter和getter設置和取得
- 如果需要可以加入不同參數的構造方法進行重載
- 添加所需的自定義方法
- 類中的方法不能直接輸出,而是要交給被調用處輸出
設計出類圖:
按照類圖構造代碼