第一節:方法的引數傳遞、返回值
Java語言在給被呼叫方法的引數賦值時,採用傳值的方式:
- 基本型別資料傳遞的是該資料的值本身。
- 引用型別資料傳遞的也是這個變數的值本身,即物件的地址(引用),而非物件本身。
1.1 基本資料型別傳遞
//類
public class PassValue{
public void change(int x){
x = 100;
System.out.println("方法中x==" + x);
}
}
//類
public class Test{
public static void main(String[] args){
PassValue pv = new PassValue();
int x = 5;
System.out.println("方法呼叫之前x=="+ x);
pv.change(x);
System.out.println("方法呼叫之後x==" + x);
}
}
1.2 引用資料型別傳遞
陣列、類、String(比較特殊特點:和基本型別一樣)
public class PassValue2{
int x ;
public void change(PassValue2 obj){
obj.x = 100;
System.out.println(“方法中obj.x==” + obj.x);
}
}
public class Test{
public static void main(String[] args){
PassValue2 p = new PassValue2();
p.x = 5;
System.out.println(“方法呼叫之前p.x==” + p.x);
p.change(p);
System.out.println(“方法呼叫之後p.x==” + p.x);
}
}
1.3基本型別和引用型別作為方法的返回值
基本型別返回的實際資料
引用型別返回的是物件的地址
第二節:封裝性
Java語言有三大特徵:
- 封裝(encapsulation):對外部不可見,隱藏物件的屬性和實現細節。
- 繼承(inheritance):一個類繼承另一個類的成員。
- 多型(Polymorphism):每個物件表現的多樣性。
1.1 封裝的概念
什麼是封裝:在類中,對於不想被類外直接訪問的成員變數,進行私有化,同時對外提供一個公有的方法訪問私有的成員。
封裝成員變數兩個步驟:
第一步: 新增private 修飾符
第二步: 新增get和set方法
1.2 private
使用private訪問許可權實現成員變數的私有化,private修飾的成員變數就是私有成員變數,只能在類內部直接訪問,類外不能直接訪問
1.3 get和set方法
get方法表示訪問私有屬性的方法:
語法:
public 屬性型別 getXxx(){ return 屬性; }
set方法表示修改私有屬性的值的方法:
public void setXxx(引數型別 引數){ this.xxx = 引數; }
/**
* 人類
* 屬性: 姓名 年齡 性別
* 方法: eat study
*
* 封裝:(1)把成員變數變成私有的 (2) 新增get和set方法
* @author wgy
*
*/
public class Person {
private String name;
private int age;
private String sex;
public String getName() {
return name;
}
public void setName(String name) {
this.name=name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
if(age>100||age<1) {
this.age=18;
}else {
this.age=age;
}
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
if(sex.equals("男")||sex.equals("女")) {
this.sex=sex;
}else {
this.sex="男";
}
}
public void eat() {
System.out.println(name+"開始吃飯...");
}
public void study() {
System.out.println(name+"開始努力學習...");
}
public void show() {
System.out.println("姓名:"+name+" 年齡:"+age+" 性別:"+sex);
}
}
1.4 類設計原則
- 成員變數(屬性)私有化(用private修飾),新增get和set方法
- 公開方法(用public修飾)
第三節:static關鍵字
static關鍵字可以修飾類成員:修飾成員變數、方法、程式碼塊、內部類等。
2.1 靜態屬性
所有本類物件所共有且相同的一個屬性,是類的公用變數,不會隨著物件的改變而改變的屬性。例如:圓周率。靜態屬性先於物件,不依賴於物件,可以直接通過類名直接訪問(類名.屬性名)。
public class Person{
String name;
int age;
//人口總數
static int totalCount = 1300000000;
}
public class DemoPerson{
public static void main(String[]args){
System.out.println(Person.totalCount);//Person類中的totalCount屬性是一個靜態屬性,可以直接通過類名訪問
}
}
2.2 靜態方法
所有本類物件所共有且相同的一個公共方法,屬於類方法,先於物件的方法,不依賴於物件,可以直接通過類名直接呼叫(類名.方法名())。
public class Person{
static int totalCount;
public static void calcTotalCount(){
System.out.println("統計人口方法");
totalCount=1350000000;
}
}
public class DemoPerson{
public static void main(String[]args){
Person.calcTotalCount();
}
}
靜態屬性和方法使用原則:
1如果這個變數或方法,不屬於每個物件,屬於整個類,就用靜態
2如果這個類是共用的,那麼類中的屬性和方法都用靜態,一般工具類中的方法都是靜態的,
如Arrays.方法名()
使用注意事項:
1 靜態方法中可以直接訪問靜態變數,不能直接訪問非靜態變數。
2 非靜態方法中可以直接訪問靜態變數和靜態方法。
3 靜態變數存在方法區中靜態域中
2.3 靜態程式碼塊
程式碼塊分為:區域性程式碼塊、動態程式碼塊、靜態程式碼塊
區域性程式碼塊:宣告在方法中的程式碼塊,使用範圍與宣告位置相關, 提前釋放變數。(瞭解)
動態程式碼塊:又稱構造程式碼塊或例項程式碼塊,宣告在類體中的程式碼塊,建立物件時自動執行一次,每建立一個物件就執行一次動態程式碼塊,初始化物件。(瞭解)
靜態程式碼塊:使用static關鍵字修飾的動態程式碼塊,在類載入時自動執行,並只執行一次,初始化類(記住)
2.4 靜態匯入(瞭解)
用import static代替import,靜態匯入包是JDK1.5中的新特性。
一般我們匯入一個類都用:import com...ClassName;而靜態匯入是這樣:import static com...ClassName.* ;這裡的多了個static,還有就是類名ClassName後面多了個.* ,意思是匯入這個類裡的靜態方法和屬性。
靜態匯入前
public class Demo {
public static void main(String [] args){
System.out.println(Integer.MAX_VALUE);
System.out.println(Integer.toHexString(36));
}
}
靜態匯入後
import static java.lang.System.out;
import static java.lang.Integer.*;
public class Demo {
public static void main(String [] args){
out.println(MAX_VALUE);
out.println(toHexString(36));
}
}
這種方法建議在有很多重複呼叫的時候使用,如果僅有一到兩次呼叫,不如直接寫方便。
第四節:繼承性
4.1 繼承的概念
在原有類的基礎上,產生一個新的類,在新的類中可以訪問原有類中的非私有成員,並且可以新增一些自己獨有的成員,這個過程叫做繼承,簡單理解一個類繼承另外一個類。
4.2 繼承的好處
-
實現程式碼的重用和擴充套件
-
模擬現實世界的關係
4.3 類的繼承的使用
使用extends關鍵實現兩個類的繼承關係
被繼承的類:父類,超類,基類
繼承的類:子類,派生類
繼承符合: is a 關係
4.4 語法:
public class FatherClass{
//屬性
//方法
}
public class ChildClass extends FatherClass {
//屬性
//方法
}
編寫Person類:
屬性有:姓名、年齡,出生日期
方法有:showInfo();
編寫Student類:
屬性有:姓名、年齡,出生日期、學校
方法有:showInfo();
study();
使用繼承優化Student類。
public class Person {
String name;
int age;
String birthday;
public void showInfo() {
System.out.println("姓名:"+name+" 年齡:"+age+" 出生日期:"+birthday);
}
}
public class Student extends Person{
String school;
public void study() {
System.out.println(name+"好好學習天天向上");
}
}
編寫動物類 (名字、顏色、品種),列印方法,編寫狗狗類(親密度)和貓類(愛好)繼承動物類,狗狗類和貓類都有列印資訊的功能,狗狗有看家方法,貓類有玩球方法。
Animal類
/**
* 動物類
* (名字、顏色、品種),列印方法
* @author wgy
*
*/
public class Animal {
//暱稱
String name;
//顏色
String color;
//品種
String strain;
//列印資訊
public void print() {
System.out.println("動物資訊: 暱稱:"+name+" 顏色:"+color+" 品種:"+strain) ;
}
}
Dog類
/**
* 狗狗類
* @author wgy
*
*/
public class Dog extends Animal{
//親密度
int love;
public void lookHome() {
System.out.println(name+" 正在給主人看家...........");
}
}
Cat類
/**
* 貓類
* @author wgy
*
*/
public class Cat extends Animal{
//愛好
String hobby;
/**
* 玩球
*
*/
public void playBall() {
System.out.println(name+"正在玩球..........");
}
}
4.5 子類物件例項化過程
- 1 先例項化父類物件
- 預設呼叫父類預設構造方法
- 2 再例項化子類物件
4.6 不能被子類繼承的成員:
1)私有成員:私有成員不能被子類繼承
2)構造方法:父類中的構造方法不能被子類繼承,但是會在子類的構造方法中呼叫(子類的構造方法中預設第一條語句是呼叫父類的預設構造方法)
4.7 繼承的特點
1)單繼承:一個子類只能有一個父類,一個父類可以有多個子類
2)傳遞性:繼承具有傳遞性
第五節:super關鍵字
5.1 super關鍵字:用法和this類似
this 表示當前物件的引用。
this用法:
用法1:呼叫本類的屬性,可以解決成員變數名和區域性變數名同名問題。
this.屬性名
用法2:呼叫本類的方法
this.方法名
用法3 :呼叫本類中其他的構造方法。
this(引數);
注意:1只能用在構造方法中,必須是第一條語句
2只能呼叫一次
5.2 super的概念
super表示當前父類物件的引用。
5.3 super的使用規則
1)super.屬性:表示訪問父類中的屬性,當子類中定義了與父類同名的屬性時,若想在子類中訪問父類的同名屬性,需要使用super.屬性訪問
2)super.方法:表示呼叫父類中的方法,在子類中需要呼叫父類中沒有被重寫的方法時,需要使用super.方法呼叫
3)super():表示呼叫父類的構造方法,注意:super()必須是子類構造方法中第一條語句
子類中構造方法預設第一條語句會呼叫父類的無引數構造方法super(),也可以手動呼叫父類中帶引數的構造方法
5.4 練習
public class Animal {
//屬性
String nickname;
String color;
String strain;
//預設構造方法
public Animal() {
System.out.println("父類Animal的構造方法執行了..........");
}
//帶參構造方法()
public Animal(String nickname,String color,String strain) {
this.nickname=nickname;
this.color=color;
this.strain=strain;
}
//列印方法
public void print() {
System.out.println("本動物 暱稱:"+nickname+" 顏色:"+color+" 品種:"+strain);
}
}
public class Dog extends Animal{
int love;
//預設構造方法
public Dog() {
super();//呼叫父類的預設構造方法
System.out.println("Dog子類的構造方法執行了");
}
//帶參構造方法
public Dog(String nickname,String color,String strain,int love) {
super(nickname, color, strain);//呼叫父類的帶參構造
this.love=love;
}
public void lookHome() {
System.out.println(nickname+"正在給主人看家....");
System.out.println("暱稱:"+super.nickname);
System.out.println("顏色:"+super.color);
System.out.println("品種:"+super.strain);
System.out.println("親密度:"+this.love);
super.print();
}
}
public class Test {
public static void main(String[] args) {
Dog afu=new Dog();
afu.nickname="阿福";
afu.color="黑色";
afu.strain="哈士奇";
afu.love=100;
afu.lookHome();
System.out.println("----------------------------------------");
//呼叫Dog的帶參構造
Dog xiaohei=new Dog("小黑", "白色", "泰迪", 100);
xiaohei.lookHome();
}
}
this和super的區別:
(1) this表示當前物件的引用,super表示當前父類物件的引用
(2) this.屬性可以呼叫當前物件的屬性包括繼承的屬性,super.屬性可以呼叫父類的屬性
(3) this.方法() 可以呼叫當前物件的方法包括繼承的方法,super.方法()可以呼叫父類的方法
(4) this(引數) 呼叫本類中其他的構造方法,super(引數) 呼叫父類的構造方法
(5) this(引數)和super(引數)只能用在構造方法中,必須是第一條語句,只能呼叫一次,不能同時使用。
第六節:包和訪問許可權
為了便於管理大型軟體系統中數目眾多的類,解決類命名衝突的問題,Java引入了包(package)。
在使用許多類時,類和方法的名稱很難決定。有時需要使用與其他類相同的名稱。包基本上隱藏了類並避免了名稱上的衝突。
- 用package來宣告包,package語句必須是java原始檔中的第一條語句。(若無這條語句,則放置在無名包下)
- 在package語句中,用"."來指明包(目錄)的層次。包對應著檔案系統的目錄層次結構。
- 一般使用公司或組織的域名的倒置+專案名或模組名來表示包名。
- www.baidu.com 包名 com.baidu.oa
- www.alibaba.com 包名 com.alibaba.pay
6.1 建立包
public class Employee {
private String name; //姓名
private int age; //年齡
private double salary; //薪水
public Employee(){
}
public Employee(String name, int age, double salary){ //構造方法
this.name = name;
this.age = age;
this.salary = salary;
}
//getter和setter省略
}
6.2 匯入包
為使用定義在不同包中的Java類,需要import語句來引入所需要的類。
語法格式:
import package1[.package2…].類名
public class PackageDemo {
public static void main(String args[]){
Employee employee = new Employee();
}
}
注意:
要匯入某個包中的所有類可以用:包名.*
例如:import java.util.*;
在同一包中的類可以直接互相引用,無需import語句。
6.2 訪問許可權
許可權\使用範圍 | 本類 | 同包中類或同包子類 | 不同包子類 | 不同包類 |
---|---|---|---|---|
public | v | v | v | v |
protected | v | v | v | x |
預設[default] | v | v | x | x |
private | v | x | x | x |
package a;
public class Person{
public String name;
protected int age;
char sex;
private double sal;
public Person(){}
public Person(String name, int age, char sex, double sal){
this.name = name;
this.age = age;
this.sex = sex;
this.sal = sal;
}
public static void main(String[]args){
Person p = new Person("張三", 12, 'm', 5000);
System.out.println(p.name);
System.out.println(p.age);
System.out.println(p.sex);
System.out.println(p.sal);
}
}
package a;
public class Student extends Person{
public static void main(String[]args){
Person p = new Person("張三", 12, 'm', 5000);
System.out.println(p.name);
System.out.println(p.age);
System.out.println(p.sex);
//System.out.println(p.sal);//同包子類中無法訪問父類中私有成員
}
}
package a;
public class Demo{
public static void main(String[]args){
Person p = new Person("張三", 12, 'm', 5000);
System.out.println(p.name);
System.out.println(p.age);
System.out.println(p.sex);
//System.out.println(p.sal);//同包類中無法訪問父類中私有成員
}
}
package b;
public class Student extends Person{
public static void main(String[]args){
Person p = new Person("張三", 12, 'm', 5000);
System.out.println(p.name);
System.out.println(p.age);
//System.out.println(p.sex);//不同包中子類中無法訪問預設許可權成員
//System.out.println(p.sal);
}
}
package b;
public class Demo{
public static void main(String[]args){
Person p = new Person("張三", 12, 'm', 5000);
System.out.println(p.name);
//System.out.println(p.age);//不同包中不能訪問受保護屬性
//System.out.println(p.sex);
//System.out.println(p.sal);//不同包類中無法訪問父類中私有成員
}
}
使用原則:
- 修飾類時:只能public 或 預設的
- 修飾成員變數和方法:可以使用public 、預設、protected 、private
- 區域性變數不能訪問許可權修飾符。
第七節:方法重寫
方法過載(overload):
1 同一個類中,方法名相同,引數列表不同(個數不同,型別不同,順序不同)
2 和返回值,訪問修飾符無關。
7.1 方法重寫
在繼承過程中,子類中從父類繼承來的方法無法滿足自己的需求時,可以在子類中對父類方法進行完善,這個完善過程叫做方法重寫(override),方法的重寫相當於在子類中覆蓋父類中的方法。
案例:
public class Animal {
//屬性
String nickname;
String color;
String strain;
//預設構造方法
public Animal() {
System.out.println("父類Animal的構造方法執行了..........");
}
//帶參構造方法()
public Animal(String nickname,String color,String strain) {
this.nickname=nickname;
this.color=color;
this.strain=strain;
}
//列印方法
protected Object printInfo() {
System.out.println("本動物 暱稱:"+nickname+" 顏色:"+color+" 品種:"+strain);
return 10;
}
}
public class Dog extends Animal{
int love;
//預設構造方法
public Dog() {
super();//呼叫父類的預設構造方法
System.out.println("Dog子類的構造方法執行了");
}
//帶參構造方法
public Dog(String nickname,String color,String strain,int love) {
super(nickname, color, strain);//呼叫父類的帶參構造
this.love=love;
}
/**
* 看家
*/
public void lookHome() {
System.out.println(nickname+"正在給主人看家....");
}
/**
* 重寫 :覆蓋
* 1 方法名相同
* 2 方法引數 返回值型別必須相同
* 3 訪問修飾符不能比父類嚴格
*
* java特殊 1.7 返回值 可以和父類相容就可以,必須是引用型別
*/
public String printInfo() {
System.out.println("狗狗資訊:暱稱:"+super.nickname+" 顏色:"+super.color+" 品種:"+super.strain+" 親密度:"+this.love);
return "haha";
}
}
7.2 方法重寫規則
訪問許可權 其他修飾符 返回值 方法名(引數列表)
- 1 在繼承過程中,方法名、引數列表、返回值型別必須和父類相同
- 2 訪問修飾符不能比父類嚴格
java特殊 1.7 返回值可以和父類相容就可以,必須是引用型別
7.3 方法的重寫和方法的過載的區別
方法的過載:Overload,在同一個類中,方法名相同,引數類別不同,互為過載方法。
方法的重寫:Override,在繼承過程中,在子類中重寫父類中繼承來的方法,方法名、引數列表、返回值必須相同,訪問許可權不能比父類嚴格。
7.4 有關方法重寫之後的呼叫:
只要在子類中重寫了父類的方法,通過子類物件呼叫該方法一定是子類重寫的方法。