1. 程式人生 > 其它 >繼承和方法重寫

繼承和方法重寫

1.繼承

繼承是Java中實現程式碼重用的重要手段之一。Java中只支援單根繼承,即一個類只能有一個直接父類。
子類與父類是 is-a 的關係,子類是父類
父子類資訊編寫原則:
父類中編寫共有的屬性和行為
子類中編寫獨有的屬性和行為

public class Pet {
	private String name;
	private int health;
	private int love;
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getHealth() {
		return health;
	}
	public void setHealth(int health) {
		this.health = health;
	}
	public int getLove() {
		return love;
	}
	public void setLove(int love) {
		this.love = love;
	}
	
	public void print() {
		System.out.println("寵物的名字是" + name + ",健康值是" + health + ",愛心值是" + love);
	}
}
public class Dog extends Pet{
	private String strain;
	
	public String getStrain() {
		return strain;
	}
	public void setStrain(String strain) {
		this.strain = strain;
	}
	
	public Dog() {}	
}
public class Penguin extends Pet{
	private String sex;
	
	public String getSex() {
		return sex;
	}
	
	public void setSex(String sex) {
		this.sex = sex;
	}
	
	public Penguin() {}
}
public class Test {
	public static void main(String[] args) {
		Dog dog = new Dog();
		dog.setName("大黃");// Pet繼承而來的
		dog.setHealth(100);// Pet繼承而來的
		dog.setLove(100); // Pet繼承而來的
		dog.setStrain("哈士奇"); // Dog類編寫的
		
		dog.print();
		// 呼叫從父類繼承而來的print方法列印資訊 發現以下兩個問題:
		// 1.列印資訊身份不準確
		// 2.列印資訊不具體

	System.out.println("===============================================");
		Penguin p1 = new Penguin();
		p1.setName("大白");// Pet繼承而來的
		p1.setLove(100);// Pet繼承而來的
		p1.setHealth(100);// Pet繼承而來的
		p1.setSex("雌"); // Penguin類編寫的
		
		System.out.println(p1.getName());
		System.out.println(p1.getHealth());
		System.out.println(p1.getLove());
		System.out.println(p1.getSex());
		p1.print();
	}
}

2. super關鍵字

super關鍵字指父類物件,可以訪問父類許可權允許的方法、屬性、構造方法。

public class Pet {
	protected String name;
	protected int health;
	protected int love;
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getHealth() {
		return health;
	}
	public void setHealth(int health) {
		this.health = health;
	}
	public int getLove() {
		return love;
	}
	public void setLove(int love) {
		this.love = love;
	}
	
	public void print() {
		System.out.println("寵物的名字是" + name + ",健康值是" + health + ",愛心值是" + love);
	}
}
public class Dog extends Pet{
	private String strain;
	
	public String getStrain() {
		return strain;
	}
	public void setStrain(String strain) {
		this.strain = strain;
	}
	
	public Dog() {}
	
	public void printDog() {
		super.print();
		System.out.println("狗狗的品種是" + strain);
	}
	
	public Dog(String name,int health,int love,String strain) {
		this.strain = strain;
		super.name = name;
		super.health = health;
		super.love = love;
	}
	
}
public class Test {
	public static void main(String[] args) {
		Dog dog =  new Dog();
		dog.setName("大黃");
		dog.setHealth(100);
		dog.setLove(100);
		dog.setStrain("金毛");
		
//		dog.print();
		dog.printDog();
		System.out.println("===========================");
		Penguin p1 = new Penguin();
		p1.setName("大白");
		p1.setLove(100);
		p1.setHealth(100);
		p1.setSex("雌"); 
		
		p1.printPenguin();
		System.out.println("===========================");
		Dog dog1 = new Dog("小黑", 100, 100, "金毛");
		dog1.printDog();
	}
}

super關鍵字使用構造方法建立子類物件時,預設呼叫父類的無參構造方法,除非子類顯式的呼叫父類的有參構造方法
子類必須呼叫父類的構造方法,無參或者有參必須呼叫一個

public class Pet {
	protected String name;
	protected int health;
	protected int love;
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getHealth() {
		return health;
	}
	public void setHealth(int health) {
		this.health = health;
	}
	public int getLove() {
		return love;
	}
	public void setLove(int love) {
		this.love = love;
	}
	
	public Pet(String name,int health,int love) {
		this.name = name;
		this.health = health;
		this.love = love;
	}
	
	/**
	 * 	父類中推薦都提供無參 方便子類使用
	 */
	public Pet() {}
	
	public void print() {
		System.out.println("寵物的名字是" + name + ",健康值是" + health + ",愛心值是" + love);
	}	
}
/**
 * 	狗類
 * 		品種
 * 	列印狗狗資訊
 * @author WHD
 *
 */
public class Dog extends Pet{
	private String strain;
	
	public String getStrain() {
		return strain;
	}
	public void setStrain(String strain) {
		this.strain = strain;
	}
	
	public void printDog() {
		print();
		System.out.println("狗狗的品種是" + strain);
	}
	
	/**
	 * 	因為父類的無參構造被覆蓋了 所以Dog子類報錯
	 * 	解決方案:編寫有參構造呼叫父類的有參  不再呼叫無參
	 * @param name
	 * @param health
	 * @param love
	 * @param strain
	 */
	public Dog(String name,int health,int love,String strain) {
		super(name, health, love);
		this.strain = strain;
	}
	
}
/**
 * 	企鵝類
 * 		性別
 * 	列印資訊
 * @author WHD
 *
 */
public class Penguin extends Pet{
	private String sex;
	
	public String getSex() {
		return sex;
	}
	
	public void setSex(String sex) {
		this.sex = sex;
	}
	
	public void printPenguin() {
		super.print(); // 繼承自父類的方法 可以使用super加點 或者this加點 或者直接書寫 方法名
		System.out.println("企鵝的性別是" + sex);
	}
}

3.方法重寫

方法重寫的要求:
1.父子類之間的
2.方法名稱相同
3.引數列表相同
4.訪問許可權不能嚴於父類,不能窄化父類的訪問許可權
5.返回值相同或者是其子類
6.父類的靜態方法可以被繼承,但是不能被重寫,非靜態方法不能重寫為靜態方法
7.不能丟擲比父類更多的異常
@Override註解:用於子類的方法上,表示此方法為重寫父類的方法,如果沒有符合以上重寫的規則,那麼將編譯報錯。

/**
 * 	狗類
 * 		品種
 * 	列印狗狗資訊
 * @author WHD
 *
 */
public class Dog extends Pet{
	private String strain;
	
	public String getStrain() {
		return strain;
	}
	public void setStrain(String strain) {
		this.strain = strain;
	}
	
	/**
	 * 	方法重寫
	 * 	1.父子類之間的
	 * 	2.方法名稱相同
	 * 	3.引數列表相同
	 * 	4.訪問許可權不能嚴於父類 不能窄化父類的訪問許可權
	 * 	5.返回值相同     或者是其子類
	 * 
	 * 	6.父類的靜態方法可以被繼承 但是不能被重寫 非靜態方法不能重寫為靜態方法
	 * 	7.不能丟擲比父類更多的異常
	 */
	@Override
	public  void print() {
		super.print();
		System.out.println("狗狗的品種是" + strain);
	}
	
	public static void m1() {
	}
	
	public Dog(String name,int health,int love,String strain) {
		super(name, health, love);
		this.strain = strain;
	}
	
}

4. Object類

Object類是所有類的父類,所有的類將預設繼承自此類
此類中提供了一些常用的方法,實際開發中我們經常重寫這些方法

4.1 重寫toString方法

我們直接列印一個物件將預設呼叫此物件的toString方法,返回值為包名類名+@+雜湊值
如果我們不想要這個效果,可以重寫toString方法

/**
 * 	學生類
 * 	名字
 * 	年齡
 * @author WHD
 *
 */
public class Student{
	private String name;
	private int age;
	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 toString() {
		String str = super.toString();
		return "Student[name=" + name + ",age=" + age + "]" + str;
	}
	
	public static void main(String[] args) {
		Student stu = new Student();
		stu.setName("趙四");
		stu.setAge(17);
		
		System.out.println(stu.getName());
		System.out.println(stu.getAge());
		
		System.out.println(stu); // 直接列印一個物件將呼叫從父類繼承而來的toString方法
		System.out.println(stu.toString()); 
		
	}
	
}