继承性

什么叫继承:
       在程序中对已有的类进行扩展,称为继承。
       概念的引出:例如:观察以下的程序,发现其问题:
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表示当前对象

 

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