【5】Java继承

一、概念&特点

1、概念

1)是一种类与类之间的关系;
2)使用已存在的类的定义作为基础建立新类;
3)父类(基类),子类(派生类);
4)子类的定义可以增加新的属性和新的方法,也可以用父类所有开放的属性和方法,但不能选择性地继承父类(不能只继承一部分)。

2、继承特点

1)利于代码复用。
2)缩短开发周期。

3、 继承的关系

满足A is a B的关系就可以能形成继承关系。
猫、狗→动物
老师、学生→人
轿车、卡车→车

二、继承的实现

//公共的属性和方法(父类)
public class Animal {
}

//编写子类,继承父类
public class Dog extends Animal {
    //关键字extends
    //子类特有的属性和方法
    //只能继承一个父类
}
//子类
public class Cat extends Animal{
}

三、方法重写

1、方法重载

1)在同一个类中;
2)方法名相同,参数列表不同(参数顺序、个数、类型);
3)方法返回值、访问修饰符任意。

2、方法重写

1)有继承关系的子类中;
2)方法名相同,参数列表相同(参数顺序、个数、类型),方法返回值相同;
3)访问修饰符,访问范围需要大于等于父类的访问范围。
4)与方法的参数名无关。

3、注意

1)Java中重写仅限于方法,属性不可以重写。但是在子类中,是可以定义与父类重名的属性的,此时子类对象调用的是子类的属性。
2)静态方法和最终方法不能被重写;但静态方法在子类中可以通过隐藏父类方法的方式重新实现。
public static void bark(){} //静态方法
public final void display(){} //最终方法

四、编程练习:测试和研发

要求如下:

编程练习:请使用面向对象的思想,设计自定义类完成如下功能要求:

接收用户输入的信息,选择需要完成的工作任务。其中,可供选择的有:测试工作和研发工作。关于类型设定描述如下:

测试工作

       属性:工作名称、编写的测试用例个数、发现的Bug数量

       方法:工作描述

研发工作

       属性:工作名称、有效编码行数、目前没有解决的Bug个数

       方法:工作描述

程序运行参考效果图如下:
父类信息测试:开心工作
测试工作类信息测试:测试工作的日报是:今天编写了10个测试用例,发现了5个bug
研发工作类信息测试:研发工作的日报是:今天编写了1000行代码,目前仍有10个bug没有解决


任务

思路分析:

第一步:分析测试工作和研发工作的共性:

都是工作类型

都有工作名称的属性,工作描述的方法



第二步:根据共性,定义工作类

属性:工作名称

方法:

编写无参构造方法、带参构造方法完成对属性的赋值

编写工作描述的方法,描述内容为:开心工作。



第三步:定义测试工作类、研发工作类分别继承工作类,要求:

测试工作类:

 增加属性:编写的测试用例个数、发现的Bug数量

 在构造方法中调用父类相关赋值方法,完成属性赋值

重写运行方法,描述内容为:**的日报是:今天编写了**个测试用例,发现了**bug。其中**的数据由属性提供

 研发工作类:

增加属性:有效编码行数、目前没有解决的Bug个数

在构造方法中调用父类相关赋值方法,完成属性赋值

重写运行方法,描述内容为:**的日报是:今天编写了**行代码,目前仍然有**个bug没有解决。其中**的数据由属性提供

   
要求

 代码:

package com.fiona.javaObjectOriented.day13jc.work;

public class Work {
    // 属性:工作名称
    public String name ;

    // 无参构造方法
    public Work(){

    }

    // 带参构造方法,完成工作类型的赋值
    public Work(String name) {
        this.name = name;
    }

    // 公有的get***/set***方法完成属性封装
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    // 方法:工作描述,描述内容为:开心工作
    public String work (){
        String str="开心工作\n";
        return str;

    }

}
Work

 

package com.fiona.javaObjectOriented.day13jc.work;

public class TestWork extends Work{
    //属性:编写的测试用例个数、发现的Bug数量
    public int testCase;
    public int bug;

    // 编写构造方法,并调用父类相关赋值方法,完成属性赋值
    public TestWork(String name) {
        super();
    }

    public TestWork(String name,int testCase,int bug) {
        super(name);
        this.name = name;
        this.testCase=testCase;
        this.bug=bug;
    }



    // 公有的get***/set***方法完成属性封装
    public int getTestCase() {
        return testCase;
    }

    public void setTestCase(int testCase) {
        this.testCase = testCase;
    }

    public int getBug() {
        return bug;
    }

    public void setBug(int bug) {
        this.bug = bug;
    }

    // 重写运行方法,描述内容为:**的日报是:今天编写了**个测试用例,发现了**bug。其中**的数据由属性提供
    public String work() {
        String str =this.name+"的日报是:今天编写了"+this.testCase+"个测试用例,发现了"+this.bug+"bug。\n";
    return str;
    }
}
TestWork

 

package com.fiona.javaObjectOriented.day13jc.work;

public class DevelopWork extends Work {
    public int code;
    public int bug;



    public DevelopWork() {

    }

    public DevelopWork(String name, int code, int bug) {
        super(name);
        this.code = code;
        this.bug = bug;
    }

    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public int getBug() {
        return bug;
    }

    public void setBug(int bug) {
        this.bug = bug;
    }

    public String work(){
        String str=this.name+"的日报是:今天编写了"+this.code+"行代码,目前仍有"+this.code+"个bug没有解决";
        return str;
    }
}
DevelopWork

 

package com.fiona.javaObjectOriented.day13jc.worktest;

import com.fiona.javaObjectOriented.day13jc.work.DevelopWork;
import com.fiona.javaObjectOriented.day13jc.work.TestWork;
import com.fiona.javaObjectOriented.day13jc.work.Work;

public class Test {
    public static void main(String[] args) {

        System.out.print("父类信息测试:");
        Work one = new Work();
        System.out.println(one.work());

        System.out.print("测试工作类信息测试:");
        TestWork two = new TestWork("测试工作",10,5);
        System.out.println(two.work());

        System.out.print("研发工作类信息测试:");
        DevelopWork tree = new DevelopWork("研发工作",1000,10);
        System.out.println(tree.work());

    }

}
Test

 

五、访问修饰符

访问范围从小到大:
1)private(私有的) : 只允许在本类中访问;
2)默认:允许当前类、同包子类/非子类允许调用,不允许跨包子类/非子类调用。
3)protected(受保护的):允许当前类、同包子类/非子类、跨包子类调用,不允许跨包非子类调用;
4)public(共有的): 允许在任意位置访问;

六、super关键字

1、访问父类的成员变量

在子类的成员方法中,调用父类的成员变量。
语法:super.变量名称; 例如:super.name;

2、访问父类的成员方法

在子类的成员方法中,调用父类被重写的成员方法。
语法:super.方法名(方法参数); 例如:super.prine();

3、访问父类的构造方法

在子类的构造方法中,访问父类的构造方法。
语法:super(方法参数); 例如:super(); 或者 super(name,month);
1)子类构造方法中默认调用父类无参构造方法。
2)如果没有存在构造方法,则自动创建无参构造方法
3)如果创建有参构造方法,则不会自动创建无参构造方法,那么子类在调用构造方法的过程中无法找到父类的无参构造方法
4)当父类不存在无参构造时,子类构造方法必须使用super(方法参数);明确表示当前调用的是哪个父类构造,此时super不能省略,且必须处于子类构造方法首行。
 
注意:   不能用于子类的类(静态)方法中。
参考自:

七、this和super

八、编程练习:车行管理系统

要求:

【编程练习】
编程练习:某公司要开发“XX车行管理系统”,请使用面向对象的思想,设计自定义类描述自行车、电动车和三轮车。

【程序参考运行效果如下】

父类信息测试:这是一辆红色的,天宇牌的非机动车,有4个轮子,有2个座椅
自行车类信息测试:这是一辆黄色的,捷安特牌的自行车
电动车类信息测试:这是一辆使用飞鸽牌电池的电动车
三轮车类信息测试:三轮车是一款有3个轮子的非机动车


【任务】

任务分析;

第一步:分析自行车、电动车和三轮车的共性:

都是非机动车,具有非机动车的基本特征

都有运行的方法

第二步:根据共性,定义非机动车

属性:品牌、颜色、轮子(默认2个)、座椅(默认   1个)

方法:

编写无参构造方法、双参构造方法和四参构造方法,其中,在双参构造方法中,完成对品牌和颜色的赋值;在四参构造方法中,完成对所有属性的赋值

编写运行的方法,描述内容为:这是一辆**颜色的,**牌的非机动车,有**个轮子,有**个座椅的非机动车。其中**的数据由属性提供

第三步:定义自行车、电动车和三轮车分别继承自行车类,要求:

自行车类:

在构造方法中调用父类多参构造,完成属性赋值

重写运行方法,描述内容为:这是一辆**颜色的,**牌的自行车。其中**的数据由属性提供

电动车:

增加“电池品牌”属性

重写运行方法,描述内容为:这是一辆使用**牌电池的电动车。其中**的数据由属性提供

三轮车:

在无参构造中实现对轮子属性值进行修改

重写运行方法,描述内容为:三轮车是一款有**个轮子的非机动车。其中**的数据由属性提供
要求

代码:

package com.fiona.javaObjectOriented.day13jc.vehicle;
/**
 * 父类
 */
public class NonMotor {
    // 私有属性:品牌、颜色、轮子(默认2个)、座椅(默认 1个)
    private String brand;
    private String colour;
    private int wheel=2;
    private int seat=1;

    // 无参构造方法
    public NonMotor() {
    }
    // 双参构造方法,完成对品牌和颜色的赋值
    public NonMotor(String brand, String colour) {
        this.setBrand(brand);
        this.setColour(colour);
    }
    // 四参构造方法,分别对所有属性赋值
    public NonMotor(String brand, String colour, int wheel, int seat) {
        this.setBrand(brand);
        this.setColour(colour);
        this.setWheel(wheel);
        this.setSeat(seat);
    }
    // 公有的get***/set***方法完成属性封装
    public String getBrand() {
        return brand;
    }

    public void setBrand(String brand) {
        this.brand = brand;
    }

    public String getColour() {
        return colour;
    }

    public void setColour(String colour) {
        this.colour = colour;
    }

    public int getWheel() {
        return wheel;
    }

    public void setWheel(int wheel) {
        this.wheel = wheel;
    }

    public int getSeat() {
        return seat;
    }

    public void setSeat(int seat) {
        this.seat = seat;
    }

    // 方法:运行,描述内容为:这是一辆**颜色的,**牌的非机动车,有**个轮子,有**个座椅的非机动车。其中**的数据由属性提供
    public String work() {
         String str =("这是一辆"+this.getColour()+"颜色的,"+this.getBrand()+"牌的非机动车,有"+this.getWheel()+"个轮子,有"+this.getSeat()+"个座椅的非机动车。");
        return str;
    }
}
NonMotor

 

package com.fiona.javaObjectOriented.day13jc.vehicle;

/**
 * 自行车类
 */
public class Bicycle extends NonMotor {
// 在构造方法中调用父类多参构造,完成属性赋值


    public Bicycle() {
    }

    public Bicycle(String brand, String colour) {
        super(brand, colour);
    }


    // 重写运行方法,描述内容为:这是一辆**颜色的,**牌的自行车。其中**的数据由属性提供
    @Override
    public String work(){
        String str = "这是一辆"+this.getColour()+"颜色的,"+this.getBrand()+"牌的自行车。";
        return str;
    }

}
Bicycle

 

package com.fiona.javaObjectOriented.day13jc.vehicle;
/**
 * 电动车类
 */
public class ElectricVehicle extends NonMotor {
    // 私有属性:电池品牌
    private String battery;


    public  ElectricVehicle(){

    }
    public ElectricVehicle(String battery) {
        this.setBattery(battery);
    }
    // 公有的get***/set***方法完成属性封装

    public String getBattery() {
        return battery;
    }

    public void setBattery(String battery) {
        this.battery = battery;
    }

    // 重写运行方法,描述内容为:这是一辆使用**牌电池的电动车。其中**的数据由属性提供

    @Override
    public String work() {
        String str="这是一辆使用"+this.getBattery()+"牌电池的电动车";
        return str;
    }
}
ElectricVehicle

 

package com.fiona.javaObjectOriented.day13jc.vehicle;

/**
 * 三轮车类
 */
public class Tricycle extends NonMotor {
    // 在无参构造中实现对轮子属性值进行修改
    public Tricycle() {
        super.setWheel(3);
    }

    // 重写运行方法,描述内容为:三轮车是一款有**个轮子的非机动车。其中**的数据由属性提供
    @Override
    public String work() {
        String str = "三轮车是一款有"+this.getWheel()+"个轮子的非机动车";
        return str;
    }
}
Tricycle

 

package com.fiona.javaObjectOriented.day13jc.vehicletest;

import com.fiona.javaObjectOriented.day13jc.vehicle.Bicycle;
import com.fiona.javaObjectOriented.day13jc.vehicle.ElectricVehicle;
import com.fiona.javaObjectOriented.day13jc.vehicle.NonMotor;
import com.fiona.javaObjectOriented.day13jc.vehicle.Tricycle;

public class Test {
    public static void main(String[] args) {
        NonMotor one = new NonMotor("天宇","红",4,2);
        System.out.print("父类信息测试:"+one.work());
        System.out.println();

        Bicycle two = new Bicycle("捷安特","黄");
        System.out.print("自行车类信息测试:"+two.work());
        System.out.println();

        ElectricVehicle tree = new ElectricVehicle("飞鸽");
        System.out.print("电动车类信息测试:"+tree.work());
        System.out.println();

        Tricycle four = new Tricycle();
        System.out.print("三轮车类信息测试:"+four.work());

    }
}
Test

 

九、继承的初始化顺序

1、访问修饰符对成员加载顺序不影响,加载顺序与代码的位置有关
 
2、在满足继承条件的情况下子类的继承顺序
1)优先加载父类的静态成员
2)加载子类的静态成员
3)父类对象构造(属性、构造代码块、无参构造方法)
4)子类对象构造

 

posted @ 2020-04-21 15:11  柠檬不萌!  阅读(367)  评论(0编辑  收藏  举报
浏览器标题切换
浏览器标题切换end