一、概念&特点
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(){} //最终方法
四、编程练习:测试和研发
要求如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
编程练习:请使用面向对象的思想,设计自定义类完成如下功能要求: 接收用户输入的信息,选择需要完成的工作任务。其中,可供选择的有:测试工作和研发工作。关于类型设定描述如下: 测试工作 属性:工作名称、编写的测试用例个数、发现的Bug数量 方法:工作描述 研发工作 属性:工作名称、有效编码行数、目前没有解决的Bug个数 方法:工作描述 程序运行参考效果图如下: 父类信息测试:开心工作 测试工作类信息测试:测试工作的日报是:今天编写了10个测试用例,发现了5个bug 研发工作类信息测试:研发工作的日报是:今天编写了1000行代码,目前仍有10个bug没有解决 任务 思路分析: 第一步:分析测试工作和研发工作的共性: 都是工作类型 都有工作名称的属性,工作描述的方法 第二步:根据共性,定义工作类 属性:工作名称 方法: 编写无参构造方法、带参构造方法完成对属性的赋值 编写工作描述的方法,描述内容为:开心工作。 第三步:定义测试工作类、研发工作类分别继承工作类,要求: 测试工作类: 增加属性:编写的测试用例个数、发现的Bug数量 在构造方法中调用父类相关赋值方法,完成属性赋值 重写运行方法,描述内容为:**的日报是:今天编写了**个测试用例,发现了**bug。其中**的数据由属性提供 研发工作类: 增加属性:有效编码行数、目前没有解决的Bug个数 在构造方法中调用父类相关赋值方法,完成属性赋值 重写运行方法,描述内容为:**的日报是:今天编写了**行代码,目前仍然有**个bug没有解决。其中**的数据由属性提供
代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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="开心工作 "; return str; } }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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。 "; return str; } }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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; } }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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()); } }
五、访问修饰符
访问范围从小到大:
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
八、编程练习:车行管理系统
要求:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
【编程练习】 编程练习:某公司要开发“XX车行管理系统”,请使用面向对象的思想,设计自定义类描述自行车、电动车和三轮车。 【程序参考运行效果如下】 父类信息测试:这是一辆红色的,天宇牌的非机动车,有4个轮子,有2个座椅 自行车类信息测试:这是一辆黄色的,捷安特牌的自行车 电动车类信息测试:这是一辆使用飞鸽牌电池的电动车 三轮车类信息测试:三轮车是一款有3个轮子的非机动车 【任务】 任务分析; 第一步:分析自行车、电动车和三轮车的共性: 都是非机动车,具有非机动车的基本特征 都有运行的方法 第二步:根据共性,定义非机动车 属性:品牌、颜色、轮子(默认2个)、座椅(默认 1个) 方法: 编写无参构造方法、双参构造方法和四参构造方法,其中,在双参构造方法中,完成对品牌和颜色的赋值;在四参构造方法中,完成对所有属性的赋值 编写运行的方法,描述内容为:这是一辆**颜色的,**牌的非机动车,有**个轮子,有**个座椅的非机动车。其中**的数据由属性提供 第三步:定义自行车、电动车和三轮车分别继承自行车类,要求: 自行车类: 在构造方法中调用父类多参构造,完成属性赋值 重写运行方法,描述内容为:这是一辆**颜色的,**牌的自行车。其中**的数据由属性提供 电动车: 增加“电池品牌”属性 重写运行方法,描述内容为:这是一辆使用**牌电池的电动车。其中**的数据由属性提供 三轮车: 在无参构造中实现对轮子属性值进行修改 重写运行方法,描述内容为:三轮车是一款有**个轮子的非机动车。其中**的数据由属性提供
代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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; } }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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; } }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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; } }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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; } }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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()); } }
九、继承的初始化顺序
1、访问修饰符对成员加载顺序不影响,加载顺序与代码的位置有关
2、在满足继承条件的情况下子类的继承顺序
1)优先加载父类的静态成员
2)加载子类的静态成员
3)父类对象构造(属性、构造代码块、无参构造方法)
4)子类对象构造