天天看點

封裝繼承

第一節:方法的參數傳遞、傳回值

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 = 參數;
}
           
package com.qf.day09_4;
/**
 * 人類
 * 	屬性: 姓名 年齡 性别
 *  方法: 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類

package com.qf.day09_2;
/**
 * 動物類 
 *  (名字、顔色、品種),列印方法
 * @author wgy
 *
 */
public class Animal {
	//昵稱
	String name;
	//顔色
	String color;
	//品種
	String strain;
	
	//列印資訊
	public void print() {
		System.out.println("動物資訊: 昵稱:"+name+" 顔色:"+color+" 品種:"+strain) ;
	}
}
           

Dog類

package com.qf.day09_2;
/**
 * 狗狗類
 * @author wgy
 *
 */
public class Dog extends Animal{
	//親密度
	int love;
	

	
	public void lookHome() {
		System.out.println(name+" 正在給主人看家...........");
	}
	
}
           

Cat類

package com.qf.day09_2;
/**
 * 貓類
 * @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 建立包
package com.qf.test;

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…].類名

import com.qf.test.Employee;

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 有關方法重寫之後的調用:

​ 隻要在子類中重寫了父類的方法,通過子類對象調用該方法一定是子類重寫的方法。