繼承和方法重寫
阿新 • • 發佈:2021-07-14
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());
}
}