abstract關鍵字的用法
現在我們要寫一個狗類,也要寫一個貓類:
package oop1;
public class Dog {
public String name;
public int age;
public String color;
public void eat(){
System.out.println("吃飯");
}
public void sleep(){
System.out.println("睡覺");
}
}
package oop1; public class Cat { public String name; public int age; public String color; public void eat(){ System.out.println("吃飯"); } public void sleep(){ System.out.println("睡覺"); } }
可以發現,貓類和狗類中屬性和方法是一樣的,看下來程式碼幾乎是一樣的,但是我們還得寫兩遍,這就很麻煩,雖然可以複製貼上,但是當後續又有豬、猴、馬、兔呢?所以我們想要類似於一個模板一樣的東西。在Java中我們可以使用繼承。
1.什麼是繼承?
Java中將多個類中具有的相同屬性和方法抽取出來,寫到一個單獨的類中,將這個類作為父類,這裡就涉及到了繼承的概念,其它的類使用這個類去生成新的類,就叫繼承了這個類,這個類就是父類,繼承父類的其它類就作為該父類的子類。
父類也叫基類、超類。子類也可叫做派生類。
我們將上述貓、狗類中的屬性和方法抽取出來,放到一個Pet類中,Dog、Cat類繼承Pet:
繼承的關鍵字:extends
語法:子類 extends 父類
Pet:
package oop1;
public class Pet {
public String name;
public int age;
public String color;
public void eat(){
System.out.println("吃飯");
}
public void sleep(){
System.out.println("睡覺");
}
}
Dog:繼承Pet類
public class Dog extends Pet{ }
Cat:繼承Pet類
public class Cat extends Pet{
}
如果我們再多幾個動物類,也可以繼承Pet類,這樣是不是就減少了很多的程式碼量呢?繼承的好處就是:程式碼重用。
2.繼承的使用
(1)子類擁有了父類的哪些東西?
那繼承了父類有什麼用呢?我們就可以使用父類的屬性和方法了。
我們在Dog類中new一個物件,使用.來檢視一下有沒有什麼:
我們可以看到,Dog類的物件擁有了父類的全部屬性和方法。
package oop1;
public class Dog extends Pet{
public static void main(String[] args) {
//使用父類屬性
Dog dog = new Dog();
dog.name = "哈士奇";
dog.age = 3;
dog.color = "黑";
System.out.println(dog.name+"\t"+dog.age+"\t"+dog.color);
//呼叫父類方法
dog.eat();
dog.sleep();
}
}
執行也是沒有問題的:
這就像兒子可以使用父親的很多東西一樣,但是兒子可以使用父親的所有東西嗎?這肯定是不可以的,那繼承的東西是否也會有限制呢?我們再來看看四個許可權修飾符的許可權表:
在學了父類、子類概念後,現在我們已經可以看明白整個表了。可以看到,private修飾的就算是同一個包下的子類都是不可訪問的,我們來實驗一下,將屬性修改成四個不同許可權修飾符修飾:
package oop1;
public class Pet {
public String name;
protected int age;
String color;
private double price;
public void eat(){
System.out.println("吃飯");
}
protected void walk(){
System.out.println("散步");
}
void play(){
System.out.println("玩耍");
}
private void sleep(){
System.out.println("睡覺");
}
}
再驗證一下不同包下的子類:
驗證結果與表中一致,所以得出結論:同一包下的子類,繼承父類之後,就擁有了父類中除私有的屬性和方法;不同包下的子類,繼承父類之後,就擁有了除私有的和預設的以外的私有屬性和方法。
(2)子類能否繼承父類的構造方法?
我們說子類可以繼承父類的符合許可權的屬性和方法,那我們知道構造方法是特殊的方法,父類的構造方法能否被子類繼承呢?
構造方法是用來建立唯一的東西的,如果子類繼承了父類的構造方法,則在建立物件時就不知道建立的是父物件還是子物件,呼叫父類的構造方法,不會建立一個父物件,只是初始化父類的成員屬性和方法(因為子類繼承父類後,會獲取到父類的屬性和方法,這些屬性和方法在使用前必須先初始化,所以須先呼叫父類的構造器進行初始化)。
也不會產生父類物件,只是用了父類的構造方法而已,並不是用到構造方法就會產生物件,構造方法只是起物件初始化作用的,而不是起產生物件作用的;即只有 new 語句才會產生父類的物件。
所以,子類不會繼承父類的構造方法,但是會呼叫父類的構造方法用於初始化。
package oop1;
public class Pet {
public Pet() {
System.out.println("我是父類的構造方法");
}
}
package oop1;
public class Cat extends Pet{
public Cat() {
System.out.println("我是子類的構造方法");
}
public static void main(String[] args) {
Cat cat = new Cat();
}
}
這裡看到雖然輸出了父類的構造方法中的輸出語句,但是隻是子類在new物件時呼叫了父類的構造方法而已。這是一個很容易混淆和繞暈自己的點。
擴充套件:
可以從結果中看出,在子類中new物件,是先輸出了父類的構造方法中的內容,再輸出了子類構造方法中的內容,這裡涉及到了:
繼承關係的初始化順序:
父類的屬性
父類的構造方法
子類的屬性
子類的構造方法
(3)能否繼承多個類?
既然繼承那麼好用,我們可不可以多繼承幾個類呢?
是不可以的,提示中寫著類不能繼承多個類,所以Java是單繼承,只能直接的繼承一個類。
(4)繼承了父類之後還能不能有自己的屬性和方法?
子類繼承了父類之後,還能不能定義自己的屬性和方法呢?
Pet:父類
package oop1;
public class Pet {
public String name;
public int age;
public String color;
public void eat() {
System.out.println("吃飯");
}
public void sleep() {
System.out.println("睡覺");
}
}
Cat:子類
package oop1;
public class Cat extends Pet{
public double price;
public void play(){
System.out.println("貓抓老鼠");
}
public static void main(String[] args) {
Cat cat = new Cat();
//繼承父類屬性
cat.name = "肥橘";
//子類自定義屬性
cat.price = 1000;
//繼承父類方法
cat.eat();
//子類自定義方法
cat.play();
}
}
子類繼承了父類具有許可權的屬性和方法之後,也可以自定義獨有的屬性和方法。
3.總結
- 同一包下的子類,繼承父類的除私有的以外的屬性和方法;
- 不同包下的子類,繼承父類的除私有的和預設的以外的屬性和方法;
- 子類不繼承父類的構造方法;
- 單繼承,只能直接繼承一個類;
- 繼承父類之後,子類還能自定義屬性和方法。
本人水平有限,若有錯誤,望指出~