繼承性

什麼叫繼承:
       在程序中對已有的類進行擴展,稱爲繼承。
       概念的引出:例如:觀察以下的程序,發現其問題:
class Person{

         private String name ;

         private int age ;

         public void setName(String name){

                   this.name = name ;

         }

         public void setAge(int age){

                   this.age = age ;

         }

         public String getName(){

                   return this.name ;

         }

         public int getAge(){

                   return this.age ;

         }

};

class Student{

         private String name ;

         private int age ;

         private String school ;

         public void setName(String name){

                   this.name = name ;

         }

         public void setAge(int age){

                   this.age = age ;

         }

         public void setSchool(String school){

                   this.school = school ;

         }

         public String getName(){

                   return this.name ;

         }

         public int getAge(){

                   return this.age ;

         }

         public String getSchool(){

                   return this.school ;

         }

};

       此代碼符合之前的設計思路,但是進一步觀察,會發現以下問題,在Student類中定義了三個屬性,其中有兩個屬性已經在Person中定義了,所以此時就發現代碼重複太多了。那麼現在就要使用繼承的概念。
       繼承的基本格式:class 子類 extends 父類
class Person{

         private String name ;

         private int age ;

         public void setName(String name){

                   this.name = name ;

         }

         public void setAge(int age){

                   this.age = age ;

         }

         public String getName(){

                   return this.name ;

         }

         public int getAge(){

                   return this.age ;

         }

};

class Student extends Person{

         // 如果什麼都不定義的話,至少包含四個方法

};

public class Demo02{

         public static void main(String args[]){

                   Student stu = new Student() ;

                   stu.setName("張三") ;

                   stu.setAge(30) ;

                   System.out.println("姓名:"+stu.getName()+",年齡:"+stu.getAge()) ;

         }

};

 

       實際上子類可以擁有比父類中更多的屬性或方法。所以此時直接在類中定義新的屬性 —— school
class Person{

         private String name ;

         private int age ;

         public void setName(String name){

                   this.name = name ;

         }

         public void setAge(int age){

                   this.age = age ;

         }

         public String getName(){

                   return this.name ;

         }

         public int getAge(){

                   return this.age ;

         }

};

class Student extends Person{

         // 如果什麼都不定義的話,至少包含四個方法

         private String school ;

         public void setSchool(String school){

                   this.school = school ;

         }

         public String getSchool(){

                   return this.school ;

         }

};

public class Demo03{

         public static void main(String args[]){

                   Student stu = new Student() ;

                   stu.setName("張三") ;

                   stu.setAge(30) ;

                   // 此爲子類自己的方法

                   stu.setSchool("北京大學") ;

                   System.out.println("姓名:"+stu.getName()+",年齡:"+stu.getAge()+",學校:"+stu.getSchool()) ;

         }

};

       由此可見,子類確實增加了父類中的方法,擴展了父類中已有的功能。

 

但是一個子類不允許同時繼承多個父類,它本身是一個單繼承的關係。

 

父類中的所有私有操作實際上子類是全部繼承了,只是採用了隱式的繼承方式完成的,例如:各個私有屬性,可以通過settergetter進行訪問。

 

下面開始進一步完善Person
class Person{

         private String name ;

         private int age ;

         public Person(){

                   System.out.println("**************************") ;

         }

         public Person(String name,int age){

                   this.name = name ;

                   this.age = age ;

         }

         public void setName(String name){

                   this.name = name ;

         }

         public void setAge(int age){

                   this.age = age ;

         }

         public String getName(){

                   return this.name ;

         }

         public int getAge(){

                   return this.age ;

         }

         public String getInfo(){

                   return "姓名:"+this.name+",年齡:"+this.age ;

         }

};

class Student extends Person{

         // 如果什麼都不定義的話,至少包含四個方法

         private String school ;

         public Student(){

                   System.out.println("---------------------------") ;

         }

         public void setSchool(String school){

                   this.school = school ;

         }

         public String getSchool(){

                   return this.school ;

         }

};

public class Demo05{

         public static void main(String args[]){

                   new Student() ;

         }

};

 

 

正常的規律:

       沒有老子,那來的自己呢???
       如果想用子類,則必須先保證父初始化了。因爲構造方法是爲屬性進行初始化的,所以必須先調用父類中的構造方法,但是默認情況下,找的是父類中的無參構造方法。
         public Student(){

                   // 此處實際上默認隱含了一個super(),表示調用父類中的無參構造方法

                   super() ;

                   System.out.println("---------------------------") ;

         }

 

繼續完善Student類。

class Person{

         private String name ;

         private int age ;

         public Person(){

                   System.out.println("**************************") ;

         }

         public Person(String name,int age){

                   this.name = name ;

                   this.age = age ;

         }

         public void setName(String name){

                   this.name = name ;

         }

         public void setAge(int age){

                   this.age = age ;

         }

         public String getName(){

                   return this.name ;

         }

         public int getAge(){

                   return this.age ;

         }

         public String getInfo(){

                   return "姓名:"+this.name+",年齡:"+this.age ;

         }

};

class Student extends Person{

         // 如果什麼都不定義的話,至少包含四個方法

         private String school ;

         public Student(){

                   // 此處實際上默認隱含了一個super(),表示調用父類中的無參構造方法

                   super() ;

                   System.out.println("---------------------------") ;

         }

         public void setSchool(String school){

                   this.school = school ;

         }

         public String getSchool(){

                   return this.school ;

         }

         public String getStuInfo(){

                   return "姓名:"+getName()+",年齡:"+getAge()+",學校:"+this.school ;

         }

};

public class Demo06{

         public static void main(String args[]){

                   Student stu = new Student() ;

                   stu.setName("張三") ;

                   stu.setAge(30) ;

                   stu.setSchool("北京大學") ;

                   System.out.println(stu.getStuInfo()) ;

         }

};

 

在此代碼之中存在了問題:
Person.class

         public String getInfo(){

                   return "姓名:"+this.name+",年齡:"+this.age ;

         }

 

Student.class

         public String getStuInfo(){

                   return "姓名:"+getName()+",年齡:"+getAge()+",學校:"+this.school ;

         }

 

       以上兩部分代碼相比較,可以發現:
· 有部分內容重複了
· 如果要是取得信息的話,是不是應該方法名稱相同纔好,感覺父類中定義的方法不夠子類使。

 

方法的覆寫:

       子類可以定義與父類中方法名稱完全相同的方法,參數的類型或個數也相同,此時就是方法的覆寫。
class A{

         public void fun(){

                   System.out.println("Hello") ;

         }

};

class B extends A{

         // 此處定義了一個與父類中方法名稱相同的方法

         // 所以此時稱爲方法的覆寫

         public void fun(){

                   System.out.println("World!!!") ;

         }

};

public class Demo07{

         public static void main(String args[]){

                   B b = new B() ;

                   b.fun() ;

         }

};

       如果方法被子類覆寫了,則肯定最終找的是被覆寫過的方法。

 

實際上覆寫也是有要求:

       在子類覆寫父類方法的時候,被覆寫的方法不能擁有比父類更嚴格的訪問權限。
       訪問權限:public > default > private
`
那麼現在使用此概念修改之前的代碼,進一步完善PersonStudent類。
class Person{

         private String name ;

         private int age ;

         public Person(){

                   System.out.println("**************************") ;

         }

         public Person(String name,int age){

                   this.name = name ;

                   this.age = age ;

         }

         public void setName(String name){

                   this.name = name ;

         }

         public void setAge(int age){

                   this.age = age ;

         }

         public String getName(){

                   return this.name ;

         }

         public int getAge(){

                   return this.age ;

         }

         public String getInfo(){

                   return "姓名:"+this.name+",年齡:"+this.age ;

         }

};

class Student extends Person{

         // 如果什麼都不定義的話,至少包含四個方法

         private String school ;

         public Student(){

                   // 此處實際上默認隱含了一個super(),表示調用父類中的無參構造方法

                   super() ;

                   System.out.println("---------------------------") ;

         }

         public void setSchool(String school){

                   this.school = school ;

         }

         public String getSchool(){

                   return this.school ;

         }

         public String getInfo(){

                   return super.getInfo()+",學校:"+this.school ;

         }

};

public class Demo08{

         public static void main(String args[]){

                   Student stu = new Student() ;

                   stu.setName("張三") ;

                   stu.setAge(30) ;

                   stu.setSchool("北京大學") ;

                   System.out.println(stu.getInfo()) ;

         }

};

 

覆寫與重載的區別:

區別點

方法的覆寫

方法的重載

概念上

方法名稱相同,參數的類型或個數相同

方法名稱相同,參數的類型或個數不同

範圍

繼承關係之中

發生在一個類中

特殊要求

覆寫的時候被子類覆寫的方法不能用有比父類更嚴格的訪問權限

-

 

注意點:

       關於方法覆寫一定要明白,如果父類中定義的方法是一個私有方法,則子類中在定義重名方法的時候不叫覆寫。
class Demo{

         private void fun(){

                   System.out.println("HELLO") ;

         }

         public void test(){

                   fun() ;

         }

};

class SDemo extends Demo{

         // 實際上此時是在本類中新定義了一個方法

         void fun(){

                   System.out.println("hello") ;

         }

};

public class Demo12{

         public static void main(String args[]){

                   SDemo sd = new SDemo() ;

                   sd.test() ;

         }

};

 

super關鍵字:

       super關鍵字,在程序中明確的表示出了要調用父類的:
       · 構造方法
       · 屬性
       · 普通方法

 

super調用構造方法的時候,必須放在子類構造方法的首行
class Demo{

         public Demo(){

                   System.out.println("父類中的無參構造。") ;

         }

         public Demo(String name){

                   System.out.println("父類中有一個參數的構造。") ;

         }

};

class SDemo extends Demo{

         public SDemo(){

                   super() ;

         }

         public SDemo(String name){

                   super(name) ;

         }

};

 

public class Demo09{

         public static void main(String args[]){

                   SDemo sd = new SDemo("zhangsan") ;

         }

};

 

使用super還可以調用父類中已經被子類覆寫過的方法
class Demo{

         public Demo(){

                   System.out.println("父類中的無參構造。") ;

         }

         public Demo(String name){

                   System.out.println("父類中有一個參數的構造。") ;

         }

         public void fun(){

                   System.out.println("父類中的方法。。。") ;

         }

};

class SDemo extends Demo{

         public SDemo(){

                   super() ;

         }

         public SDemo(String name){

                   super(name) ;

         }

         public void fun(){

                   super.fun() ;

                   System.out.println("子類中的方法。。。") ;

         }

};

 

public class Demo10{

         public static void main(String args[]){

                   SDemo sd = new SDemo("zhangsan") ;

                   sd.fun() ;

         }

};

 

使用super還可以直接找到父類中被子類覆蓋的屬性:
class Demo{

         public String name = "HELLO" ;

};

class SDemo extends Demo{

         public String name = "hello" ;

         public void fun(){

                   System.out.println(super.name) ;

                   System.out.println(name) ;

         }

};

public class Demo11{

         public static void main(String args[]){

                   SDemo sd = new SDemo() ;

                   sd.fun() ;

         }

};

 

superthis的區別:

區別

super

this

範圍

從子類找到父類中的內容

直接找到本類中的內容

屬性

直接找到父類中的指定屬性,不在子類中找

如果在本類中找到了屬性,則使用,如果沒有找到,則會從父類中找此屬性

方法

直接調用父類中的方法

如果本類中有就調用,如果沒有就找父類中的方法

構造

在子類構造方法的首行調用,表示調用父類中的構造。子類中至少有一個構造方法可以調父類構造

表示直接調用本類中的其他構造方法,但至少有一個構造方法是沒有this()的,作爲出口

特殊

-

this表示當前對象

 

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