Fork me on GitHub

Java从零开始学十五(继承)

一、继承作用

继承使用复用以前的代码非常容易,能够大大的缩短开发周期,降低开发成本,同时增加程序的易维护性

继承使重一个类A能够直接使用另外一个类B的属性和方法的一种途径

类A可以有自己的属性和方法

二、继承实现

类的继承格式
在Java中使用extends关键字完成类的继承关系,操作格式:
class 父类{} // 定义父类
class 子类 extends 父类{} // 使用extends关键字实现继承
package com.pb.person;
/*
 * 父类
 */
public class Person {
    private String name; //姓名
    private String sex;    //性别
    private int age;//年龄

    //设置getter和setter方法
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getSex() {
        return sex;
    }
    public void setSex(String sex) {
        if(sex.equals("男") || sex.equals("女")){
            //设置性别限制,不合法的值将提示错误
        this.sex = sex;
        }else{
            System.out.println("性别不合法,性别只能是:男或者女");
        }
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        if(age>0 && age<=150){
            //设置年龄限制
        this.age = age;
        }else{
            System.out.println("年龄只能在1-150岁之间");
        }
    }
    public Person() {
        this.name = "无名氏";
        this.sex = "男";
        this.age = 22;
    }
    public Person(String name, String sex, int age) {
        this.name = name;
        this.sex = sex;
        this.age = age;
    }
    
    public void say(){
        System.out.println("自我介绍:");
        System.out.println("姓名:"+this.name);
        System.out.println("性别:"+this.sex);
        System.out.println("年龄:"+this.age);
    }

}

子类:

package com.pb.person;
/*
 * 子类
 */
public class Student extends Person {
    private int stuNo ;   //学号
    private String specialty;   //专业
    
    public Student() {

    }
    public Student(String name, String sex, int age,int stuNo,String specialty) {
        super(name, sex, age);
        this.stuNo=stuNo;
        this.specialty=specialty;
    }
    
    
    //getter/setter方法
    public int getStuNo() {
        return stuNo;
    }
    public void setStuNo(int stuNo) {
        this.stuNo = stuNo;
    }
    public String getSpecialty() {
        return specialty;
    }
    public void setSpecialty(String specialty) {
        this.specialty = specialty;
    }
    
    
    

}

测试类

package com.pb.persontest;

import com.pb.person.Student;

public class Test {

    public static void main(String[] args) {
        Student stu=new Student("张三", "男", 22, 121, "计算机科学与技术") ;
        stu.say();

    }

}

结果:

自我介绍:
姓名:张三
性别:男
年龄:22

以下可以发现,子类的学号,和专业并没有输出,

默认调用的父类的say()方法

需要子类重写父类的方法

三、方法的重写

方法的重写是发生的子类对父类的过程中,是在2个类中,和方法重载是在一个类中

方法重写有以下要求

Student类重写Person类中的say()方法

package com.pb.person;
/*
 * 子类
 */
public class Student extends Person {
    private int stuNo ;   //学号
    private String specialty;   //专业
    
    public Student() {

    }
    public Student(String name, String sex, int age,int stuNo,String specialty) {
        super(name, sex, age);
        this.stuNo=stuNo;
        this.specialty=specialty;
    }
    //方法重写
    @Override
    public void say() {
    
        super.say();
        System.out.println("学号是:"+this.stuNo);
        System.out.println("专业是:"+this.specialty);
    }
    
    //getter/setter方法
    public int getStuNo() {
        return stuNo;
    }
    public void setStuNo(int stuNo) {
        this.stuNo = stuNo;
    }
    public String getSpecialty() {
        return specialty;
    }
    public void setSpecialty(String specialty) {
        this.specialty = specialty;
    }
    
    
    

}

测试类不变:

package com.pb.persontest;

import com.pb.person.Student;

public class Test {

    public static void main(String[] args) {
        Student stu=new Student("张三", "男", 22, 121, "计算机科学与技术") ;
        stu.say();

    }

}

结果:

自我介绍:
姓名:张三
性别:男
年龄:22
学号是:121
专业是:计算机科学与技术

重写以后,调用的就是子类重写后的方法

 四、super关键字

super必须是出现在子类中(子类的方法和构造方法中),而不是其他位置,在构造方法中必须出现在第一行

用以访问父类的成员,例如:父类的属性、方法、构造方法

访问权限的限制,例如无法通过super访问private成员

五、继承条件下构造方法的调用规则

规则一:如果子类的构造方法中没有通过super显示调用父类的有参构造方法,也没有通过this显式调用自身的其他构造方法,则系统会默认先调用父类的无参构造方法

规则二:如果子类的构造方法中通过super显示调用父类的有参构造方法,那将执行父类的相应的构造方法,而不执行父类无参数构造方法

 规则三:如果子类的构造方法中通过this显式调用自身的其他构造方法,在相应构造方法中应用以上2条规则

5.1、例一

package compb.demo4;
/*
 * 父类
 */
public class StaticSuper {
    public static String staticGet() {
        return "父类静态方法";
    }

    public String dynamicGet() {
        return "父类动态方法";
    }
}

package compb.demo4;
/*
 * 子类
 */
public class StaticSub  extends StaticSuper{
    
    //静态方法不能重写
    public static String staticGet() {
        return "子类静态方法";
    }
    @Override
    public String dynamicGet() {
        return "子类动态方法重写父类动态方法";
    }

}

package compb.demo4;
/*
 * 测试
 */
public class Test {

    public static void main(String[] args) {
        StaticSub s= new StaticSub();  //声明子类对象
    System.out.println(s.staticGet());   //调用子类静态方法
        System.out.println(s.dynamicGet());  //调用子类动态方法
    }

}

结果:

子类静态方法
子类动态方法重写父类动态方法

5.2、例二、

package com.pb.demo5;
/*
 * 父类
 */
public class VenderLate {

    public VenderLate() {
        System.out.print("VenderLate out");
    }
    
}
package com.pb.demo5;

public class MoveGoods  extends VenderLate{

    public MoveGoods( ) {
        System.out.println("MoveGoods out!");
        }
    
    public MoveGoods(String s) {
    System.out.println(s);
    }
    
    
}
package com.pb.demo5;
/*
 * 测试类
 */
public class Test {

    public static void main(String[] args) {
        MoveGoods m=new MoveGoods();
        MoveGoods g=new MoveGoods("   child");
    
    

    }

}

结果:

VenderLate outMoveGoods out!
VenderLate out child

5.3 、例三

package com.pb.demo4;
/*
 * 父类
 */
public class SuperClass {
    private String name;

    public SuperClass() {
    System.out.println("父类的无参数构造方法");
    }
    public SuperClass(String name) {
        System.out.println("父类有一个参数的构造方法:"+name);
        }
    //setter/getter方法
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    
}

子类

package com.pb.demo4;

public class SubClass extends SuperClass {
 private String name;
 private int count;
 
    public SubClass() {
        System.out.println("子类无参数构造方法");
    }
    public SubClass(int count) {
        System.out.println("子类有一个参数构造方法:"+count);
    }
    
    //调用父类有参数的构造方法
    public SubClass(String name) {
        super(name);
        this.name=name;
        System.out.println("调用子类有一个参数构造方法,同时使用super显示调用"+name);
    }

//setter/getter方法
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
    public int getCount() {
        return count;
    }
    public void setCount(int count) {
        this.count = count;
    }

}

测试类:

package com.pb.demo4;

public class Test {

    public static void main(String[] args) {
        System.out.println("*******调用子类无参数构造方法**********");
        SubClass s1=new SubClass();
        System.out.println("*******调用子类有一个参数构造方法但是没有使用super显示调用**********");
        SubClass s2=new SubClass(34);
        System.out.println("*******调用子类有一个参数构造方法,同时使用super显示调用**********");
        SubClass s3=new SubClass("张三");
    }

}

结果:

*******调用子类无参数构造方法**********
父类的无参数构造方法
子类无参数构造方法
*******调用子类有一个参数构造方法但是没有使用super显示调用**********
父类的无参数构造方法
子类有一个参数构造方法:34
*******调用子类有一个参数构造方法,同时使用super显示调用**********
父类有一个参数的构造方法:张三
调用子类有一个参数构造方法,同时使用super显示调用张三

 六、Object类

所有的有类都自动继承java.lang包中的Object类

Object类是所有类的父类(基类)

在定义一个类时如果没有使用extends关键字,则默认继承Object类

Object常被重写的方法:

posted @ 2015-02-17 16:46  森林森  阅读(579)  评论(0编辑  收藏  举报