1.封裝Encapsulation:隱藏(private)對象的屬性和實現細節(方法),僅對外提供公共訪問方式。
對外開發,不安全,導致一些不合理的賦值。
僅私有化,訪問不了。
折中,對外提供公共訪問方式:通過函數對屬性可控
class Person
{
//private: 私有,是一個權限修飾符,用於修身成員,修飾不了局部。
// 私有的內容只有在本類中有效
//注意:私有隻有封裝的一種體現而已。只要保證訪問不到,就是封裝。
//私有是封裝,封裝不是私有
private int age;
public void setAge(int a)
{
if(a>0) //在函數中進行判斷,保證數據正確性
age = a;
else
System.out.println("數據錯誤!"); //異常處理
}
public int getAge() //1個成員變量對應2個方法setXX(),getXX(),10個對應20個方法。寫死你。但是IDE有快捷鍵可以一鍵生成
{
return age;
}
void speak()
{
System.out.println("age = " + getAge());
}
}
class Encapsulation
{
public static void main(String[] args)
{
Person p = new Person();
p.setAge(-1);
p.speak();
p.setAge(21);
p.speak();
}
}
2.封裝思想:
舉例:
不封裝相當於主機無機箱裸奔,存在不安全因素。
用機箱裝好後,使用機箱對外提供的按鈕來控制主機,安全性提高。
筆記本就是一個封裝體。
Java最小的封裝體就是函數。
類也是封裝體。
框架也是封裝體。
封裝好處:
1.數據安全性提高
2.提高了複用性。
3.隔離變化。
4.隱藏細節,便於使用。
封裝原則:
1.將不需要對外提供的內容都隱藏起來(屬性和方法)
2.把屬性都隱藏起來,提供公共方法對其訪問
注意:
私有隻有封裝的一種體現而已。只要保證訪問不到,就是封裝。
私有是封裝,封裝不是私有。
3.構造函數:
特點:
1.函數名和類名相同。
2.不用定義返回值類型。
3.沒有具體的返回值。
作用:
1.構建創造對象時調用的函數,可以給對象進行初始化。
2.創建對象都必須要通過構造函數初始化。
一個類中如果沒有定義過構造函數,那麼類中會有一個默認的空參數構造函數;
如果在類中定義了指定的構造函數,那麼類中的默認構造函數就不默認添加了。
class Person
{
private int age;
private String name;
Person() //可以帶參數,可以重載
{
age = 21; //初始化
System.out.println("Persion run");
}
Person(String name, int age) //重載
{
this.name = name;
this.age = age;
}
}
Person p = new Person(); // Persion run
Person p1 = new Person("小明");
一般函數和構造函數有什麼區別:
構造函數:對象創建時,就會調用與之對應的構造函數,對對象進行初始化。一個對象只能調用一次。
一般函數:對象創造後,需要函數功能時才調用。一個對象可以調用多次。
什麼時候定義構造函數:
在描述事物時,該事務已存在就具備的一些內容,這些內容都是定義在構造函數中。
4.構造函數的重載:
定義:在同一個類中,允許存在一個以上的同名函數,只要它們的參數個數 或者 參數類型不同即可。
特點:與返回值類型無關,只看參數列表(參數順序也考慮)。
構造函數可以有多個,用於對不同的對象進行針對性的初始化。
多個構造函數在類中以重載的形式來體現。
5.構造函數內存圖解:構造函數要進棧。
Person p2 = new Person(“小強”,10);
p2.speak();
6.構造函數細節:
1.三種初始化方式:構造函數,構造函數重載,setget函數。
2.構造函數可以調用其它函數。其他函數不能直接調用構造函數,構造函數是對象初始化調用的。
3.構造函數沒有返回值類型,void也不能寫。構造函數和類名相同首字母大寫,其他函數首字母小寫。
4.如果定義了構造函數,那麼默認的Person()就沒有了。
5.構造函數最後一行默認有return; 可以自行添加控制。
7.關鍵字this:代表當前對象,
this就是所在函數所屬對象的引用。
簡單說,哪個對象調用了this所在的函數,this就代表了哪個對象。
1.this應用1:當成員變量和局部變量重名時,可以用this區分。
private String name;
Person(String name) //構造函數
{
name = name; //這裏都是棧的局部變量name
this.name = name//這裏左邊是對象的在堆裏的name,右邊是構造函數的局部變量name。當局部變量和成員變量同名時,可以用this來區分。
}
Person p = new Person();
此時,this代表的 new Person()對象的引用,相當於p,但是不是p,因爲對象在初始化的時候,還沒有把地址給p。
當函數裏面沒有定義參數,或者參數沒有與成員變量重名,那麼this可以省略,java默認添加。
(this.)name = n;
8.this另一種應用:
一個類當中所有的成員,只要想運行,都必須要用對象調用,this大多數情況被省略了。
構造函數調用構造函數,代碼重用:this(參數);
Person(String name)
{
this.name =a name;
}
Person(String name ,int age)
{
this(name); //不能寫this.Person(name),因爲Person(String name)是方法,而此時this對象還沒有被初始化,不能調用方法。而且必須寫在第一行。
this.age = age;
}
細節:
1.當構造函數調用了其他初始化構造函數的語句,必須寫在第一行。因爲初始化動作要先執行,後來數據爲主放在後面,以免用戶的數據被覆蓋。
2.避免構造函數相互來回調用,會導致棧溢出,沒有出棧,一直進棧。
9.this應用:只要在本類中用到了本類的對象,通常都用this。
例子:
/*
判斷是否是同齡人
*/
class Person
{
private String name;
private int age;
Person(String name, int age)
{
this.name = name;
this.age = age;
}
boolean compare(Person p)
{
if(this.age == p.age)//if(age ==p.age)也是可以的,因爲這裏this默認添加,可以省略。但是閱讀性不好。
return true;
else
return false;
// 簡寫:return this.age == p.age;
}
}
class Demo
{
public static void main(String[] args)
{
Person p1 = new Person("張三",21);
Person p2 = new Person("王五",23);
System.out.println(p1.compare(p2));
}
}