【Java基礎】2020.01.06類之間的關係

1.繼承

1、被繼承的類叫父類或超類(subclass),繼承父類的類叫子類或派生類(derived class);

2、子類繼承了父類中定義的所有實例變量和方法,並且增加了獨特的元素;

3、在Java中,使用extends體現繼承關係,其名緊跟父類的類名;

4、可以實現:泛化父類維護共性,細化子類添加特性;

5、Java只支持單一繼承,即只能繼承一個父類,但可通過接口實現多繼承;

6、缺省的自動繼承java.lang.Object類,Object類是所有類的頂級父類;

7、子類擁有父類定義的所有屬性和方法。但父類可以通過“封裝”的思想隱藏某些數據;

8、構造子類實例時,先調用父類的構造方法,然後調用子類的構造方法,兩個構造方法都執行。

9、例子:

父類

package com.hyg.ext;
/**
package com.hyg.ext;
/**
 * 父類,屬性公有
 * @author 15332
 *
 */
public class Person {
	public String name;//姓名
	public int age;//年齡
	public String gender;//性別
	
	//父類構造方法
	public Person(){
		System.out.println("這是父類的構造方法!");
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String getGender() {
		return gender;
	}
	public void setGender(String gender) {
		this.gender = gender;
	}
	
}


子類:

package com.hyg.ext;
/**
 * 子類,派生類
 * @author 15332
 *
 */
public class Student extends Person {
	private double score;//成績
	private String grade;//年級
	//子類構造方法
	public Student(){
		System.out.println("這是子類的構造方法!");
	}
	public double getScore() {
		return score;
	}
	public void setScore(double score) {
		this.score = score;
	}
	public String getGrade() {
		return grade;
	}
	public void setGrade(String grade) {
		this.grade = grade;
	}
	
}


測試:

package com.hyg.ext;
/**
 * 測試繼承關係
 * @author 15332
 *
 */
public class TestDemo {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Student student = new Student();//創建子類對象
		student.setName("高和超");//子類可以調用父類的方法
		System.out.println(student.getName());
		student.setScore(56.56);//子類屬性是私有的,只能通過get、set方法訪問
		System.out.println(student.getScore());
		Person person = new Person();//創建父類對象,父類只能訪問自己的屬性和方法
		person.setName("父類");
		System.out.println(person.getName());
		person.age = 18;//父類的公有屬性,可以直接賦值
		System.out.println(person.age);
		
	}
}

2.多態

重寫

1、子類對父類的方法進行改造,這稱爲方法的重寫(override),重寫是Java多態性的一種體現。

2、多態存在的三個必要條件:

繼承、重寫、父類引用指向子類對象

3、遵循規則:

① 方法簽名(方法名和參數列表)必須完全相同;
② 子類方法的返回值類型可以與父類方法返回值類型相同,或是子類;
③ 子類方法聲明的異常可以與父類方法聲明的異常相同,或是其子類;
④ 父類中的私有方法不能被重寫,否在在子類中只是新定義了一個方法,而與父類中的方法無關。
⑤ 子類方法的可訪問性可以和父類方法的可訪問性相同,或者是更公開。
⑥ 靜態方法不 存在重寫的概念。
⑦ 對象可以調用子類重寫之後的犯法,對於子類改寫的方法,是無法訪問的。

4、 解釋

① 父類可以引用子類重寫的方法。
② 父類不能引用子類改寫的方法。

5、例子

Animal類

package com.hyg.override;
/**
 * 父類
 * @author 15332
 *
 */
public class Animal {
	public String name;//名字
	/**
	 * 睡覺
	 */
	public void sleep(){
		System.out.println("睡覺!");
	}
	/**
	 * 喫飯
	 */
	public void eat(){
		System.out.println("喫飯!");
	}
	public void func1(){
		System.out.println("animal中的func1");
	}
	
}

Fish類

package com.hyg.override;
/**
 * 子類:魚類
 * @author 15332
 *
 */
public class Fish extends Animal {
	public void sleep(){
		System.out.println("魚要睜着眼睛睡覺!");
	}
	
	@Override
	public void eat() {
		System.out.println("魚要喫蝦米!");
	}
	public void func1(){
		System.out.println("fish中的func1");
	}
}


Horse類

package com.hyg.override;
/**
 * 子類:馬類
 * @author 15332
 *
 */
public class Horse extends Animal{
	public void sleep(){
		System.out.println("馬要站着睡覺!");
	}
	
	@Override
	public void eat() {
		System.out.println("馬喫草!");
	}
}


TestDemo類

package com.hyg.override;

public class TestDemo {
	public static void main(String[] args) {
		Animal animal =  new Animal();
		animal.sleep();
		animal.eat();
		
		Animal horse = new Horse();
		horse.sleep();
		horse.eat();
		
		Animal fish =  new Fish();
		fish.sleep();
		fish.eat();
		fish.func1();
		
	}
}


重寫和重載的區別

1. 定義區別:

①重載是指不同的函數使用相同的函數名,但是函數的參數個數或類型不同。調用的時候根據函數的參數來區別不同的函數。
②覆蓋(也叫重寫)是指在派生類中重新對基類中的虛函數(注意是虛函數)重新實現。即函數名和參數都一樣,只是函數的實現體不一樣。

2.類的關係區別

重寫是子類和父類之間的關係,是垂直關係;重載是同一個類中方法之間的關係,是水平關係。

3.產生方法區別

重寫只能由一個方法或只能由一對方法產生關係;重載是多個方法之間的關係。

4.參數列表要求區別

重寫要求參數列表相同;重載要求參數列表不同。

5.調用方法區別

重寫關係中,調用方法體是根據對象的類型來決定;而重載關係是根據調用時的實參表與形參表來選擇方法體的。

向上轉型

子類向父類的轉換稱爲向上轉型。

向上轉型語法:

<父類型><引用變量名> = new <子類型>();
子類轉父類規則:

1、 將一個父類的引用指向一個子類的對象,稱爲向上轉型,自動進行類型轉換;

2、 此時通過父類引用變量調用的方法是子類覆蓋或繼承父類的方法,不是父類的方法;

3、此時通過父類引用變量無法調用子類特有的方法。

3.super關鍵字

調用父類的構造方法

雖然構造方法不能夠繼承,但通過super關鍵字,在子類構造方法中可以調用父類的構造方法,以便完成父類的初始化。若在子類沒有明顯寫明調用父類構造方法,則系統會自動調用父類不帶參數的構造方法

訪問父類的屬性和方法

可用“ super.屬性名“ 引用父類中被子類隱藏(即子類中有與父類同名的屬性)的屬性或被子類覆蓋的方法。
子類的方法覆蓋了父類的方法時,可用 “super.方法名(參數列表)” 的方式訪問父類中的方法。
在子類中可以添加與父類中屬性名重名的屬性,但是這樣的設計會產生一些不良的後果,不容易開發人員閱讀,因此不建議這樣設計。

例子

Person類

package com.hyg.ext;
/**
 * 父類,屬性公有
 * @author 15332
 *
 */
public class Person {
	public String name;//姓名
	public int age;//年齡
	public String gender;//性別
	
	//父類無參構造方法
	public Person(){
		System.out.println("這是父類的構造方法!");
	}
	//父類有參構造方法
	public Person(String name, int age, String gender) {
		this.name = name;
		this.age = age;
		this.gender = gender;
	}
	//get、set方法
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String getGender() {
		return gender;
	}
	public void setGender(String gender) {
		this.gender = gender;
	}
	public void work(){
		System.out.println("工作");
	}
}

Teacher類

package com.hyg.ext;
/**
 * 子類,派生類
 * @author 15332
 *
 */
public class Teacher extends Person {
	private int salsry;//工資
	private String department;//所屬院系
	
	//子類有參構造方法
	public Teacher(String name, int age, String gender,int salsry, String department) {
		super(name, age, gender);//調用父類的構造方法
		super.age = age;//調用父類的屬性
		this.salsry = salsry;
		this.department = department;
	}
	
	//子類無參構造方法
	public Teacher() {
		super();//調用父類的構造方法
	}

	//get、set方法
	public int getSalsry() {
		return salsry;
	}
	public void setSalsry(int salsry) {
		this.salsry = salsry;
	}
	public String getDepartment() {
		return department;
	}
	public void setDepartment(String department) {
		this.department = department;
	}
	@Override
	public void work() {
		super.work();//調用父類的方法
	}
}


4.final關鍵字

表示 “ 不可改變的、最終的”

1、 修飾變量:表示此變量不可修改,定義時必須給予初始值,;

2、 修飾方法:表示此方法不可被子類重寫;

3、 修飾類:表示此類不可被繼承,類中的所有方法都隱式地指定爲final。

4、 對對象使用final後,你只能改變此對象屬性,而不能將其指向其它對象

例子:

package com.hyg.finalDemo;
/*
 * 類生聲明爲final之後,不可以繼承
 */
public final  class FinalDemo {
	/*常量,對象名.屬性*/
	public final int a = 5; 
	/*靜態常量,類名.屬性名*/
	public static final double PI = 3.25;
	public int b =1;
	/*
	 *  最終方法,final修飾之後,不可以被重寫
	 */
	public final void  work(){
		System.out.println("工作");
	}
	private void test() {
		// TODO Auto-generated method stub
		FinalDemo finaldemo = new FinalDemo();
		System.out.println(finaldemo.a);//對象名.屬性
		System.out.println(FinalDemo.PI);//類名.屬性名
		/*
		 * 對象聲明爲final,但對象的屬性依舊可以改變,而不能其指向其它對象
		 */
		final FinalDemo fdemo = new FinalDemo();
		fdemo.b = 4;
	}
	/*
	 * 內部類,也可以添加訪問修飾符
	 * */
	class InnerClass extends FinalDemo{
		/*報錯
		public void work() {
			// TODO Auto-generated method stub
		}*/
	}	
}
/*
 * 同級類,不可以添加訪問修飾符
 * 一個Java文件中可以存在多個同級類,只能有一個公有的類
 */
 class Son extends FinalDemo{ 
	/*報錯
	 public void work() {
		// TODO Auto-generated method stub
	}*/
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章