一:什麼是面向對象的繼承
- 當A繼承B時,A是B的子類,B是A的父類
- 單繼承:一個子類只能有一個直接的父類
- 多繼承:一個子類可以有多個直接的父類
- java只繼承單繼承,不支持多繼承(因爲多繼承會產生調用的不確定性—多個父類中有相同的成員)
繼承的案例
class Fu{
int num1=4;
}
class Zi extends Fu{
int num2=5;
void show(){
System.out.println(num2+"...."+num1);
}
}
class ExtendsDemo2{
public static void main(String[] args){
Zi z=new Zi();
z.show();
}
}
二:繼承的好處
- 提高代碼的複用性
- 讓類與類之間產生關係,給第三特徵提供前提(沒有繼承就沒有多態)
三:什麼時候定義繼承
- 當類與類之間存在所屬關係就定義繼承
- xxx是yyy一種 (xxx extends yyy)
- 但是不能夠爲了繼承而去繼承,如下
class A{
void show1(){}
void show2(){}
}
class B{
void show1(){}
void show3(){}
}
A與B類中都有show1();但是不可以去繼承,因爲A中有show2(),但B中沒有,所以不需要繼承。如果非要繼承就單獨定義show1();
所以不可以亂繼承。
class Person{
String name;
int age;
}
class Student extends Person{
//String name;
//int age;
void study(){
System.out.println(name+"...student study..."+age);
}
}
class Worker extends Person{
//String name;
//int age;
void work(){
System.out.println("Worker work");
}
}
class ExtendsDemo{
public static void main(String[] args){
Student s=new Student();
s.name="wang";
s.age=20;
s.study();
}
}
四:在繼承裏,子父類成員特點
1.成員變量
- 當本類成員與局部變量成員同名時,用this區分,this代表本類本類對象的引用
- 當子父類成員變量同名時,用super區分,super代表父類的空間
2.成員函數
-當子父類出現成員函數一模一樣時,會運行子類函數
-出現此情況稱爲覆蓋操作
-覆蓋操作後父類特徵
1)重載,同一個了自己類中,overload
2)覆蓋,子類中 覆蓋也稱爲重寫,覆寫override
3.構造函數
class Fu{
Fu(){
System.out.println("fu run");
}
}
class Zi extends Fu{
Zi(){
//super();調用父類中的空參數構造函數
System.out.println("zi run");
}
}
class ExtendsDemo4{
public static void main(String[] args){
new Zi();
}
}
**1.**在子類構造函數時,發現訪問子類構造函數時父類也運行了
爲什麼?
因爲在子類的構造函數中的第一行有一個默認的隱式語句 super();
class Demo{
super();
return;
}
2.構造中不是空參
class Fu{
Fu(int x){
System.out.println("fu run");
}
}
class Zi extends Fu{
Zi(){
//super();diaoyongfuleikongcanshu
System.out.println("zi run");
}
}
class ExtendsDemo4{
public static void main(String[] args){
new Zi();
}
}
修改方法如下:
子類實例化過程:子類中所有構造函數都會去訪問父類中空參數構造函數
class Fu{
Fu(int x){
System.out.println("fu run");
}
}
class Zi extends Fu{
Zi(){
//super();diaoyongfuleikongcanshu
super(2);
System.out.println("zi run");
}
}
class ExtendsDemo4{
public static void main(String[] args){
new Zi();
}
}
五:覆蓋的注意事項
- 子類方法覆蓋父類方法時,子類權限應該大於等於父類權限
- 滿足大於等於父類條件纔可以覆蓋
- 靜態只能覆蓋靜態,或者被靜態覆蓋
- 目前我所學的權限,public ,private,默認權限
覆蓋案例
class Fu{
void show(){
System.out.println("fu run show");
}
}
class Zi extends Fu {
public void show(){
System.out.println("zi run show ");//子類覆蓋父類的函數
}
}
class ExtendsDemo3{
public static void main(String [] args){
Zi z=new Zi();
z.show();
//z.show2();
NewPhone p=new NewPhone();
p.newShow();
}
}
class Phone{
void call(){}
void show(){
System.out.println("number");
}
}
class NewPhone extends Phone{
void newShow(){
System.out.println("name");
System.out.println("pic");
//System.out.println("number");
super.show();//用super代表父類的number
}
}
六:什麼時候使用覆蓋
當一個類進行子類擴展時,子類需要保留父類的功能聲明,但是要定義子類中該功能特有內容,就使用功能覆蓋操作完成
七:子父類中的構造函數中的實例過程
- 子類實例化過程:子類中所有構造函數都會去訪問父類中空參數構造函數
- 爲什麼子類實例化的時候要訪問父類的構造函數?
- 因爲子類繼承父類,獲取父類中的內容(屬性),所以使用父類內容之前,要先看父類是如何對自己的內容進行初始化的
- 爲什麼子類必須訪問父類後,就在子類構造函數中加入了super()語句?
- 如果父類沒有定義父類空參數構造函數,則子類函數就必須用super()語句明確調用的父類中那個構造函數,,若子類中用this調用本類構造函數時,super就沒有用了。因爲super與this都只能定義在第一行,(父類的初始化要先完成)只能存在一個。 但是,子類中肯定有其他構造函數訪問父類 的構造函數
class Fu{
Fu(){
System.out.println("A fu run");
}
Fu (int x){
System.out.println(" B fu run");
}
}
class Zi extends Fu{
Zi(){
//super();diaoyongfuleikongcanshu
//super(2);
System.out.println("C zi run");
}
Zi (int x){
System.out.println("D zi run");
}
}
class ExtendsDemo4{
public static void main(String[] args){
new Zi(4);
}
}
class Fu{
Fu(){
super();
show();
return;
}
void show(){
System.out.println("fu show");
}
}
class Zi extends Fu{
int num=8;
Zi(){
super();
return;
}
void show(){
System.out.println("zi show......."+num);
}
}
class ExtendsDemo5{
public static void main(String [] args){
Zi z=new Zi();
z.show();
}
}