java面向对象(十) 继承性

来源:互联网 发布:成品app直播源码 编辑:程序博客网 时间:2024/04/29 16:24

继承性是面向对象的第二大主要特征.

继承性即扩充一个类已有的功能.格式如下:

class 子类 extends 父类 {}
说明:

    1.子类又被称为派生类;

    2.父类又被称为超类(super class)

范例1:继承的基本实现

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{ //Student类继承了Person类}public class Demo2{public static void main(String args[]){Student stu = new Student() ;stu.setName("张三") ;stu.setAge(12) ;System.out.println("姓名:" + stu.getName() + ",年龄:" + stu.getAge()) ;}}
运行结果:


以上代码中,子类(Student类)没有定义任何操作,所有操作都是由Person类定义的,这说明子类及时不扩充父类也可以维持父类.

下面的代码演示子类对父类的功能进行扩充.范例2:

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{ //Student类继承了Person类private String school ;public void setSchool(String school){this.school = school ;}public String getSchool(){return this.school ;}}public class Demo2{public static void main(String args[]){Student stu = new Student() ;stu.setName("张三") ;stu.setAge(12) ;stu.setSchool("清华大学") ;System.out.println("姓名:" + stu.getName() + ",年龄:" + stu.getAge() + ",学校:" + stu.getSchool()) ;}}
运行结果:

在定义继承的时候会存在如下几条限制:

    1.一个子类只能继承一个父类,存在单继承局限;

    2.在一个子类继承时,会继承父类的所有操作(属性,方法),但是对于所有的非私有操作属于显式继承(可以直接利用对象操作),对于所有的私有操作属于隐式继承(需要间接完成)(见错例);

    3.在继承关系中,如果要实例化子类对象,则过程为:先调用父类构造→为父类中的属性初始化→调用子类构造→为子类中的属性初始化.见范例3.

对于第一条限制,可以使用其他方式实现,如下:

class A{}class B extends A{}   //B类继承A类class C extends C{}   //C类继承B类,即C类继承了A类,B类的全部方法
java中只允许多继承(一般不超过3层),不允许多重继承.即java存在单继承局限.
错例:

class A{private String msg ;public void setMsg(String msg){this.msg = msg ;}public String getMsg(){return this.msg ;}}class B extends A{public void print(){System.out.println(msg) ;}}public class Demo{public static void main(String args[]){B b = new B() ;b.setMsg("张三") ;System.out.println(b.getMsg()) ;}}
编译结果:


由以上错误可以得出:A类中的msg这个私有属性无法进行直接访问,但是却可以通过setter,getter方法间接访问,并且也可以在B类的对象中保存msg属性的内容.即:私有属性页被继承下来,但无法直接使用.

范例3:

class A{public A(){//父类无参构造System.out.println("*********") ;}}class B extends A{//子类构造public B(){System.out.println("#########") ;}}public class Demo{public static void main(String args[]){B b = new B() ;}}
运行结果:


以上程序中,虽然实例化的是子类对象,但是发现他会默认先执行父类构造.此时,对于子类而言,就相当于隐含了一个super()的形式.范例4:

class A{public A(){//父类无参构造System.out.println("*********") ;}}class B extends A{//子类构造public B(){super() ;System.out.println("#########") ;}}public class Demo{public static void main(String args[]){B b = new B() ;}}
运行结果:



在默认情况下,子类调用的是父类中的无参构造方法,而如果这个时候父类没有无参构造,则子类必须通过super()调用指定参数的构造方法.范例5:

class A{public A(String msg){//父类无参构造System.out.println("msg = " + msg) ;}}class B extends A{//子类构造public B(){super("hello") ;System.out.println("#########") ;}}public class Demo{public static void main(String args[]){B b = new B() ;}}
运行结果:


在任何情况下,子类的实例化操作都会调用父类的构造方法,那么super调用父类构造时一定要放在构造方法的首行(所以this()和super()不会同时出现).

如果在一个类中有多个构造方法,并且之间使用this()互相调用的话,至少要保留一个构造方法作为出口,通过上例可知,这个出口一定回去调用父类构造,也简单解释了之前提到的:一个简单java类一定要保留一个无参构造方法.

0 0
原创粉丝点击